objectbase.h

Go to the documentation of this file.
00001 /**
00002  * \file objectbase.h <gre/objectbase.h>
00003  * \brief Define base GRE object class
00004  *
00005  * \if NODOC
00006  * $Id: objectbase.h_v 1.3 2003/09/15 13:48:59 fileserver!dwilliss Exp $
00007  *
00008  * $Log: objectbase.h_v $
00009  * Revision 1.3  2003/09/15 13:48:59  fileserver!dwilliss
00010  * Doxygen
00011  *
00012  * Revision 1.2  2003/07/30 15:33:20  mju
00013  * Ignore private sections.
00014  *
00015  * Revision 1.1  2003/06/16 19:40:04  mju
00016  * Initial revision
00017  *
00018  * \endif
00019 **/
00020 
00021 #ifndef  INC_GRE_OBJECTBASE_H
00022 #define  INC_GRE_OBJECTBASE_H
00023 
00024 #ifndef  INC_GRE_BASE_H
00025    #include <gre/base.h>
00026 #endif
00027 
00028 #ifndef  INC_GRE_MSG_H
00029    #include <gre/msg.h>
00030 #endif
00031 
00032 #ifndef  INC_MI32_MICON_H
00033    #include <mi32/micon.h>
00034 #endif
00035 
00036 #ifndef INC_STRING_H
00037    #include <string.h>
00038    #define INC_STRING_H
00039 #endif
00040 
00041 
00042 //! Base class for other GRE "spatial" objects.
00043 class GRE_OBJECT {
00044 
00045    public:
00046 
00047       typedef void (*CBFUNC)(const GRE_CALLBACK_MSG*, void*);
00048 
00049       //! Allocate index into private pointer array to attach to.
00050       //! @see GetPrivPtr, SetPrivPtr
00051       //! It is often desirable for a process or library module to attach "private"
00052       //! data to one or more GRE objects.  This can be done using AllocPrivIndex()
00053       //! to allocate an entry into each object's private pointer array.  This method
00054       //! should only be called the first time the private index is needed.  It is
00055       //! the programmer's responsibility to retain this private index value.  Once
00056       //! a private index is allocated, use SetPrivPtr() to attach data to any GRE
00057       //! object and GetPrivPtr() to retrieve previously attached data.
00058       static int AllocPrivIndex (
00059          );
00060 
00061       //! Constructor
00062       explicit GRE_OBJECT (
00063          GRE_OBJTYPE type                       //!< Object type to construct
00064          );
00065 
00066       //! Destructor.
00067       virtual ~GRE_OBJECT (
00068          ) = 0;
00069 
00070       //! Request destruction of this object.
00071       //! @return true if destroyed, false if destruction deferred.
00072       //! If an object is dynamically created then unless the destruction occurs
00073       //! in the same function as creation the Destroy() method should be used 
00074       //! instead.  This is especially true if destruction is to be performed within
00075       //! a GRE callback.  Using delete on an object withing a callback may result
00076       //! in unpredictable behavior.
00077       bool Destroy (
00078          bool NotifyParent = true               //!< Notify parent of child's destruction if appropriate
00079          ) { return (v_Destroy(NotifyParent)); }
00080 
00081       //! Get icon for this object type.
00082       MICON GetIcon (
00083          ) const { return (v_GetIcon()); }
00084 
00085       //! Get name of this object type.
00086       //! @return Pointer to constant string.
00087       const char* GetTypeName (
00088          ) const { return (v_GetTypeName()); }
00089 
00090       //! Get name of this object type in string.
00091       //! @return Pointer to string provided.
00092       char* GetTypeName (
00093          char *string                           //!< String to fill in
00094          ) { strcpy(string,GetTypeName()); return (string); }
00095 
00096       //! Add callback function to object.
00097       //!
00098       //! The new callback function will be added to the head of the list.
00099       //!
00100       //! Callbacks may be added to any GRE object.  When a callback occurs for a particular object
00101       //! the message is sent to that object's callback list and any "ancestor" object's callback
00102       //! lists as well.  A callback will be called if the object type for the message was included in
00103       //! the object types specified when the callback was added.  This often eliminates the need to
00104       //! add callbacks to every GRE object which is created.  If a program creates a single group
00105       //! and needs information about the group and layers within it then a callback can be added
00106       //! to the group with GRE_OBJTYPE_Group and GRE_OBJTYPE_Layer specified.  Then within the
00107       //! callback itself a determination of the object type may be done.  Alternatively two callbacks
00108       //! might be used, one specifying GRE_OBJTYPE_Group and the other specifying GRE_OBJTYPE_Layer.
00109       //! Both callbacks would be added to the group, but no check of the object type would be needed
00110       //! within the callback since only one object type was specified when each callback was added.
00111       void CallbackAdd (
00112          CBFUNC cbfunc,                         //!< Callback function
00113          void *cbdata,                          //!< "Hook" data to pass to callback
00114          GRE_OBJTYPE objtypes                   //!< Object types for which messages are requested
00115          ) { m_CallbackList.Add(cbfunc,cbdata,objtypes); }
00116 
00117       //! Invoke callbacks on object and its ancestors.
00118       //! This method is generally only invoked from within the GRE library itself.
00119       void CallbackInvoke (
00120          GRE_CALLBACK_MSG::ACTION action,
00121          GRE_VIEW *view = 0,
00122          ELEMTYPE elemtype = ELEMTYPE_Empty
00123          ) { GRE_CALLBACK_MSG msg(action,this,view,elemtype); CallbackInvoke(msg); }
00124          
00125       //! Invoke callbacks on object and its ancestors.
00126       //! This method is generally only invoked from within the GRE library itself.
00127       void CallbackInvoke (
00128          GRE_CALLBACK_MSG::ACTION action,
00129          ELEMTYPE elemtype
00130          ) { GRE_CALLBACK_MSG msg(action,this,elemtype); CallbackInvoke(msg); }
00131          
00132       //! Invoke callbacks on object and its ancestors.
00133       //! This method is generally only invoked from within the GRE library itself.
00134       void CallbackInvoke (
00135          GRE_VIEW *view,
00136          GRE_CALLBACK_MSG::ACTION action
00137          ) { GRE_CALLBACK_MSG msg(action,this,view); CallbackInvoke(msg); }
00138          
00139       //! Invoke callbacks on object and its ancestors.
00140       //! This method is generally only invoked from within the GRE library itself.
00141       void CallbackInvoke (
00142          const GRE_CALLBACK_MSG& msg
00143          );
00144       
00145       //! Remove callback function.
00146       //! All callbacks are automatically removed when the object is destroyed.
00147       //! However, if the data specified when the callback was added is freed 
00148       //! before the object is destroyed, all callbacks referencing that data
00149       //! should be removed.  In this case, the cbfunc may be specified as NULL
00150       //! and the cbdata should be the pointer about to be freed.  This will
00151       //! remove all callbacks referencing that pointer in a single step.
00152       void CallbackRemove (
00153          CBFUNC cbfunc,                         //!< Callback function, matching CallbackAdd, or NULL to match all
00154          void *cbdata,                          //!< Callback data, matching CallbackAdd
00155          GRE_OBJTYPE objtypes = GRE_OBJTYPE_All //!< Object types
00156          ) { m_CallbackList.Remove(cbfunc,cbdata,objtypes); }
00157 
00158       //! Determine if destruction has been requested for this object.
00159       //! Sometimes a callback may be invoked on an object after destruction has been
00160       //! requested on that object.  This may occur if destruction occurs in a callback
00161       //! and more callbacks are in the list after the one destroying the object.  In
00162       //! order to avoid unwanted processing or errors it may be necessary to determine
00163       //! if an object has been requested to be destroyed.  This is only useful within
00164       //! a callback since once the callbacks are completed the destruction will finish
00165       //! and thus the object will no longer exist.
00166       bool DestroyRequested (
00167          ) const { return (m_DestroyRequested); }
00168 
00169       //! Get "private" pointer for this object.
00170       //! @see AllocPrivIndex, SetPrivPtr
00171       void *GetPrivPtr (
00172          int idx                                //!< Private index obtained from AllocPrivIndex()
00173          ) const { return (m_PrivData[idx]); }
00174 
00175       //! Get GRE object type
00176       GRE_OBJTYPE GetType (
00177          ) const { return (m_objtype); }
00178 
00179       //! Determine if object in process of being destroyed.
00180       //! Sometimes a callback may be invoked on an object after destruction has begun
00181       //! on that object. In order to avoid unwanted processing or errors it may be
00182       //! necessary to determine if an object is in the process of being destroyed.
00183       //! This is only useful within a callback since once the callbacks are completed
00184       //! the destruction will finish and thus the object will no longer exist.
00185       bool IsBeingDestroyed (
00186          ) const { return (m_BeingDestroyed); }
00187 
00188       //! Set "private" pointer for this object.
00189       //! When an object is destroyed, the private pointers are NOT freed by the GRE
00190       //! system.  Thus it is the programmers responsibility to see that allocated data
00191       //! attached to an object is freed at the appropriate time, usually by checking for
00192       //! ACTION_Destroy in the callback message.
00193       //! @see GetPrivPtr, AllocPrivIndex
00194       void SetPrivPtr (
00195          int idx,                               //!< Private index obtained from AllocPrivIndex()
00196          void *privptr                          //!< Pointer value to set.
00197          ) { m_PrivData[idx] = privptr; }
00198 
00199    protected:
00200 
00201       //! Determine if callbacks are currently being invoked on this object.
00202       bool CallbacksBeingInvoked (
00203          ) const { return (m_CallbackList.BeingInvoked()); }
00204 
00205       //! Notify object that is being destroyed, usually called by Destroy() method
00206       void SetBeingDestroyed (
00207          ) { m_BeingDestroyed = true; }
00208 
00209       //! Request destruction of object, usually called by Destroy() method
00210       void SetDestroyRequest (
00211          ) { m_DestroyRequested = true; }
00212 
00213    private:
00214 
00215       #ifndef GENERATING_DOXYGEN_OUTPUT
00216 
00217       // GRE_OBJECT::CBFUNCLIST
00218       //! Callback function list.
00219       class CBFUNCLIST {
00220          public:
00221 
00222             CBFUNCLIST (
00223                );
00224 
00225             ~CBFUNCLIST (
00226                );
00227 
00228             //! Add function to callback list
00229             void Add (
00230                CBFUNC cbfunc,                   //!< Function to add
00231                void *cbdata,                          //!< "Hook" data to pass to function
00232                GRE_OBJTYPE objtypes                   //!< Object type(s) for which messages are requested
00233                );
00234 
00235             //! Determine if callback list is currently being invoked.
00236             bool BeingInvoked (
00237                ) const { return (m_callcount > 0); }
00238 
00239             //! Invoke callbacks in list with specified message.
00240             void Invoke (
00241                const GRE_CALLBACK_MSG& msg            //!< Message
00242                );
00243 
00244             //! Remove function from callback list
00245             void Remove (
00246                CBFUNC cbfunc,                   //!< Function to remove, NULL to match all
00247                void *cbdata,                          //!< "Hook" data, must match value used in Add, or NULL to match all
00248                GRE_OBJTYPE objtypes = GRE_OBJTYPE_All //!< Object type(s) to match
00249                );
00250 
00251          private:
00252             // GRE_OBJECT::CBFUNCLIST::ITEM
00253             class ITEM {
00254                public:
00255 
00256                   ITEM (
00257                      CBFUNC cbfunc,
00258                      void *cbdata,
00259                      GRE_OBJTYPE objtypes
00260                      );
00261 
00262                   CBFUNC m_cbfunc;
00263                   void *m_cbdata;
00264                   GRE_OBJTYPE m_objtypes;
00265                   ITEM *m_next;
00266                };
00267 
00268             ITEM *m_first;
00269             UINT16 m_callcount;
00270             bool m_DidRemove;
00271          };
00272 
00273       static int s_PrivDataCount;            //!< Number of private data index entries used
00274       static int s_PrivDataAlloc;            //!< Number of private data index entries allocated
00275 
00276       const GRE_OBJTYPE m_objtype;           //!< Object type
00277       void **m_PrivData;                     //!< Private data for modules to attach stuff to
00278       CBFUNCLIST m_CallbackList;             //!< Callback list
00279       bool m_DestroyRequested;               //!< Destroy requested while in callback
00280       bool m_BeingDestroyed;                 //!< Object in process of being destroyed
00281 
00282       #endif //!< GENERATING_DOXYGEN_OUTPUT
00283 
00284       //! Overridables.
00285       virtual bool v_Destroy (bool NotifyParent) = 0;
00286       virtual MICON v_GetIcon () const = 0;
00287       virtual const char* v_GetTypeName () const = 0;
00288    };
00289 
00290 
00291 #endif   //!< INC_GRE_OBJECTBASE_H

Generated on Tue Dec 14 13:18:14 2004 for TNTsdk by  doxygen 1.3.8-20040913