Instancetracker update. LLInstanceTrackerScopedGuard was deprecated, now removed.

This commit is contained in:
Shyotl
2011-08-18 00:23:59 -05:00
parent ca99f5d2e5
commit ecce8ad23a
4 changed files with 142 additions and 84 deletions

View File

@@ -44,59 +44,36 @@
// //
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
//std::list<LLEventTimer*> LLEventTimer::sActiveList;
LLEventTimer::LLEventTimer(F32 period) LLEventTimer::LLEventTimer(F32 period)
: mEventTimer() : mEventTimer()
{ {
mPeriod = period; mPeriod = period;
//sActiveList.push_back(this);
} }
LLEventTimer::LLEventTimer(const LLDate& time) LLEventTimer::LLEventTimer(const LLDate& time)
: mEventTimer() : mEventTimer()
{ {
mPeriod = (F32)(time.secondsSinceEpoch() - LLDate::now().secondsSinceEpoch()); mPeriod = (F32)(time.secondsSinceEpoch() - LLDate::now().secondsSinceEpoch());
//sActiveList.push_back(this);
} }
LLEventTimer::~LLEventTimer() LLEventTimer::~LLEventTimer()
{ {
//sActiveList.remove(this);
} }
//static //static
void LLEventTimer::updateClass() void LLEventTimer::updateClass()
{ {
std::list<LLEventTimer*> completed_timers; std::list<LLEventTimer*> completed_timers;
for (instance_iter iter = beginInstances(); iter != endInstances(); )
/*{
for (std::list<LLEventTimer*>::iterator iter = sActiveList.begin(); iter != sActiveList.end(); )
{
LLEventTimer* timer = *iter++;
F32 et = timer->mEventTimer.getElapsedTimeF32();
if (timer->mEventTimer.getStarted() && et > timer->mPeriod) {
timer->mEventTimer.reset();
if ( timer->tick() )
{
completed_timers.push_back( timer );
}
}
}
}*/
{ {
LLInstanceTrackerScopedGuard guard; LLEventTimer& timer = *iter++;
for (instance_iter iter = guard.beginInstances(); iter != guard.endInstances(); ) F32 et = timer.mEventTimer.getElapsedTimeF32();
{ if (timer.mEventTimer.getStarted() && et > timer.mPeriod) {
LLEventTimer& timer = *iter++; timer.mEventTimer.reset();
F32 et = timer.mEventTimer.getElapsedTimeF32(); if ( timer.tick() )
if (timer.mEventTimer.getStarted() && et > timer.mPeriod) { {
timer.mEventTimer.reset(); completed_timers.push_back( &timer );
if ( timer.tick() )
{
completed_timers.push_back( &timer );
}
} }
} }
} }

View File

@@ -56,11 +56,6 @@ public:
protected: protected:
LLTimer mEventTimer; LLTimer mEventTimer;
F32 mPeriod; F32 mPeriod;
//private:
//list of active timers
// static std::list<LLEventTimer*> sActiveList; // TODO should this be a vector
}; };
#endif //LL_EVENTTIMER_H #endif //LL_EVENTTIMER_H

View File

@@ -49,6 +49,7 @@ class LL_COMMON_API LLInstanceTrackerBase : public boost::noncopyable
protected: protected:
static void * & getInstances(std::type_info const & info); static void * & getInstances(std::type_info const & info);
}; };
/// This mix-in class adds support for tracking all instances of the specified class parameter T /// This mix-in class adds support for tracking all instances of the specified class parameter T
/// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup /// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup
/// If KEY is not provided, then instances are stored in a simple set /// If KEY is not provided, then instances are stored in a simple set
@@ -58,13 +59,80 @@ class LLInstanceTracker : public LLInstanceTrackerBase
{ {
typedef typename std::map<KEY, T*> InstanceMap; typedef typename std::map<KEY, T*> InstanceMap;
typedef LLInstanceTracker<T, KEY> MyT; typedef LLInstanceTracker<T, KEY> MyT;
typedef boost::function<const KEY&(typename InstanceMap::value_type&)> KeyGetter;
typedef boost::function<T*(typename InstanceMap::value_type&)> InstancePtrGetter;
public: public:
/// Dereferencing key_iter gives you a const KEY& class instance_iter : public boost::iterator_facade<instance_iter, T, boost::forward_traversal_tag>
typedef boost::transform_iterator<KeyGetter, typename InstanceMap::iterator> key_iter; {
/// Dereferencing instance_iter gives you a T& public:
typedef boost::indirect_iterator< boost::transform_iterator<InstancePtrGetter, typename InstanceMap::iterator> > instance_iter; typedef boost::iterator_facade<instance_iter, T, boost::forward_traversal_tag> super_t;
instance_iter(const typename InstanceMap::iterator& it)
: mIterator(it)
{
++sIterationNestDepth;
}
~instance_iter()
{
--sIterationNestDepth;
}
private:
friend class boost::iterator_core_access;
void increment() { mIterator++; }
bool equal(instance_iter const& other) const
{
return mIterator == other.mIterator;
}
T& dereference() const
{
return *(mIterator->second);
}
typename InstanceMap::iterator mIterator;
};
class key_iter : public boost::iterator_facade<key_iter, KEY, boost::forward_traversal_tag>
{
public:
typedef boost::iterator_facade<key_iter, KEY, boost::forward_traversal_tag> super_t;
key_iter(typename InstanceMap::iterator& it)
: mIterator(it)
{
++sIterationNestDepth;
}
key_iter(const key_iter& other)
: mIterator(other.mIterator)
{
++sIterationNestDepth;
}
~key_iter()
{
--sIterationNestDepth;
}
private:
friend class boost::iterator_core_access;
void increment() { mIterator++; }
bool equal(key_iter const& other) const
{
return mIterator == other.mIterator;
}
KEY& dereference() const
{
return const_cast<KEY&>(mIterator->first);
}
typename InstanceMap::iterator mIterator;
};
static T* getInstance(const KEY& k) static T* getInstance(const KEY& k)
{ {
@@ -72,42 +140,47 @@ public:
return (found == getMap_().end()) ? NULL : found->second; return (found == getMap_().end()) ? NULL : found->second;
} }
static instance_iter beginInstances()
{
return instance_iter(getMap_().begin());
}
static instance_iter endInstances()
{
return instance_iter(getMap_().end());
}
static S32 instanceCount() { return getMap_().size(); }
static key_iter beginKeys() static key_iter beginKeys()
{ {
return boost::make_transform_iterator(getMap_().begin(), return key_iter(getMap_().begin());
boost::bind(&InstanceMap::value_type::first, _1));
} }
static key_iter endKeys() static key_iter endKeys()
{ {
return boost::make_transform_iterator(getMap_().end(), return key_iter(getMap_().end());
boost::bind(&InstanceMap::value_type::first, _1));
} }
static instance_iter beginInstances()
{
return instance_iter(boost::make_transform_iterator(getMap_().begin(),
boost::bind(&InstanceMap::value_type::second, _1)));
}
static instance_iter endInstances()
{
return instance_iter(boost::make_transform_iterator(getMap_().end(),
boost::bind(&InstanceMap::value_type::second, _1)));
}
static S32 instanceCount() { return getMap_().size(); }
protected: protected:
LLInstanceTracker(KEY key) { add_(key); } LLInstanceTracker(KEY key) { add_(key); }
virtual ~LLInstanceTracker() { remove_(); } virtual ~LLInstanceTracker()
{
// it's unsafe to delete instances of this type while all instances are being iterated over.
llassert(sIterationNestDepth == 0);
remove_();
}
virtual void setKey(KEY key) { remove_(); add_(key); } virtual void setKey(KEY key) { remove_(); add_(key); }
virtual const KEY& getKey() const { return mKey; } virtual const KEY& getKey() const { return mInstanceKey; }
private: private:
void add_(KEY key) void add_(KEY key)
{ {
mKey = key; mInstanceKey = key;
getMap_()[key] = static_cast<T*>(this); getMap_()[key] = static_cast<T*>(this);
} }
void remove_() void remove_()
{ {
getMap_().erase(mKey); getMap_().erase(mInstanceKey);
} }
static InstanceMap& getMap_() static InstanceMap& getMap_()
@@ -122,9 +195,12 @@ private:
private: private:
KEY mKey; KEY mInstanceKey;
static S32 sIterationNestDepth;
}; };
template <typename T, typename KEY> S32 LLInstanceTracker<T, KEY>::sIterationNestDepth = 0;
/// explicit specialization for default case where KEY is T* /// explicit specialization for default case where KEY is T*
/// use a simple std::set<T*> /// use a simple std::set<T*>
template<typename T> template<typename T>
@@ -133,42 +209,55 @@ class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase
typedef typename std::set<T*> InstanceSet; typedef typename std::set<T*> InstanceSet;
typedef LLInstanceTracker<T, T*> MyT; typedef LLInstanceTracker<T, T*> MyT;
public: public:
/// Dereferencing key_iter gives you a T* (since T* is the key)
typedef typename InstanceSet::iterator key_iter;
/// Dereferencing instance_iter gives you a T&
typedef boost::indirect_iterator<key_iter> instance_iter;
/// for completeness of analogy with the generic implementation /// for completeness of analogy with the generic implementation
static T* getInstance(T* k) { return k; } static T* getInstance(T* k) { return k; }
static S32 instanceCount() { return getSet_().size(); } static S32 instanceCount() { return getSet_().size(); }
// Instantiate this to get access to iterators for this type. It's a 'guard' in the sense class instance_iter : public boost::iterator_facade<instance_iter, T, boost::forward_traversal_tag>
// that it treats deletes of this type as errors as long as there is an instance of
// this class alive in scope somewhere (i.e. deleting while iterating is bad).
class LLInstanceTrackerScopedGuard
{ {
public: public:
LLInstanceTrackerScopedGuard() instance_iter(const typename InstanceSet::iterator& it)
: mIterator(it)
{ {
++sIterationNestDepth; ++sIterationNestDepth;
} }
~LLInstanceTrackerScopedGuard() instance_iter(const instance_iter& other)
: mIterator(other.mIterator)
{
++sIterationNestDepth;
}
~instance_iter()
{ {
--sIterationNestDepth; --sIterationNestDepth;
} }
static instance_iter beginInstances() { return instance_iter(getSet_().begin()); } private:
static instance_iter endInstances() { return instance_iter(getSet_().end()); } friend class boost::iterator_core_access;
static key_iter beginKeys() { return getSet_().begin(); }
static key_iter endKeys() { return getSet_().end(); } void increment() { mIterator++; }
bool equal(instance_iter const& other) const
{
return mIterator == other.mIterator;
}
T& dereference() const
{
return **mIterator;
}
typename InstanceSet::iterator mIterator;
}; };
static instance_iter beginInstances() { return instance_iter(getSet_().begin()); }
static instance_iter endInstances() { return instance_iter(getSet_().end()); }
protected: protected:
LLInstanceTracker() LLInstanceTracker()
{ {
// it's safe but unpredictable to create instances of this type while all instances are being iterated over. I hate unpredictable. This assert will probably be turned on early in the next development cycle. // it's safe but unpredictable to create instances of this type while all instances are being iterated over. I hate unpredictable. This assert will probably be turned on early in the next development cycle.
//llassert(sIterationNestDepth == 0);
getSet_().insert(static_cast<T*>(this)); getSet_().insert(static_cast<T*>(this));
} }
virtual ~LLInstanceTracker() virtual ~LLInstanceTracker()
@@ -180,7 +269,6 @@ protected:
LLInstanceTracker(const LLInstanceTracker& other) LLInstanceTracker(const LLInstanceTracker& other)
{ {
//llassert(sIterationNestDepth == 0);
getSet_().insert(static_cast<T*>(this)); getSet_().insert(static_cast<T*>(this));
} }

View File

@@ -2011,8 +2011,7 @@ void LLGLNamePool::release(GLuint name)
//static //static
void LLGLNamePool::upkeepPools() void LLGLNamePool::upkeepPools()
{ {
tracker_t::LLInstanceTrackerScopedGuard guard; for (tracker_t::instance_iter iter = beginInstances(); iter != endInstances(); ++iter)
for (tracker_t::instance_iter iter = guard.beginInstances(); iter != guard.endInstances(); ++iter)
{ {
LLGLNamePool & pool = *iter; LLGLNamePool & pool = *iter;
pool.upkeep(); pool.upkeep();
@@ -2022,8 +2021,7 @@ void LLGLNamePool::upkeepPools()
//static //static
void LLGLNamePool::cleanupPools() void LLGLNamePool::cleanupPools()
{ {
tracker_t::LLInstanceTrackerScopedGuard guard; for (tracker_t::instance_iter iter = beginInstances(); iter != endInstances(); ++iter)
for (tracker_t::instance_iter iter = guard.beginInstances(); iter != guard.endInstances(); ++iter)
{ {
LLGLNamePool & pool = *iter; LLGLNamePool & pool = *iter;
pool.cleanup(); pool.cleanup();