00001
00002
00003
00004
00005
00006
00007
00008
00015 #ifndef _FU_OBJECT_H_
00016 #define _FU_OBJECT_H_
00017
00018 #ifndef _FU_OBJECT_TYPE_H_
00019 #include "FUtils/FUObjectType.h"
00020 #endif // _FU_OBJECT_TYPE_H_
00021
00022 class FUObjectOwner;
00023
00030 class FCOLLADA_EXPORT FUObject
00031 {
00032 private:
00033 static class FUObjectType* baseObjectType;
00034
00035 FUObjectOwner* objectOwner;
00036
00037 protected:
00040 static const uint32 nextAvailableBit = 0;
00041
00042 public:
00046 FUObject();
00047
00049 virtual ~FUObject();
00050
00055 virtual void Release();
00056
00059 static const FUObjectType& GetClassType() { return *baseObjectType; }
00060
00063 virtual const FUObjectType& GetObjectType() const { return *baseObjectType; }
00064
00068 inline bool IsType(const FUObjectType& _type) const { return GetObjectType() == _type; }
00069
00073 inline bool HasType(const FUObjectType& _type) const { return GetObjectType().Includes(_type); }
00074
00075 protected:
00078 void Detach();
00079
00080 private:
00081 friend class FUObjectOwner;
00082
00085 inline void SetObjectOwner(FUObjectOwner* owner)
00086 {
00087
00088
00089
00090 FUAssert(objectOwner == NULL || owner == NULL, return);
00091 objectOwner = owner;
00092 }
00093 };
00094
00101 class FUObjectOwner
00102 {
00103 protected:
00106 inline void AttachObject(FUObject* object) { object->SetObjectOwner(this); }
00107
00112 inline void DetachObject(FUObject* object)
00113 {
00114
00115 FUAssert(object->objectOwner == this, return);
00116 object->SetObjectOwner(NULL);
00117 }
00118
00119 public:
00121 virtual ~FUObjectOwner() {}
00122
00125 virtual void OnOwnedObjectReleased(FUObject* object) = 0;
00126 };
00127
00133 template <class HigherClassType>
00134 inline HigherClassType* DynamicCast(FUObject* object) { return object->HasType(HigherClassType::GetClassType()) ? (HigherClassType*) object : NULL; }
00135
00146 template <class ObjectClass = FUObject>
00147 class FUObjectRef : public FUObjectOwner
00148 {
00149 private:
00150 typedef fm::pvector<ObjectClass> Parent;
00151
00153 ObjectClass* ptr;
00154
00155 public:
00159 FUObjectRef(ObjectClass* _ptr = NULL)
00160 : ptr(_ptr)
00161 {
00162 if (_ptr != NULL) AttachObject((FUObject*) ptr);
00163 }
00164
00167 ~FUObjectRef()
00168 {
00169 if (ptr != NULL)
00170 {
00171 DetachObject((FUObject*) ptr);
00172 ((FUObject*) ptr)->Release();
00173 #ifdef _DEBUG
00174
00175 ptr = NULL;
00176 #endif // _DEBUG
00177
00178 }
00179 }
00180
00184 FUObjectRef<ObjectClass>& operator=(ObjectClass* _ptr)
00185 {
00186 if (ptr != NULL) ((FUObject*) ptr)->Release();
00187 FUAssert(ptr == NULL, return *this);
00188 ptr = _ptr;
00189 if (_ptr != NULL) AttachObject((FUObject*) ptr);
00190 return *this;
00191 }
00192
00199 FUObjectRef<ObjectClass>& operator=(FUObjectRef<ObjectClass>& _ptr)
00200 {
00201 operator=(_ptr.ptr);
00202 _ptr.ptr = NULL;
00203 return *this;
00204 }
00205
00208 inline ObjectClass& operator*() { FUAssert(ptr != NULL, return *ptr); return *ptr; }
00209 inline const ObjectClass& operator*() const { FUAssert(ptr != NULL, return *ptr); return *ptr; }
00210 inline ObjectClass* operator->() { return ptr; }
00211 inline const ObjectClass* operator->() const { return ptr; }
00212 inline operator ObjectClass*() { return ptr; }
00213 inline operator const ObjectClass*() const { return ptr; }
00215 protected:
00219 virtual void OnOwnedObjectReleased(FUObject* object)
00220 {
00221 FUAssert((size_t) object == (size_t) ptr, return);
00222 ptr = NULL;
00223 }
00224 };
00225
00226
00233 template <typename ObjectClass = FUObject>
00234 class FUObjectContainer : private fm::pvector<ObjectClass>, public FUObjectOwner
00235 {
00236 private:
00237 typedef fm::pvector<ObjectClass> Parent;
00238 public:
00239 typedef ObjectClass** iterator;
00240 typedef const ObjectClass** const_iterator;
00241
00242 public:
00245 virtual ~FUObjectContainer() { clear(); }
00246
00248 void clear()
00249 {
00250 while (size() > 0)
00251 {
00252 FUObject* last = (FUObject*) Parent::back();
00253 Parent::pop_back();
00254 DetachObject(last);
00255 last->Release();
00256 }
00257 }
00258
00261 inline size_t size() const { return Parent::size(); }
00262
00265 inline bool empty() const { return Parent::empty(); }
00266
00269 ObjectClass*& front() { return (ObjectClass*&) Parent::front(); }
00270 const ObjectClass*& front() const { return (const ObjectClass*&) Parent::front(); }
00274 ObjectClass*& back() { return (ObjectClass*&) Parent::back(); }
00275 const ObjectClass*& back() const { return (const ObjectClass*&) Parent::back(); }
00280 inline ObjectClass* at(size_t index) { return (ObjectClass*) Parent::at(index); }
00281 inline const ObjectClass* at(size_t index) const { return (const ObjectClass*) Parent::at(index); }
00282 template <class INTEGER> inline ObjectClass* operator[](INTEGER index) { return at(index); }
00283 template <class INTEGER> inline const ObjectClass* operator[](INTEGER index) const { return at(index); }
00287 inline iterator begin() { return (iterator) Parent::begin(); }
00288 inline const_iterator begin() const { return (const_iterator) Parent::begin(); }
00292 inline iterator end() { return (iterator) Parent::end(); }
00293 inline const_iterator end() const { return (const_iterator) Parent::end(); }
00299 inline iterator find(const ObjectClass* item) { return (iterator) Parent::find(item); }
00300 inline const_iterator find(const ObjectClass* item) const { return (const_iterator) Parent::find(item); }
00304 inline void push_back(ObjectClass* object)
00305 {
00306 AttachObject((FUObject*) object);
00307 Parent::push_back(object);
00308 }
00309
00314 iterator insert(iterator _iterator, ObjectClass* object)
00315 {
00316 AttachObject((FUObject*) object);
00317 return (iterator) Parent::insert(_iterator, object);
00318 }
00319
00323 inline void insert(size_t index, ObjectClass* object) { insert(begin() + index, object); }
00324
00330 template <class _It>
00331 void insert(iterator _where, _It _startIterator, _It _endIterator)
00332 {
00333 if (_startIterator < _endIterator)
00334 {
00335 size_t relativeWhere = _where - begin();
00336 size_t count = _endIterator - _startIterator;
00337 Parent::insert(Parent::begin() + relativeWhere, count);
00338 _where = begin() + relativeWhere;
00339
00340 for (; _startIterator != _endIterator; ++_startIterator, ++_where)
00341 {
00342 *_where = const_cast<ObjectClass*>((const ObjectClass*)(*_startIterator));
00343 AttachObject((FUObject*) *_startIterator);
00344 }
00345 }
00346 }
00347
00349 void pop_back()
00350 {
00351 FUAssert(!Parent::empty(), return);
00352 FUObject* last = (FUObject*) Parent::back();
00353 Parent::pop_back();
00354 DetachObject(last);
00355 last->Release();
00356 }
00357
00361 void pop_front()
00362 {
00363 FUAssert(!Parent::empty(), return);
00364 FUObject* first = (FUObject*) Parent::front();
00365 Parent::pop_front();
00366 DetachObject(first);
00367 first->Release();
00368 }
00369
00372 iterator erase(iterator _it)
00373 {
00374 FUAssert(contains(*_it), return _it);
00375 FUObject* o = (FUObject*) * _it;
00376 iterator it = (iterator) Parent::erase(_it);
00377 DetachObject(o);
00378 o->Release();
00379 return it;
00380 }
00381
00385 inline void erase(iterator first, iterator last)
00386 {
00387 for (iterator it = first; it != last; ++it)
00388 {
00389 FUObject* o = (FUObject*) * it;
00390 DetachObject(o);
00391 o->Release();
00392 }
00393 Parent::erase(first, last);
00394 }
00395
00399 inline void erase(size_t first, size_t last) { erase(begin() + first, begin() + last); }
00400
00404 inline bool erase(const ObjectClass* value)
00405 {
00406 iterator it = find(value);
00407 if (it == Parent::end()) return false;
00408 erase(it);
00409 return true;
00410 }
00411
00416 iterator Detach(iterator _it)
00417 {
00418 FUAssert(contains(*_it), return _it);
00419 FUObject* o = (FUObject*) * _it;
00420 iterator it = (iterator) Parent::erase(_it);
00421 DetachObject(o);
00422 return it;
00423 }
00424
00430 inline void Detach(iterator first, iterator last)
00431 {
00432 for (iterator it = first; it != last; ++it)
00433 {
00434 FUObject* o = (FUObject*) * it;
00435 DetachObject(o);
00436 }
00437 Parent::erase(first, last);
00438 }
00439
00445 inline void Detach(size_t first, size_t last) { Detach(begin() + first, begin() + last); }
00446
00452 inline bool Detach(const ObjectClass* value)
00453 {
00454 iterator it = find(value);
00455 if (it == Parent::end()) return false;
00456 Detach(it);
00457 return true;
00458 }
00459
00462 inline void erase(size_t index) { erase(begin() + index); }
00463
00467 inline void reserve(size_t count) { Parent::reserve(count); }
00468
00472 inline bool contains(const ObjectClass* value) const { return Parent::contains(value); }
00473
00479 DEPRECATED(3.05A, "FUObject::Release()") bool release(const ObjectClass* value)
00480 {
00481 ObjectClass** it = find(value);
00482 if (it != Parent::end()) { ((FUObject*) value)->Release(); return true; }
00483 return false;
00484 }
00485
00488 ObjectClass* Add()
00489 {
00490 ObjectClass* object = new ObjectClass();
00491 push_back(object);
00492 return object;
00493 }
00494
00498 template <class A1>
00499 ObjectClass* Add(const A1& arg1)
00500 {
00501 ObjectClass* object = new ObjectClass(arg1);
00502 push_back(object);
00503 return object;
00504 }
00505
00510 template <class A1, class A2>
00511 ObjectClass* Add(const A1& arg1, const A2& arg2)
00512 {
00513 ObjectClass* object = new ObjectClass(arg1, arg2);
00514 push_back(object);
00515 return object;
00516 }
00517
00523 template <class A1, class A2, class A3>
00524 ObjectClass* Add(const A1& arg1, const A2& arg2, const A3& arg3)
00525 {
00526 ObjectClass* object = new ObjectClass(arg1, arg2, arg3);
00527 push_back(object);
00528 return object;
00529 }
00530
00531 protected:
00534 virtual void OnOwnedObjectReleased(FUObject* object)
00535 {
00536 FUAssert(Parent::contains(object), return);
00537 Parent::erase((ObjectClass*) object);
00538 }
00539 };
00540
00541 #endif // _FU_OBJECT_H_