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 \____/