- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# 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_