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_ClassNode_H 00006 #define COM_M4NKIND_ClassNode_H 00007 00008 #include "NamedObject.h" 00009 // serializable base type needed: 00010 #include "PackString.h" 00011 #include "BaseObject.h" 00012 #include "PackList.h" 00013 00014 class BaseContext; 00015 /*! 00016 \addtogroup BaseContextDocGroup BaseContext Related Documentations 00017 \brief Here are links to documentations related to class BaseContext. This class 00018 allows the management of a set of objects as an application context, 00019 and is provided with the base package. 00020 On this page, the methods are sorted by themes. 00021 */ 00022 /*! \addtogroup BaseContextDocGroup_InitMethods BaseContext Init Methods 00023 \ingroup BaseContextDocGroup 00024 \brief Init Methods for BaseContext 00025 */ 00026 /*! \addtogroup BaseContextDocGroup_ObjectEditionMethods BaseContext Object Edition Methods 00027 \ingroup BaseContextDocGroup 00028 \brief The methods that allows to create Objects in a BaseContext. 00029 Then to edit objects, use the objects methods. 00030 */ 00031 /*! \addtogroup BaseContextDocGroup_InputOutputMethods BaseContext Input & Output Methods 00032 \ingroup BaseContextDocGroup 00033 \brief Serialization methods. Also note BaseType::WriteFile() and 00034 BaseType::ReadFile() are valid for %BaseContext. 00035 */ 00036 /*! \addtogroup BaseContextDocGroup_EventManagement BaseContext Event Management Methods 00037 \ingroup BaseContextDocGroup 00038 \brief You can be notified of any change in the context with these Methods. 00039 This makes possible to build a complete user interface to edit the context. 00040 */ 00041 /*! \addtogroup BaseContextDocGroup_Undoing BaseContext Undo & Redo Methods 00042 \ingroup BaseContextDocGroup 00043 \brief %BaseContext provides an automatic management for all editable object members 00044 in the context. Active it with BaseContext::SetMaximumNumberOfUndoableEvents(). 00045 Note: its is currently beta, because re-creation of destroyed objects 00046 or list elements by undo is not managed at the moment, So any deletion 00047 on a list will flush the undo stack. 00048 */ 00049 00050 /*! 00051 \class ClassNode 00052 00053 \brief Class used privately by BaseContext to represent a class node in its 00054 database tree. This tree has the shape of the inheritance hierarchy. 00055 It manages a special hierarchic serialization which can re-create 00056 the object recursively. Basically, there is 1 classnode by class and context: 00057 It is initialized using a static BaseObject::ClassDescription, when using 00058 BaseContext::RegisterClassList(). 00059 Again: It IS NOT a class that is instancied to make BaseObject objects, it just indicates 00060 the class in the class hierarchy of BaseContext, and BaseObjects are under it in a list. 00061 It is also used for the context database access, and management. 00062 */ 00063 class ClassNode : public NamedObject 00064 { 00065 /*================================================================== 00066 PUBLIC 00067 ==================================================================*/ 00068 public: 00069 /*! 00070 \brief Constructor. Need a BaseObject::m_Descriptor static member. 00071 \parm _classDescription The static Class description structure. 00072 */ 00073 ClassNode( BaseObject::ClassDescription const &_classDescription ); 00074 #ifdef _ENGINE_EDITABLE_ 00075 /*! 00076 \brief Destructor. 00077 */ 00078 virtual ~ClassNode(void); 00079 #endif 00080 #ifdef _ENGINE_EDITABLE_ 00081 /*! 00082 \ingroup BaseContextDocGroup_ObjectEditionMethods 00083 \brief Declare all objects as if each were used with BaseObject::Close(). 00084 This can be used to force a re-creation of the whole context. 00085 */ 00086 void CloseAllObjects( ); 00087 #endif 00088 00089 /*! 00090 \brief Read the object description from a byte chunk. Could crash if chunk not valid. 00091 It serializes first the class name, the number of object instancied, then 00092 then all object instancied, then all subclasses recursively. 00093 */ 00094 virtual const unsigned char * Serialize_In( const unsigned char * _pDescriptionChunk); 00095 00096 #ifdef _ENGINE_EDITABLE_ 00097 /*! 00098 \brief get the size of the whole byte chunk that will be written by Serialize_Out(). 00099 \return byte size of the serialisation to do. 00100 */ 00101 virtual unsigned int GetSerializedDescriptionSize(void); 00102 #endif 00103 #ifdef _ENGINE_EDITABLE_ 00104 /*! 00105 \brief write the Current object definition to a Chunk using private packed types, recursively. 00106 \param _pDescriptionChunkToFill the chunk where to write the objet description chunk. 00107 \return the end of the chunk written, possibly unlocated. Don't use this if you don't need it. 00108 */ 00109 virtual unsigned char * Serialize_Out(unsigned char * _pDescriptionChunkToFill); 00110 #endif 00111 00112 /*! 00113 \brief Find an Object instancied from that class or another subclass. 00114 It is needed in non-editable mode to get a given object in the context base. 00115 \param _ObjectName the name of the object to get. 00116 \return the object or 0L if not found. 00117 */ 00118 BaseObject *GetBaseObject(const char * _ObjectName); 00119 00120 #ifdef _ENGINE_EDITABLE_ 00121 /*! 00122 \brief Factory Method to create a new Object in the context. All object members 00123 should be inited to default, then use BaseObject's Set methods in editable mode. 00124 This method is used in editable mode, but in serialize_in only mode, it does 00125 not compute a new name. 00126 \param _ObjectName. the objectName then used to reference it. computed if NULL. 00127 \return The Object Created. 0L if class unknown or anywhat. 00128 */ 00129 BaseObject *NewObject( const char * _ObjectName=0L ); 00130 #endif 00131 /*! 00132 \ingroup BaseContextDocGroup_InitMethods 00133 \brief Register a 0-ended list of static class descriptors ( BaseObject::ClassDescription ) 00134 from objects inherited from BaseObject, to the context, down the class tree. 00135 It is used by to register the classes in a context, before any serialization or context edition. 00136 IMPORTANT: You must register the classes in an order so that the inherited classes are set 00137 <b>after their parents</b>. BaseContext registers BaseObject itself in its constructor. 00138 It can look like: 00139 \code 00140 const BaseObject::ClassDescription * const descTable[]= 00141 { 00142 // standard class from VedaLib: 00143 & VirtualMedia::m_Description, 00144 & MediaTimePattern::m_Description, // class built over VirtualMedia. 00145 & MyClassInheritingBaseObject::m_Description, 00146 0L 00147 }; 00148 BaseContext myContext; 00149 myContext.RegisterClassList(descTable); 00150 \endcode 00151 In editable mode, you can check all class has been serialized 00152 with CheckClassListError() 00153 \param _ppclassDescriptionList BaseObject ( and inherited class ) 's 0-ended class descriptor list. 00154 */ 00155 void RegisterClassList( const BaseObject::ClassDescription * const * _ppclassDescriptionList ); 00156 00157 #ifdef _ENGINE_EDITABLE_ 00158 /*! 00159 \brief In editable mode, it is possible to destroy an object from the context base: 00160 This should be only used privately by BaseContext. 00161 This version can only destroy objects managed by this ClassNode. 00162 This method is only compiled in editable mode. 00163 \param _objectToDelete The object to delete. 00164 */ 00165 void DestroyManagedObject( BaseObject * _objectToDelete ); 00166 #endif 00167 #ifdef _ENGINE_EDITABLE_ 00168 /*! 00169 \brief return an explicit name for the class the object is instancied. 00170 \return a const character string. 00171 */ 00172 virtual const char *GetDisplayClassName() const { return ( m_ClassDescription->m_DisplayClassName ); }; 00173 #endif 00174 #ifdef _ENGINE_EDITABLE_ 00175 /*! 00176 \brief return the default name that is set to new objects if not specified. 00177 \return a const character string. 00178 */ 00179 virtual const char *GetDefaultObjectName() const { return ( m_ClassDescription->m_DefaultObjectName ); }; 00180 #endif 00181 #ifdef _ENGINE_EDITABLE_ 00182 /*! 00183 \brief return an explicit name for the class the object is instancied. 00184 \return a const character string. 00185 */ 00186 virtual const char *GetClassHelpDescription() const { return ( m_ClassDescription->m_ClassHelpDescription ); }; 00187 #endif 00188 00189 /*! 00190 \brief Find a Son ClassNode by its static description. It looks recursively in all branches of the context. 00191 \param _classDescription the descripter. 00192 \return the classnode or 0L if not found. 00193 */ 00194 ClassNode *GetSubClassNodeByDescription( const BaseObject::ClassDescription * _classDescription); 00195 #ifdef _ENGINE_EDITABLE_ 00196 /*! 00197 \brief get the first son classnode if not a leaf class, else NULL.Used by editors. 00198 \return the classnode or 0L if not found. 00199 */ 00200 const ClassNode *GetFirstSonClassNode() const { return m_pFirstSonClassNode; } ; 00201 #endif 00202 #ifdef _ENGINE_EDITABLE_ 00203 /*! 00204 \brief get the next brother classnode. If we are the last broteher, NULL.Used by editors. 00205 \return the classnode or 0L if not found. 00206 */ 00207 const ClassNode *GetNextBrotherClassNode() const { return m_pNextBrotherClassNode; } ; 00208 #endif 00209 /*! 00210 \brief get the managed object list, in a read only way: you can get the object, edit the 00211 objects, but can't edit the list. Used by editors. 00212 \return the classnode or 0L if not found. 00213 */ 00214 inline const PackList *GetObjectList() const { return &m_BaseObjectList; } ; 00215 00216 #ifdef _ENGINE_EDITABLE_ 00217 /*! 00218 \brief false if class is able to create objects, true if virtual. 00219 \return true or false 00220 */ 00221 bool IsAbstract() const { return ( 0L == m_ClassDescription->m_NewMethod); } ; 00222 #endif 00223 #ifdef _ENGINE_EDITABLE_ 00224 /*! 00225 \brief return true if this class has at least one object created, or got an inherited class that has 00226 at least an object created. false if it is not currently used. 00227 this method is used by serialize_out() to check if a class should be written. 00228 \return true or false 00229 */ 00230 bool IsUseful() const ; 00231 #endif 00232 #ifdef _ENGINE_EDITABLE_ 00233 /*! 00234 \brief Acts like Serialize_In() but keep all previous objects. 00235 So you can load and mix 2 or more context this way. 00236 \param _pDescriptionChunk the binary image of a context. 00237 \param _pendName specify a name to add at the end of each new object. 00238 */ 00239 virtual const unsigned char * MergeSerialize_In( const unsigned char * _pDescriptionChunk,const char *_pendName=0L); 00240 #endif 00241 00242 #ifdef _ENGINE_EDITABLE_ 00243 /*! 00244 \brief reset a new unique index for PackObjectReference serialization. It does recursively in all branches of the context. 00245 This reference index is only valid during serialization. 1 is the minimum 00246 \param _FirstnumberToSet the first number for the first oject managed by this ClassNode. 00247 \param _increment the number that is added to get the next number. 00248 \return the next available index. 00249 */ 00250 unsigned int SetObjectsUniqueReferenceIndex( unsigned int _FirstnumberToSet=1,int _increment=1 ); 00251 #endif 00252 00253 #ifdef _ENGINE_EDITABLE_ 00254 /*! 00255 \brief Set all object managed's name to "" (empty string) in order to same memory in the context. It is recursive to other sub classnodes. 00256 */ 00257 virtual void FlushNames(); 00258 #endif 00259 00260 /*! 00261 \brief Find an Object instancied from that class or another subclass by its serialized index. Should only be used by BaseContext::Serialize_In. 00262 \param _index special number 00263 \return the object or 0L if not found. 00264 */ 00265 BaseObject *GetBaseObjectBySerializedIndex( unsigned int _index); 00266 #ifdef _ENGINE_EDITABLE_ 00267 /*! 00268 \brief Each BaseType's inherited classes must explicit an ID for their 00269 class, or let use one of the super class at least through this virtual method. 00270 This is needed by GUIs to detect the types of each sub-members, and shape 00271 an interface for each Object according to their member list. 00272 \return a const character string, that must be unique and unchanged for all serializable base type. 00273 */ 00274 virtual const char *GetClassID() const { return ("ClassNode" ); }; 00275 #endif 00276 #ifdef _ENGINE_EDITABLE_ 00277 /*! 00278 \brief tool for BaseContext::ExportAsCPPTableFile() , recursive write of 00279 a .cpp definition of a class description. 00280 \param _fileTextImage 00281 */ 00282 void ExportCPPClassDescription( PackString &_fileTextImage ) const ; 00283 #endif 00284 #ifdef _ENGINE_EDITABLE_ 00285 /*! 00286 \brief tool for BaseContext::ExportAsCPPTableFile() , recursive write of 00287 a .cpp definition of a class description. 00288 \param _fileTextImage the source where a line is added. 00289 */ 00290 void ExportCPPClassDescriptionLine( PackString &_fileTextImage ) const; 00291 #endif 00292 #ifdef _ENGINE_EDITABLE_ 00293 /*! 00294 \brief If RegisterClassList() detected something wrong about 00295 the class list, the faulty class is reported here. 00296 From now on, the only possible error is: 2 class 00297 have the same serializer ID, on the same hierarchy level. 00298 \return the faulty class, or 0 if OK. 00299 */ 00300 const BaseObject::ClassDescription *CheckClassListError() const; 00301 #endif 00302 /*================================================================== 00303 PROTECTED 00304 ==================================================================*/ 00305 protected: 00306 00307 //! reference to the static class descriptor. This classNode manages this class in this context. 00308 const BaseObject::ClassDescription * m_ClassDescription; 00309 #ifdef _ENGINE_EDITABLE_ 00310 //! Serializable member that stands for the number of objects instancied. 00311 unsigned int m_NumberOfObjectInstancied; 00312 #endif 00313 #ifdef _ENGINE_EDITABLE_ 00314 //! \brief an enum used by serialization. 00315 typedef enum{ 00316 eSerError_OK=0, 00317 eSerError_BadChunkHead 00318 } eSerializationError ; 00319 //! this explicit the state after the last Serialize_In() done. 00320 eSerializationError m_SerializationState; 00321 #endif 00322 //! object that handle the object list: it is serialized without registration 00323 PackList m_BaseObjectList; 00324 00325 //! pointer to Next class which inherit from the same upper class, or NULL (if it ends the list) . 00326 ClassNode *m_pNextBrotherClassNode; 00327 00328 //! pointer to the First classNode which class managed inherit from the class managed here, or NULL. 00329 ClassNode *m_pFirstSonClassNode; 00330 #ifdef _ENGINE_EDITABLE_ 00331 // note: defined here for BaseContext.h, to handle lock in some methods 00332 //! Thread management: lock from the thread editing objects: 00333 volatile bool m_OwnerThreadIsCurrentlyManagingObjects; 00334 //! test debug member, to check the lock state of a context if a crash occurs because of a bad lock. 00335 volatile int m_TESTDEBUG_CONTEXTLOCK_ID; 00336 //! Thread management: number of threads currently using objects. This should come back to zero most of the times. 00337 volatile unsigned int m_NumberOfThreadsCurrentlyLockingTheContext; 00338 #endif 00339 #ifdef _ENGINE_EDITABLE_ 00340 //! if a faulty class descriptor was registered, report it: It's a developper debugger feature. 00341 const BaseObject::ClassDescription *m_pLastClassDescWithFaultySerializer; 00342 #endif 00343 #ifdef _ENGINE_EDITABLE_ 00344 /*! 00345 \brief Destroy all managed object. Used to clean up the whole context. 00346 */ 00347 void DestroyAllManagedObjects(); 00348 #endif 00349 #ifdef _ENGINE_EDITABLE_ 00350 /*! 00351 \brief Destroy all managed object, and all object of all subclasses recursively. 00352 */ 00353 void ProtectedDestroyAllObjects(); 00354 #endif 00355 #ifdef _ENGINE_EDITABLE_ 00356 /*! 00357 \brief Remove all objects that are not refered directly or indirectly by the object passed. 00358 \param _pObjectWhichAllOtherShouldDependOn Object Which All Other Should Depend On. 00359 */ 00360 void ProtectedDestroyAllIndependantObjects( BaseObject *_pObjectWhichAllOtherShouldDependOn ); 00361 #endif 00362 #ifdef _ENGINE_EDITABLE_ 00363 /*! 00364 \brief register management of the same classes to another context. 00365 (and so create another ClassNodes to it.) 00366 Used by BaseContext::CloneClassesAndObjects(). 00367 */ 00368 void ProtectedAddSameClasses( BaseContext *_pContextToAddManagement ); 00369 #endif 00370 00371 }; 00372 00373 #endif
/\/\ 4 N k ! N D _______ _ __ ___ _____ ___ _ _ ____ ___________ __//___ /________ |/ / ___________\_______/ \ / _ _ \/ _ / _ / _/_/____/ _ __ / / / / / / / \ \/ / / \ \ / \\___/___/___/ ¯ _____/_____/ ______\___/_____/\________\\ \________/_ ___ __ l____\ /elD! http://www.m4nkind.com \____/