diff --git a/indra/newview/llcallbacklist.cpp b/indra/newview/llcallbacklist.cpp index 6063995cf..1bfd2cb9b 100644 --- a/indra/newview/llcallbacklist.cpp +++ b/indra/newview/llcallbacklist.cpp @@ -47,7 +47,7 @@ LLCallbackList gIdleCallbacks; // Member functions // -LLCallbackList::LLCallbackList() : mLoopingOverCallbackList(false) +LLCallbackList::LLCallbackList() { // nothing } @@ -96,15 +96,7 @@ BOOL LLCallbackList::deleteFunction( callback_t func, void *data) callback_list_t::iterator iter = std::find(mCallbackList.begin(), mCallbackList.end(), t); if (iter != mCallbackList.end()) { - if (mLoopingOverCallbackList) - { - iter->first = NULL; // Mark for removal later (when we return to LLCallbackList::callFunctions). - mNeedErase = true; - } - else - { - mCallbackList.erase(iter); - } + mCallbackList.erase(iter); return TRUE; } else @@ -116,39 +108,82 @@ BOOL LLCallbackList::deleteFunction( callback_t func, void *data) void LLCallbackList::deleteAllFunctions() { - llassert(!mLoopingOverCallbackList); // Only called from unit tests. mCallbackList.clear(); } void LLCallbackList::callFunctions() { - llassert(!mLoopingOverCallbackList); - mLoopingOverCallbackList = true; - mNeedErase = false; - for (callback_list_t::iterator iter = mCallbackList.begin(); iter != mCallbackList.end(); ++iter) + for (callback_list_t::iterator iter = mCallbackList.begin(); iter != mCallbackList.end(); ) { - if (iter->first) // Not pending removal? + callback_list_t::iterator curiter = iter++; + curiter->first(curiter->second); + } +} + +// Shim class to allow arbitrary boost::bind +// expressions to be run as one-time idle callbacks. +class OnIdleCallbackOneTime +{ +public: + OnIdleCallbackOneTime(nullary_func_t callable): + mCallable(callable) + { + } + static void onIdle(void *data) + { + gIdleCallbacks.deleteFunction(onIdle, data); + OnIdleCallbackOneTime* self = reinterpret_cast(data); + self->call(); + delete self; + } + void call() + { + mCallable(); + } +private: + nullary_func_t mCallable; +}; + +void doOnIdleOneTime(nullary_func_t callable) +{ + OnIdleCallbackOneTime* cb_functor = new OnIdleCallbackOneTime(callable); + gIdleCallbacks.addFunction(&OnIdleCallbackOneTime::onIdle,cb_functor); +} + +// Shim class to allow generic boost functions to be run as +// recurring idle callbacks. Callable should return true when done, +// false to continue getting called. +class OnIdleCallbackRepeating +{ +public: + OnIdleCallbackRepeating(bool_func_t callable): + mCallable(callable) + { + } + // Will keep getting called until the callable returns true. + static void onIdle(void *data) + { + OnIdleCallbackRepeating* self = reinterpret_cast(data); + bool done = self->call(); + if (done) { - iter->first(iter->second); // This can theorectically set any iter->first to NULL, which means the entry should be erased. + gIdleCallbacks.deleteFunction(onIdle, data); + delete self; } } - mLoopingOverCallbackList = false; - if (mNeedErase) + bool call() { - callback_list_t::iterator iter = mCallbackList.begin(); - while (iter != mCallbackList.end()) - { - if (!iter->first) - { - iter = mCallbackList.erase(iter); - } - else - { - ++iter; - } - } + return mCallable(); } +private: + bool_func_t mCallable; +}; + +void doOnIdleRepeating(bool_func_t callable) +{ + OnIdleCallbackRepeating* cb_functor = new OnIdleCallbackRepeating(callable); + gIdleCallbacks.addFunction(&OnIdleCallbackRepeating::onIdle,cb_functor); } #ifdef _DEBUG diff --git a/indra/newview/llcallbacklist.h b/indra/newview/llcallbacklist.h index 240346478..1819f865a 100644 --- a/indra/newview/llcallbacklist.h +++ b/indra/newview/llcallbacklist.h @@ -34,6 +34,7 @@ #define LL_LLCALLBACKLIST_H #include "llstl.h" +#include class LLCallbackList { @@ -53,13 +54,20 @@ public: protected: // Use a list so that the callbacks are ordered in case that matters - typedef std::pair callback_pair_t; // callback_t is a (function) pointer. If it is NULL it means that the entry should be considered deleted. + typedef std::pair callback_pair_t; typedef std::list callback_list_t; callback_list_t mCallbackList; - bool mLoopingOverCallbackList; // True while looping over mCallbackList and calling the callback_t functions (see callFunctions). - bool mNeedErase; // True when deleteFunction was called while mLoopingOverCallbackList was true. }; +typedef boost::function nullary_func_t; +typedef boost::function bool_func_t; + +// Call a given callable once in idle loop. +void doOnIdleOneTime(nullary_func_t callable); + +// Repeatedly call a callable in idle loop until it returns true. +void doOnIdleRepeating(bool_func_t callable); + extern LLCallbackList gIdleCallbacks; #endif diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index 2bd383487..aa61e3640 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -17,6 +17,7 @@ #include "llviewerprecompiledheaders.h" #include "llfloateravatarlist.h" #include "llavatarnamecache.h" +#include "llcallbacklist.h" #include "llfloaterbeacons.h" #include "llfloaterchat.h" #include "llfloaterdaycycle.h" diff --git a/indra/newview/rlvinventory.cpp b/indra/newview/rlvinventory.cpp index fc7b503a1..971140224 100644 --- a/indra/newview/rlvinventory.cpp +++ b/indra/newview/rlvinventory.cpp @@ -16,6 +16,7 @@ #include "llviewerprecompiledheaders.h" #include "llagent.h" +#include "llcallbacklist.h" #include "llstartup.h" #include "llviewerobject.h" #include "llvoavatar.h" diff --git a/indra/newview/rlvviewer2.cpp b/indra/newview/rlvviewer2.cpp index 28caf788d..a90f93c80 100644 --- a/indra/newview/rlvviewer2.cpp +++ b/indra/newview/rlvviewer2.cpp @@ -26,78 +26,6 @@ #include "llviewerinventory.h" #include "rlvviewer2.h" -// ============================================================================ -// From llappearancemgr.cpp - -// Shim class to allow arbitrary boost::bind -// expressions to be run as one-time idle callbacks. -// -// TODO: rework idle function spec to take a boost::function in the first place. -class OnIdleCallbackOneTime -{ -public: - OnIdleCallbackOneTime(nullary_func_t callable): - mCallable(callable) - { - } - static void onIdle(void *data) - { - gIdleCallbacks.deleteFunction(onIdle, data); - OnIdleCallbackOneTime* self = reinterpret_cast(data); - self->call(); - delete self; - } - void call() - { - mCallable(); - } -private: - nullary_func_t mCallable; -}; - -void doOnIdleOneTime(nullary_func_t callable) -{ - OnIdleCallbackOneTime* cb_functor = new OnIdleCallbackOneTime(callable); - gIdleCallbacks.addFunction(&OnIdleCallbackOneTime::onIdle,cb_functor); -} - -// Shim class to allow generic boost functions to be run as -// recurring idle callbacks. Callable should return true when done, -// false to continue getting called. -// -// TODO: rework idle function spec to take a boost::function in the first place. -class OnIdleCallbackRepeating -{ -public: - OnIdleCallbackRepeating(bool_func_t callable): - mCallable(callable) - { - } - // Will keep getting called until the callable returns true. - static void onIdle(void *data) - { - OnIdleCallbackRepeating* self = reinterpret_cast(data); - bool done = self->call(); - if (done) - { - gIdleCallbacks.deleteFunction(onIdle, data); - delete self; - } - } - bool call() - { - return mCallable(); - } -private: - bool_func_t mCallable; -}; - -void doOnIdleRepeating(bool_func_t callable) -{ - OnIdleCallbackRepeating* cb_functor = new OnIdleCallbackRepeating(callable); - gIdleCallbacks.addFunction(&OnIdleCallbackRepeating::onIdle,cb_functor); -} - // ============================================================================ // From llinventoryobserver.cpp diff --git a/indra/newview/rlvviewer2.h b/indra/newview/rlvviewer2.h index 41892f8b7..28075031e 100644 --- a/indra/newview/rlvviewer2.h +++ b/indra/newview/rlvviewer2.h @@ -29,18 +29,6 @@ #include "boost/function.hpp" -// ============================================================================ -// From llappearancemgr.h - -typedef boost::function nullary_func_t; -typedef boost::function bool_func_t; - -// Call a given callable once in idle loop. -void doOnIdleOneTime(nullary_func_t callable); - -// Repeatedly call a callable in idle loop until it returns true. -void doOnIdleRepeating(bool_func_t callable); - // ============================================================================ // From llinventoryobserver.h