00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef _EYEDB_GBX_H
00026 #define _EYEDB_GBX_H
00027
00028 #include <stdlib.h>
00029 #include <map>
00030 #include <vector>
00031 #include <string>
00032
00033 namespace eyedb {
00034
00040 class LinkedList;
00041
00042 class gbxTag;
00043 class gbxCycleContext;
00044
00045 enum gbxBool {
00046 gbxFalse = 0,
00047 gbxTrue = 1
00048 };
00049
00053 class gbxObject {
00054
00055
00056
00057
00058 public:
00059 gbxObject();
00060 gbxObject(const std::string &ptag);
00061 gbxObject(const gbxTag &tag);
00062 gbxObject(const gbxObject &);
00063 gbxObject(const gbxObject *);
00064
00065 gbxObject &operator=(const gbxObject &);
00066
00067 static void *operator new(size_t);
00068 static void operator delete(void *);
00069
00070 int getRefCount() const {return gbx_refcnt;}
00071 gbxBool isLocked() const {return gbx_locked;}
00072
00073 bool mustRelease() const {return gbx_must_release;}
00074
00075 virtual void incrRefCount();
00076 virtual void decrRefCount();
00077
00078 virtual void lock() {gbx_locked = gbxTrue;}
00079 virtual void unlock() {gbx_locked = gbxFalse;}
00080
00081 gbxBool isOnStack() const {return gbx_isonstack;}
00082
00083 void reserve();
00084
00085 void release();
00086
00087 void setTag(const gbxTag &);
00088 const gbxTag *getTag() const {return gbx_tag;}
00089 const std::string &getPTag() const {return gbx_ptag;}
00090
00091 virtual void userGarbage() {}
00092
00093 void keep();
00094 void unkeep();
00095
00096 static int getObjectCount() {return obj_cnt;}
00097 static int getHeapSize() {return heap_size;}
00098
00099 gbxBool isValidObject() const;
00100
00101 typedef std::map<gbxObject *, bool> Map;
00102 typedef std::map<gbxObject *, bool>::iterator MapIterator;
00103
00104 static void setObjMapped(bool obj_mapped, bool reinit_if_exists);
00105 static bool isObjMapped();
00106 static gbxObject::Map *getObjMap() {return obj_map;}
00107
00108 struct OnRelease {
00109 virtual void perform(gbxObject *) = 0;
00110 virtual ~OnRelease() {}
00111 };
00112
00113 void setOnRelease(OnRelease *on_release) {gbx_on_release = on_release;}
00114 OnRelease *getOnRelease() {return gbx_on_release;}
00115
00116 virtual ~gbxObject();
00117
00118
00119
00120
00121 protected:
00122 int gbx_refcnt;
00123 gbxBool gbx_locked;
00124 gbxBool gbx_isonstack;
00125 gbxTag *gbx_tag;
00126 std::string gbx_ptag;
00127 gbxBool gbx_chgRefCnt;
00128 bool gbx_must_release;
00129
00130 void garbageRealize(gbxBool reentrant = gbxFalse, gbxBool remove = gbxTrue);
00131 virtual void garbage() {}
00132 #ifdef GBX_NEW_CYCLE
00133 virtual void decrRefCountPropag() {}
00134 #endif
00135 virtual gbxBool grant_release() {return gbxTrue;}
00136
00137
00138
00139
00140 private:
00141 void init(const std::string &ptag);
00142 unsigned int gbx_magic;
00143 gbxBool gbx_activeDestruction;
00144 static int obj_cnt;
00145 static int heap_size;
00146 static Map *obj_map;
00147 OnRelease *gbx_on_release;
00148
00149 int gbx_size;
00150 void release_realize(gbxBool);
00151
00152
00153
00154
00155 public:
00156 virtual void manageCycle(gbxCycleContext &);
00157 void release_r();
00158 void setMustRelease(bool must_release) {gbx_must_release = must_release;}
00159 gbxBool isChgRefCnt() const {return gbx_chgRefCnt;}
00160 gbxBool setChgRefCnt(gbxBool chgRefCnt) {
00161 gbxBool old_chgRefCnt = gbx_chgRefCnt;
00162 gbx_chgRefCnt = chgRefCnt;
00163 return old_chgRefCnt;
00164 }
00165 };
00166
00167 class gbxDeleter {
00168
00169
00170
00171
00172
00173 public:
00174 gbxDeleter(gbxObject *);
00175
00176 gbxObject *keep();
00177 operator gbxObject *() {return o;}
00178
00179 ~gbxDeleter();
00180
00181 private:
00182 gbxBool _keep;
00183 gbxObject *o;
00184 };
00185
00186 class gbxRegObj;
00187
00188 class gbxAutoGarb {
00189
00190
00191
00192
00193 public:
00194 enum Type {
00195 SUSPEND = 1,
00196 ACTIVE
00197 };
00198
00199 static const int default_list_cnt = 512;
00200 gbxAutoGarb(int list_cnt = default_list_cnt);
00201 gbxAutoGarb(gbxAutoGarb::Type, int list_cnt = default_list_cnt);
00202 gbxAutoGarb(const gbxTag &, gbxBool excepted = gbxFalse, int list_cnt = default_list_cnt);
00203 gbxAutoGarb(gbxAutoGarb *);
00204 gbxAutoGarb(const gbxTag [], int cnt, gbxBool excepted = gbxFalse);
00205
00206 gbxAutoGarb::Type suspend();
00207 void restore(gbxAutoGarb::Type);
00208
00209 gbxAutoGarb::Type setType(gbxAutoGarb::Type);
00210 gbxAutoGarb::Type getType();
00211
00212 void keepObjs();
00213
00214 virtual ~gbxAutoGarb();
00215
00216 void addObj(gbxObject *);
00217 gbxBool isObjRegistered(gbxObject *);
00218 gbxBool isObjDeleted(gbxObject *);
00219 gbxBool keepObj(gbxObject *, gbxBool);
00220
00221 static void addObject(gbxObject *);
00222 static void keepObject(gbxObject *, gbxBool);
00223 static gbxBool isObjectRegistered(gbxObject *);
00224 static gbxBool isObjectDeleted(gbxObject *);
00225 static gbxAutoGarb *getCurrentAutoGarb() {return current_auto_garb;}
00226
00227
00228
00229
00230 private:
00231 gbxTag *tag;
00232 gbxBool excepted;
00233 gbxBool keepobjs;
00234 unsigned int regobjs_cnt;
00235 unsigned int list_cnt;
00236 unsigned int mask;
00237 LinkedList **todelete_lists;
00238 LinkedList **deleted_lists;
00239 unsigned int get_key(gbxObject *);
00240 gbxRegObj *find(gbxObject *o, LinkedList **);
00241 void wipeLists(LinkedList **);
00242 unsigned int countLists(LinkedList **, int state);
00243 unsigned int todelete_cnt;
00244 unsigned int deleted_cnt;
00245 void init(int);
00246
00247 static gbxAutoGarb *current_auto_garb;
00248 gbxAutoGarb *prev;
00249 Type type;
00250 gbxAutoGarb *deleg_auto_garb;
00251 void garbage();
00252 gbxAutoGarb *getAutoGarb();
00253
00254
00255
00256
00257 public:
00258 static void markObjectDeleted(gbxObject *);
00259 gbxBool markObjDeleted(gbxObject *);
00260 };
00261
00262 class gbxAutoGarbSuspender {
00263
00264 public:
00265 gbxAutoGarbSuspender();
00266 ~gbxAutoGarbSuspender();
00267
00268 private:
00269 gbxAutoGarb::Type type;
00270 gbxAutoGarb *current;
00271 };
00272
00273 class gbxTag {
00274
00275
00276
00277
00278 public:
00279 gbxTag();
00280 gbxTag(const gbxTag &);
00281 gbxTag(const char *stag);
00282 gbxTag(int itag);
00283 gbxTag(void *vtag);
00284
00285 gbxTag &operator=(const gbxTag &);
00286
00287 int operator==(const gbxTag &) const;
00288 int operator!=(const gbxTag &) const;
00289
00290 const char * getSTag() const {return stag;}
00291 const int getITag() const {return itag;}
00292 void * getVTag() const {return vtag;}
00293
00294 virtual ~gbxTag();
00295
00296
00297
00298
00299 private:
00300 char *stag;
00301 int itag;
00302 void *vtag;
00303 void init();
00304 };
00305
00306 class gbxObserver {
00307
00308
00309
00310
00311 public:
00312 typedef std::vector<gbxObject *> ObjectVector;
00313 typedef ObjectVector::iterator ObjectVectorIterator;
00314 typedef ObjectVector::const_iterator ObjectVectorConstIterator;
00315
00316 gbxObserver(const std::string &tag = "");
00317
00318 const std::string &getTag() const {return tag;}
00319
00320 virtual size_t getObjectCount() const;
00321
00322 virtual void getObjects(ObjectVector &) const;
00323
00324 virtual bool isObjectRegistered(gbxObject *) const;
00325
00326 class ObjectTrigger {
00327
00328 public:
00329 virtual void operator()(gbxObject *o) = 0;
00330 virtual ~ObjectTrigger();
00331 };
00332
00333 class AddObjectTrigger : public ObjectTrigger {
00334
00335 public:
00336 virtual ~AddObjectTrigger();
00337 };
00338
00339 class RemoveObjectTrigger : public ObjectTrigger {
00340
00341 public:
00342 virtual ~RemoveObjectTrigger();
00343 };
00344
00345 virtual void setAddObjectTrigger(AddObjectTrigger *trigger);
00346 virtual void setRemoveObjectTrigger(RemoveObjectTrigger *trigger);
00347
00348 static gbxObserver *getCurrentObserver() {return current_observer;}
00349
00350 virtual ~gbxObserver();
00351
00352
00353
00354
00355 static void addObject(gbxObject *o);
00356 static void rmvObject(gbxObject *o);
00357
00358 virtual void addObj(gbxObject *o);
00359 virtual void rmvObj(gbxObject *o);
00360
00361
00362
00363
00364 protected:
00365 std::map<gbxObject *, bool> *obj_map;
00366
00367
00368
00369
00370 private:
00371 std::string tag;
00372 gbxObserver *prev;
00373 AddObjectTrigger *addobj_trigger;
00374 RemoveObjectTrigger *rmvobj_trigger;
00375 static gbxObserver *current_observer;
00376 };
00377
00378 class gbxObjectPtr {
00379
00380 protected:
00381 gbxObject *o;
00382
00383 public:
00384 gbxObjectPtr(gbxObject *o = 0) {
00385 this->o = o;
00386 if (o && !o->mustRelease())
00387 o->reserve();
00388 }
00389
00390 gbxObjectPtr(const gbxObjectPtr &o_ptr) {
00391 o = 0;
00392 *this = o_ptr;
00393 }
00394
00395 gbxObjectPtr& operator=(const gbxObjectPtr &o_ptr) {
00396 if (o)
00397 o->release();
00398 o = o_ptr.o;
00399 if (o)
00400 o->reserve();
00401 return *this;
00402 }
00403
00404 gbxObject *getGBXObject() {return o;}
00405 const gbxObject *getGBXObject() const {return o;}
00406
00407 gbxObject *operator->() {return o;}
00408 const gbxObject *operator->() const {return o;}
00409
00410 bool operator!() const {return o == 0;}
00411
00412 virtual ~gbxObjectPtr() {
00413 if (o)
00414 o->release();
00415 o = 0;
00416 }
00417 };
00421 }
00422
00423 #endif