FUtils/FUTracker.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 
00009 #ifndef _FU_TRACKER_H_
00010 #define _FU_TRACKER_H_
00011 
00017 #ifndef _FU_OBJECT_H_
00018 #include "FUtils/FUObject.h"
00019 #endif // _FU_OBJECT_H_
00020 
00021 class FUTracker;
00022 
00032 class FCOLLADA_EXPORT FUTrackable : public FUObject
00033 {
00034 private:
00035     DeclareObjectType(FUObject);
00036 
00037     // The objects tracking this one.
00038     typedef fm::pvector<FUTracker> FUTrackerList;
00039     FUTrackerList trackers;
00040 
00041 public:
00045     FUTrackable();
00046 
00049     virtual ~FUTrackable();
00050 
00054     size_t GetTrackerCount() const { return trackers.size(); }
00055 
00056 protected:
00060     void Detach();
00061 
00062 private:
00063     friend class FUTracker;
00064     void AddTracker(FUTracker* tracker);
00065     void RemoveTracker(FUTracker* tracker);
00066     bool HasTracker(const FUTracker* tracker) const;
00067 };
00068 
00069 
00077 class FCOLLADA_EXPORT FUTracker
00078 {
00079 public:
00081     virtual ~FUTracker() {}
00082 
00086     virtual void OnObjectReleased(FUTrackable* object) = 0;
00087 
00090     virtual bool TracksObject(const FUTrackable* object) const { return object != NULL ? object->HasTracker(this) : false; }
00091 
00092 protected:
00095     void TrackObject(FUTrackable* object) { if (object) object->AddTracker(this); }
00096 
00099     void UntrackObject(FUTrackable* object) { if (object) object->RemoveTracker(this); }
00100 };
00101 
00108 template <class ObjectClass = FUTrackable>
00109 class FUTrackedPtr : public FUTracker
00110 {
00111 protected:
00113     ObjectClass* ptr;
00114 
00115 public:
00119     FUTrackedPtr(ObjectClass* _ptr = NULL) : ptr(_ptr)
00120     {
00121         if (ptr != NULL) FUTracker::TrackObject((FUTrackable*) ptr);
00122         ptr = ptr;
00123     }
00124 
00127     ~FUTrackedPtr()
00128     {
00129         if (ptr != NULL) FUTracker::UntrackObject((FUTrackable*) ptr);
00130         ptr = NULL;
00131     }
00132 
00136     FUTrackedPtr& operator=(ObjectClass* _ptr)
00137     {
00138         if (ptr != NULL) FUTracker::UntrackObject((FUTrackable*) ptr);
00139         ptr = _ptr;
00140         if (ptr != NULL) FUTracker::TrackObject((FUTrackable*) ptr);
00141         return *this;
00142     }
00143     inline FUTrackedPtr& operator=(const FUTrackedPtr& _ptr) { return operator=(_ptr.ptr); } 
00147     virtual bool TracksObject(const FUTrackable* object) const { return (FUTrackable*) ptr == object; }
00148 
00151     inline ObjectClass& operator*() { FUAssert(ptr != NULL, return *ptr); return *ptr; }
00152     inline const ObjectClass& operator*() const { FUAssert(ptr != NULL, return *ptr); return *ptr; } 
00153     inline ObjectClass* operator->() { return ptr; } 
00154     inline const ObjectClass* operator->() const { return ptr; } 
00155     inline operator ObjectClass*() { return ptr; } 
00156     inline operator const ObjectClass*() const { return ptr; } 
00158 protected:
00162     virtual void OnObjectReleased(FUTrackable* object)
00163     {
00164         FUAssert(TracksObject(object), return);
00165         ptr = NULL;
00166     }
00167 };
00168 
00176 template <class ObjectClass = FUTrackable>
00177 class FUTrackedList : private fm::pvector<ObjectClass>, FUTracker
00178 {
00179 public:
00180     typedef fm::pvector<ObjectClass> Parent;
00181     typedef ObjectClass* item;
00182     typedef const ObjectClass* const_item;
00183     typedef item* iterator;
00184     typedef const_item* const_iterator;
00185 
00187     virtual ~FUTrackedList() { clear(); }
00188 
00190     void clear()
00191     {
00192         for (iterator it = begin(); it != end(); ++it)
00193         {
00194             FUTracker::UntrackObject((FUTrackable*) (*it));
00195         }
00196         Parent::clear();
00197     }
00198     
00201     ObjectClass*& front() { return (ObjectClass*&) Parent::front(); }
00202     const ObjectClass*& front() const { return (const ObjectClass*&) Parent::front(); } 
00206     ObjectClass*& back() { return (ObjectClass*&) Parent::back(); }
00207     const ObjectClass*& back() const { return (const ObjectClass*&) Parent::back(); } 
00212     inline ObjectClass* at(size_t index) { return (ObjectClass*) Parent::at(index); }
00213     inline const ObjectClass* at(size_t index) const { return (const ObjectClass*) Parent::at(index); } 
00214     template <class INTEGER> inline ObjectClass* operator[](INTEGER index) { return at(index); } 
00215     template <class INTEGER> inline const ObjectClass* operator[](INTEGER index) const { return at(index); } 
00219     inline iterator begin() { return (iterator) Parent::begin(); }
00220     inline const_iterator begin() const { return (const_iterator) Parent::begin(); } 
00224     inline iterator end() { return (iterator) Parent::end(); }
00225     inline const_iterator end() const { return (const_iterator) Parent::end(); } 
00231     inline iterator find(const ObjectClass* item) { return (iterator) Parent::find(item); }
00232     inline const_iterator find(const ObjectClass* item) const { return (const_iterator) Parent::find(item); } 
00236     inline void push_back(ObjectClass* object)
00237     {
00238         FUTracker::TrackObject((FUTrackable*) object);
00239         Parent::push_back(object);
00240     }
00241 
00246     iterator insert(iterator _iterator, ObjectClass* object)
00247     {
00248         FUTracker::TrackObject(object);
00249         return (iterator) Parent::insert(_iterator, object);
00250     }
00251 
00255     inline void insert(size_t index, ObjectClass* object) { insert(begin() + index, object); }
00256 
00262     template <class _It>
00263     void insert(iterator _where, _It _startIterator, _It _endIterator)
00264     {
00265         if (_startIterator < _endIterator)
00266         {
00267             size_t relativeWhere = _where - begin();
00268             size_t count = _endIterator - _startIterator;
00269             Parent::insert(Parent::begin() + relativeWhere, count);
00270             _where = begin() + relativeWhere;
00271 
00272             for (; _startIterator != _endIterator; ++_startIterator, ++_where)
00273             {
00274                 *_where = const_cast<ObjectClass*>((const ObjectClass*)(*_startIterator));
00275                 FUTracker::TrackObject(const_cast<FUTrackable*>((const FUTrackable*) (*_startIterator)));
00276             }
00277         }
00278     }
00279 
00281     void pop_back()
00282     {
00283         if (!Parent::empty())
00284         {
00285             FUTracker::UntrackObject(back());
00286             Parent::pop_back();
00287         }
00288     }
00289     
00292     iterator erase(iterator _it)
00293     {
00294         FUTracker::UntrackObject((FUTrackable*) *_it);
00295         return (iterator) Parent::erase(_it);
00296     }
00297 
00301     inline void erase(iterator first, iterator last)
00302     {
00303         for (iterator it = first; it != last; ++it) FUTracker::UntrackObject((FUTrackable*) *it);
00304         Parent::erase(first, last);
00305     }
00306 
00310     inline void erase(size_t first, size_t last) { erase(begin() + first, begin() + last); }
00311 
00315     inline bool erase(const ObjectClass* value)
00316     {
00317         iterator it = Parent::find(value);
00318         if (it != Parent::end())
00319         {
00320             FUTracker::UntrackObject((FUTrackable*) *it);
00321             Parent::erase(it);
00322             return true;
00323         }
00324         return false;
00325     }
00326 
00329     inline void erase(size_t index) { erase(begin() + index); }
00330 
00333     virtual bool TracksObject(const FUTrackable* object) const { return Parent::contains((ObjectClass*) object); }
00334 
00340     FUTrackedList<ObjectClass>& operator= (const FUTrackedList<ObjectClass>& other) { clear(); insert(end(), other.begin(), other.end()); return *this; }
00341 
00342     inline bool empty() const { return Parent::empty(); } 
00343     inline size_t size() const { return Parent::size(); } 
00344     void reserve(size_t count) { Parent::reserve(count); } 
00345     inline bool contains(const ObjectClass* value) const { return Parent::contains(value); } 
00351     inline bool release(const ObjectClass* value)
00352     {
00353         ObjectClass** it = find(value);
00354         if (it != Parent::end()) { erase(it); ((FUTrackable*) value)->Release(); return true; }
00355         return false;
00356     }
00357 
00359     void pop_front()
00360     {
00361         if (!Parent::empty())
00362         {
00363             FUTracker::UntrackObject(front());
00364             Parent::pop_front();
00365         }
00366     }
00367 
00368 protected:
00371     virtual void OnObjectReleased(FUTrackable* object)
00372     {
00373         FUAssert(TracksObject(object), return);
00374         Parent::erase((ObjectClass*) object);
00375     }
00376 };
00377 
00378 #endif // _FU_TRACKER_H_

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