Veda/ClassNode.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_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 \____/