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
1.3.8-20040913