FUtils/FUObject.h

Go to the documentation of this file.
00001 /*
00002    Copyright (C) 2005-2007 Feeling Software Inc.
00003    Portions of the code are:
00004    Copyright (C) 2005-2007 Sony Computer Entertainment America
00005    
00006    MIT License: http://www.opensource.org/licenses/mit-license.php
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         // Are you attempting to transfer ownership or do multiple-containment?
00088         // (owner == NULL) is used to avoid the notification when the container
00089         // knows its about to release this object.
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         // This assert verifies that we are, indeed, the owner.
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_

Generated on Thu Feb 14 16:58:35 2008 for FCollada by  doxygen 1.4.6-NO