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,63 +44,40 @@
//
//////////////////////////////////////////////////////////////////////////////
//std::list<LLEventTimer*> LLEventTimer::sActiveList;
LLEventTimer::LLEventTimer(F32 period)
: mEventTimer()
{
mPeriod = period;
//sActiveList.push_back(this);
}
LLEventTimer::LLEventTimer(const LLDate& time)
: mEventTimer()
{
mPeriod = (F32)(time.secondsSinceEpoch() - LLDate::now().secondsSinceEpoch());
//sActiveList.push_back(this);
}
LLEventTimer::~LLEventTimer()
LLEventTimer::~LLEventTimer()
{
//sActiveList.remove(this);
}
//static
void LLEventTimer::updateClass()
{
std::list<LLEventTimer*> completed_timers;
/*{
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 );
}
}
}
}*/
for (instance_iter iter = beginInstances(); iter != endInstances(); )
{
LLInstanceTrackerScopedGuard guard;
for (instance_iter iter = guard.beginInstances(); iter != guard.endInstances(); )
{
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 );
}
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 );
}
}
}
if ( completed_timers.size() > 0 )
{
for (std::list<LLEventTimer*>::iterator completed_iter = completed_timers.begin();

View File

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

View File

@@ -49,6 +49,7 @@ class LL_COMMON_API LLInstanceTrackerBase : public boost::noncopyable
protected:
static void * & getInstances(std::type_info const & info);
};
/// 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
/// 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 LLInstanceTracker<T, KEY> MyT;
typedef boost::function<const KEY&(typename InstanceMap::value_type&)> KeyGetter;
typedef boost::function<T*(typename InstanceMap::value_type&)> InstancePtrGetter;
public:
/// Dereferencing key_iter gives you a const KEY&
typedef boost::transform_iterator<KeyGetter, typename InstanceMap::iterator> key_iter;
/// Dereferencing instance_iter gives you a T&
typedef boost::indirect_iterator< boost::transform_iterator<InstancePtrGetter, typename InstanceMap::iterator> > instance_iter;
class instance_iter : public boost::iterator_facade<instance_iter, T, boost::forward_traversal_tag>
{
public:
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)
{
@@ -72,42 +140,47 @@ public:
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()
{
return boost::make_transform_iterator(getMap_().begin(),
boost::bind(&InstanceMap::value_type::first, _1));
return key_iter(getMap_().begin());
}
static key_iter endKeys()
{
return boost::make_transform_iterator(getMap_().end(),
boost::bind(&InstanceMap::value_type::first, _1));
return key_iter(getMap_().end());
}
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:
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 const KEY& getKey() const { return mKey; }
virtual const KEY& getKey() const { return mInstanceKey; }
private:
void add_(KEY key)
{
mKey = key;
mInstanceKey = key;
getMap_()[key] = static_cast<T*>(this);
}
void remove_()
{
getMap_().erase(mKey);
getMap_().erase(mInstanceKey);
}
static InstanceMap& getMap_()
@@ -122,9 +195,12 @@ 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*
/// use a simple std::set<T*>
template<typename T>
@@ -133,42 +209,55 @@ class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase
typedef typename std::set<T*> InstanceSet;
typedef LLInstanceTracker<T, T*> MyT;
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
static T* getInstance(T* k) { return k; }
static S32 instanceCount() { return getSet_().size(); }
// Instantiate this to get access to iterators for this type. It's a 'guard' in the sense
// 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
class instance_iter : public boost::iterator_facade<instance_iter, T, boost::forward_traversal_tag>
{
public:
LLInstanceTrackerScopedGuard()
instance_iter(const typename InstanceSet::iterator& it)
: mIterator(it)
{
++sIterationNestDepth;
}
~LLInstanceTrackerScopedGuard()
instance_iter(const instance_iter& other)
: mIterator(other.mIterator)
{
++sIterationNestDepth;
}
~instance_iter()
{
--sIterationNestDepth;
}
static instance_iter beginInstances() { return instance_iter(getSet_().begin()); }
static instance_iter endInstances() { return instance_iter(getSet_().end()); }
static key_iter beginKeys() { return getSet_().begin(); }
static key_iter endKeys() { return getSet_().end(); }
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;
}
typename InstanceSet::iterator mIterator;
};
static instance_iter beginInstances() { return instance_iter(getSet_().begin()); }
static instance_iter endInstances() { return instance_iter(getSet_().end()); }
protected:
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.
//llassert(sIterationNestDepth == 0);
getSet_().insert(static_cast<T*>(this));
}
virtual ~LLInstanceTracker()
@@ -180,7 +269,6 @@ protected:
LLInstanceTracker(const LLInstanceTracker& other)
{
//llassert(sIterationNestDepth == 0);
getSet_().insert(static_cast<T*>(this));
}

View File

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