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

- File List
- File Members

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