diff options
| author | Richard Nelson <richard@lindenlab.com> | 2011-07-26 14:26:27 -0700 | 
|---|---|---|
| committer | Richard Nelson <richard@lindenlab.com> | 2011-07-26 14:26:27 -0700 | 
| commit | fd9f3b9fe945cb86f677f5b0cf31302d10bcfa99 (patch) | |
| tree | a16d6541e199103a069378ea3e0d695c59685719 /indra/llcommon | |
| parent | 95da8c81f3d5afd8d888589398028883e6647333 (diff) | |
EXP-1021 FIX Position of web content browser dictates position of profile panel - profile panel position changes do not persist
EXP-1030 FIX Search button toggle can get out of synch in bottom bar
made llinstancetracker::iterator do own nested level management (removing need for separate guard)
added support for filename= to floaters
can pass in arbitrary window_class to floaters
Diffstat (limited to 'indra/llcommon')
| -rw-r--r-- | indra/llcommon/lleventtimer.cpp | 20 | ||||
| -rw-r--r-- | indra/llcommon/llfasttimer_class.cpp | 29 | ||||
| -rw-r--r-- | indra/llcommon/llinstancetracker.h | 162 | 
3 files changed, 144 insertions, 67 deletions
| diff --git a/indra/llcommon/lleventtimer.cpp b/indra/llcommon/lleventtimer.cpp index 7743826c60..0d96e03da4 100644 --- a/indra/llcommon/lleventtimer.cpp +++ b/indra/llcommon/lleventtimer.cpp @@ -58,19 +58,15 @@ LLEventTimer::~LLEventTimer()  void LLEventTimer::updateClass()   {  	std::list<LLEventTimer*> completed_timers; - +	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 );  			}  		}  	} diff --git a/indra/llcommon/llfasttimer_class.cpp b/indra/llcommon/llfasttimer_class.cpp index 1dfc194d7c..b93d9935cb 100644 --- a/indra/llcommon/llfasttimer_class.cpp +++ b/indra/llcommon/llfasttimer_class.cpp @@ -219,11 +219,8 @@ LLFastTimer::DeclareTimer::DeclareTimer(const std::string& name)  // static  void LLFastTimer::DeclareTimer::updateCachedPointers()  { -	DeclareTimer::LLInstanceTrackerScopedGuard guard;  	// propagate frame state pointers to timer declarations -	for (DeclareTimer::instance_iter it = guard.beginInstances(); -		it != guard.endInstances(); -		++it) +	for (instance_iter it = beginInstances(); it != endInstances(); ++it)  	{  		// update cached pointer  		it->mFrameState = &it->mTimer.getFrameState(); @@ -395,10 +392,7 @@ void LLFastTimer::NamedTimer::buildHierarchy()  	// set up initial tree  	{ -		NamedTimer::LLInstanceTrackerScopedGuard guard; -		for (instance_iter it = guard.beginInstances(); -		     it != guard.endInstances(); -		     ++it) +		for (instance_iter it = beginInstances(); it != endInstances(); ++it)  		{  			NamedTimer& timer = *it;  			if (&timer == NamedTimerFactory::instance().getRootTimer()) continue; @@ -526,10 +520,7 @@ void LLFastTimer::NamedTimer::resetFrame()  		LLSD sd;  		{ -			NamedTimer::LLInstanceTrackerScopedGuard guard; -			for (NamedTimer::instance_iter it = guard.beginInstances(); -			     it != guard.endInstances(); -			     ++it) +			for (instance_iter it = beginInstances(); it != endInstances(); ++it)  			{  				NamedTimer& timer = *it;  				FrameState& info = timer.getFrameState(); @@ -566,7 +557,7 @@ void LLFastTimer::NamedTimer::resetFrame()  		llassert_always(timerp->mFrameStateIndex < (S32)getFrameStateList().size());  	} -	// sort timers by dfs traversal order to improve cache coherency +	// sort timers by DFS traversal order to improve cache coherency  	std::sort(getFrameStateList().begin(), getFrameStateList().end(), SortTimersDFS());  	// update pointers into framestatelist now that we've sorted it @@ -574,10 +565,7 @@ void LLFastTimer::NamedTimer::resetFrame()  	// reset for next frame  	{ -		NamedTimer::LLInstanceTrackerScopedGuard guard; -		for (NamedTimer::instance_iter it = guard.beginInstances(); -		     it != guard.endInstances(); -		     ++it) +		for (instance_iter it = beginInstances(); it != endInstances(); ++it)  		{  			NamedTimer& timer = *it; @@ -621,10 +609,7 @@ void LLFastTimer::NamedTimer::reset()  	// reset all history  	{ -		NamedTimer::LLInstanceTrackerScopedGuard guard; -		for (NamedTimer::instance_iter it = guard.beginInstances(); -		     it != guard.endInstances(); -		     ++it) +		for (instance_iter it = beginInstances(); it != endInstances(); ++it)  		{  			NamedTimer& timer = *it;  			if (&timer != NamedTimerFactory::instance().getRootTimer())  @@ -872,7 +857,7 @@ std::string LLFastTimer::sClockType = "rdtsc";  #else  //LL_COMMON_API U64 get_clock_count(); // in lltimer.cpp -// These use QueryPerformanceCounter, which is arguably fine and also works on amd architectures. +// These use QueryPerformanceCounter, which is arguably fine and also works on AMD architectures.  U32 LLFastTimer::getCPUClockCount32()  {  	return (U32)(get_clock_count()>>8); diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h index b971b2f914..cdddd0d7a0 100644 --- a/indra/llcommon/llinstancetracker.h +++ b/indra/llcommon/llinstancetracker.h @@ -52,13 +52,68 @@ 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: +		instance_iter(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.m_iterator; +		} + +		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: +		key_iter(typename InstanceMap::iterator& it) +			:	mIterator(it) +		{ +			++sIterationNestDepth; +		} + +		~key_iter() +		{ +			--sIterationNestDepth; +		} + +	private: +		friend class boost::iterator_core_access; + +		void increment() { mIterator++; } +		bool equal(instance_iter const& other) const +		{ +			return mIterator == other.m_iterator; +		} + +		KEY& dereference() const +		{ +			return mIterator->first; +		} + +		typename InstanceMap::iterator mIterator; +	};  	static T* getInstance(const KEY& k)  	{ @@ -66,42 +121,47 @@ public:  		return (found == getMap_().end()) ? NULL : found->second;  	} -	static key_iter beginKeys() -	{ -		return boost::make_transform_iterator(getMap_().begin(), -											  boost::bind(&InstanceMap::value_type::first, _1)); +	static instance_iter beginInstances()  +	{	 +		return instance_iter(getMap_().begin());   	} -	static key_iter endKeys() + +	static instance_iter endInstances()   	{ -		return boost::make_transform_iterator(getMap_().end(), -											  boost::bind(&InstanceMap::value_type::first, _1)); +		return instance_iter(getMap_().end());  	} -	static instance_iter beginInstances() + +	static S32 instanceCount() { return getMap_().size(); } + +	static key_iter beginKeys()  	{ -		return instance_iter(boost::make_transform_iterator(getMap_().begin(), -															boost::bind(&InstanceMap::value_type::second, _1))); +		return key_iter(getMap_().begin());  	} -	static instance_iter endInstances() +	static key_iter endKeys()  	{ -		return instance_iter(boost::make_transform_iterator(getMap_().end(), -															boost::bind(&InstanceMap::value_type::second, _1))); +		return key_iter(getMap_().end());  	} -	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_() @@ -116,9 +176,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> @@ -127,15 +190,52 @@ 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(); } +	class instance_iter : public boost::iterator_facade<instance_iter, T, boost::forward_traversal_tag> +	{ +	public: +		instance_iter(typename InstanceSet::iterator& it) +		:	mIterator(it) +		{ +			++sIterationNestDepth; +		} + +		instance_iter(const instance_iter& other) +		:	mIterator(other.mIterator) +		{ +			++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; +		} + +		typename InstanceSet::iterator mIterator; +	}; + +	static instance_iter beginInstances() {	return instance_iter(getSet_().begin()); } +	static instance_iter endInstances() { return instance_iter(getSet_().end()); } + +	// DEPRECATED: iterators now increment and decrement iteration depth  	// 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). @@ -154,15 +254,12 @@ public:  		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(); }  	};  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() @@ -174,7 +271,6 @@ protected:  	LLInstanceTracker(const LLInstanceTracker& other)  	{ -		//llassert(sIterationNestDepth == 0);  		getSet_().insert(static_cast<T*>(this));  	} | 
