Veda/PackObjectReference.h

Go to the documentation of this file.
00001 /*! \file 
00002     \author victorien ferry & www.m4nkind.com
00003     \brief This file applies the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1 , read file COPYING.
00004 */
00005 #ifndef COM_M4NKIND_PackObjectReference_H
00006 #define COM_M4NKIND_PackObjectReference_H
00007 
00008 // serializable base type needed:
00009 #include "PackULong.h"
00010 #include "PackString.h"
00011 #include "BaseObject.h"
00012 
00013 /*!
00014     \class  PackObjectReference
00015     \ingroup    BaseSerializableClass
00016     \brief   Base type managing a serializable reference to another object in the same context.
00017             a BaseObject can use a %PackObjectReference as a member, and when registering it,
00018             you specify a pointable base class. Then the %PackObjectReference will be able
00019             to point any object in the context that match this pointable class, or its inherited classes.\n
00020             You get the pointer with GetObjectPointer(). Getting NULL is valid, and simply means that nothing is pointed.
00021             You change the pointer with SetObjectPointer(), and you should check its enum_SetReferenceResult errorcode.\n
00022              Please, don't stock a pointer from GetObjectPointer() elsewhere between
00023              two functions, because %PackObjectReference are dynamic pointers, that can
00024              change or become NULL during edition.
00025              Registering a %PackObjectReference member in a BaseObject constructor 
00026              can look like this:
00027              \code
00028 #include "myClass.h"
00029 #include "VirtualImage.h"
00030 myClass::myClass() : BaseObject()
00031 {
00032     REGISTER_MEMBER_REFERENCE(  m_MyImagePointer,"the Reference",VirtualImage::m_Description );
00033 }
00034              \endcode
00035              ...And then, inside your class code, you will get the image like this:
00036              \code
00037 void    myClass::myMethodThatUsesImages(void)
00038 {
00039     // PackObjectReference ensures that the pointer can be casted to that class:
00040     VirtualImage *pImage = (VirtualImage *) m_MyImagePointer.GetObjectPointer();
00041     if(pImage != NULL)
00042     {
00043         // you can use pImage here.
00044     }
00045 }
00046     \endcode
00047 */
00048 
00049 
00050 class PackObjectReference : public PackULong
00051 {
00052 /*==================================================================
00053                                 PUBLIC
00054 ==================================================================*/
00055 public:
00056     /*!
00057         \brief  Constructor. Each PackObjectReference refers to an object instancied
00058             from a given class, or from an inherited class. 
00059     */
00060     PackObjectReference();
00061 #ifdef _ENGINE_EDITABLE_
00062     /*!
00063         \brief  Destructor. 
00064     */
00065     virtual ~PackObjectReference(void);
00066 #endif
00067     /*!
00068         \brief  Get the object refered. If it exists and has a right class type,
00069                 Get will return the object. Else, Get would return NULL. You should get
00070                 your objects one time by method, and never stock what you get, because
00071                 it could be destroyed or closed between two method calls.
00072                 \return the object, or NULL if reference set to NULL.
00073     */
00074     inline BaseObject *GetObjectPointer() const { return m_pReferedObject;  };
00075 #ifdef _ENGINE_EDITABLE_
00076     //! \typedef enum_SetReferenceResult
00077     //! Result enum returned by SetObjectPointer()
00078     typedef enum {
00079         //! means the object is now pointed.
00080         eSetRef_SetOK=0,
00081         //! means the bug is in the application code, contact developers! (note; it really never hapended)
00082         eSetRef_BadReferenceInit_ShouldntHappen,
00083         //! you tried to link an object which is not from this context !
00084         eSetRef_ObjectFromOtherContext,
00085         //! each PackObjectReference can only point a given class or inheritage, and the object doesn't match that class.
00086         eSetRef_ObjectClassDoesntMatch,
00087         //! the link would create a circular dependance in the context. You can't do that !
00088         eSetRef_CantReferObjectThatReferThisOne
00089     } enum_SetReferenceResult;
00090     /*!
00091         \brief  Set the pointed object, from the same context. If it exists and has a right class type,
00092                 It will be set as the refered object, and
00093                 GetObjectPointer() will return the object. Else, it would return NULL.
00094                 This Method is only compiled in editable mode. 
00095                 In non editable mode, a shorter version is compiled.
00096             \param _Object the object to refer from now on.
00097             \return eSetRef_SetOK if OK, otherwise an error enum.
00098     */
00099     virtual enum_SetReferenceResult SetObjectPointer( BaseObject * _Object );
00100 #else
00101     /*!
00102         \brief  Set the object refered, non-editable version, done by BaseContext::Serialization_in()
00103         \param _Object the object to refer from now on.
00104     */
00105     inline void SetObjectPointer( BaseObject * _Object ){ m_pReferedObject = _Object ; };
00106 #endif
00107 
00108 #ifdef _ENGINE_EDITABLE_
00109     /*!
00110         \brief  Set the kind of class of object that we will be able to refer. Is only possible in editable mode.
00111                 In read-only mode, the referable type is implicit. It can only be done once.
00112     */
00113     void    SetReferableBaseClass( const BaseObject::ClassDescription &_classDescription  );
00114 #endif
00115 #ifdef _ENGINE_EDITABLE_
00116     /*!
00117         \brief  Get the kind of class of object that we will be able to refer. Is only possible in editable mode.
00118                 In read-only mode, the referable type is implicit.
00119     */
00120      const BaseObject::ClassDescription &GetReferableBaseClass();
00121 #endif
00122 #ifdef _ENGINE_EDITABLE_
00123     /*!
00124         \brief  get the size of the whole byte chunk that will be written by Serialize_Out().
00125         \return byte size of the serialisation to do.(1,2,3, or4)
00126     */
00127     virtual unsigned int  GetSerializedDescriptionSize(void);
00128 #endif
00129 #ifdef _ENGINE_EDITABLE_
00130     /*!
00131         \brief  write the Current object definition to a Chunk using private packed types, recursively.
00132         \param  _pDescriptionChunkToFill the chunk where to write the objet description chunk. 
00133         \return the end of the chunk written, possibly unlocated. Don't use this if you don't need it.
00134     */
00135     virtual unsigned char * Serialize_Out(unsigned char * _pDescriptionChunkToFill);
00136 #endif
00137 #ifdef _ENGINE_EDITABLE_
00138     /*!
00139         \brief  Each BaseType's inherited classes must explicit an ID for their
00140                 class, or let use one of the super class at least through this virtual method.
00141                 This is needed by GUIs to detect the types of each sub-members, and shape
00142                 an interface for each Object according to their member list.
00143         \return a const character string, that must be unique and unchanged for all serializable base type.
00144     */
00145     virtual const char *GetClassID() const { return "PackObjectReference"; };
00146 #endif
00147 #ifdef _ENGINE_EDITABLE_
00148     /*!
00149         \brief  convert the value of this object to an explicit string. The object manages the string privately,
00150             so just read it or copy it. the string would be destroyed with the objects, and changed when using Set() methods.
00151              Note: this is not virtual, but each class can manage m_pValueString or not.
00152         \return the value as a const string. 
00153     */
00154     virtual const char  *ValueToString();
00155 #endif
00156 #ifdef _ENGINE_EDITABLE_
00157     /*!
00158         \brief  Used to scan the list of all reference to an object (which start is in BaseObject):
00159         \return the next in the list or 0L if it ends.
00160     */
00161     inline PackObjectReference * GetNextSelfReferenceNode(){ return m_pNextSelfReferenceNode; };
00162 #endif
00163 
00164     /*!
00165         \brief  Set the kind of class of object that we will be able to refer. Is only possible in editable mode.
00166                 In read-only mode, the referable type is implicit. It can only be done once.
00167         \return pointer on a pointer
00168     */
00169     inline PackObjectReference  **GetPointerOnNextObjectReferenceInContextList(){ return( &m_pNextObjectReferenceInContextList ); };
00170 
00171     /*!
00172         \brief  The Object this one belong to as a member. Should only be used at init.
00173         \param _pManager    BaseObject
00174     */
00175     virtual void    SetObjectThatManagesThis(BaseObject *_pManager);
00176 #ifdef _ENGINE_EDITABLE_
00177     /*!
00178         \brief  Update Reference To Unique Index. 
00179             It is used by context serialization
00180     */
00181     inline void UpdateSerializedID(void)
00182     {
00183         if( m_pReferedObject ) m_value = m_pReferedObject->GetUniqueReference() ;
00184         else m_value = 0 ;
00185     };
00186 #endif
00187 /*==================================================================
00188                                 PROTECTED
00189 ==================================================================*/
00190 protected:
00191     
00192     //! the objects refered. If destroyed in editablemode, become null.
00193     BaseObject      *m_pReferedObject;
00194 
00195 #ifdef _ENGINE_EDITABLE_
00196 
00197     //! copy of the object name referenced. It is not serialized.
00198     //PackString        m_referencedObjectName;
00199     /*! The name of the class of an object this reference can refer. Should never be null.
00200         Note: it is took and pointed to an BaseObject static member, not copied in any way. It shoud be OK.
00201     */
00202     const BaseObject::ClassDescription *m_ReferableclassDescription;
00203 
00204     //! in editable mode, chain list which start is in BaseObject, and list all the reference to the object.
00205     PackObjectReference *m_pNextSelfReferenceNode;
00206 
00207 #endif
00208     //! chain list which start is in BaseContext, and list all the references to the object for the whole context.
00209     PackObjectReference *m_pNextObjectReferenceInContextList;
00210 #ifdef _ENGINE_EDITABLE_
00211     /*!
00212         \brief  protected. Declare that the previous reference state is closed. equivalent to Set(0L);
00213     */
00214     void    CloseReference();
00215 #endif
00216 };
00217 #ifdef _ENGINE_EDITABLE_
00218 /*!
00219     \def    REGISTER_MEMBER_REFERENCE
00220     \brief  This macro is used to register a serializable PackObjectReference member
00221             and specify the base class a reference can ask. It must be used in BaseObject's constructor,
00222             never elsewhere.
00223             It does compile less things in non-editable mode.
00224 */
00225 #define     REGISTER_MEMBER_REFERENCE(_object,_MemberName,_classDescriptor) \
00226 REGISTER_MEMBER(_object,_MemberName);\
00227 _object.SetReferableBaseClass(_classDescriptor);
00228 #else
00229 #define     REGISTER_MEMBER_REFERENCE(_object,_MemberName,_classDescriptor) \
00230 REGISTER_MEMBER(_object,_MemberName);
00231 #endif
00232 //end of file:
00233 #endif

      /\/\        4         N         k         !         N         D
                      _______  _ __ ___  _____            ___ _ _  ____
     ___________  __//___   /________  |/    / ___________\_______/    \
    /   _   _   \/   _     /    _   /      _/_/____/    _       __     /
   /    /   /       /     /    /    \      \/     /    /    \   \     /
  \\___/___/___/    ¯    _____/_____/       ______\___/_____/\________\\
               \________/_ ___ __ l____\      /elD!  
                 http://www.m4nkind.com \____/