Pulled idle callback functions out of rlvviewer2 and moved them into llcallbacklist where they belong. LLCallbackList brought up to current, as well.

This commit is contained in:
Shyotl
2011-10-10 00:02:12 -05:00
parent c99aabf17c
commit fc3ba78aed
6 changed files with 79 additions and 118 deletions

View File

@@ -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<OnIdleCallbackOneTime*>(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<OnIdleCallbackRepeating*>(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

View File

@@ -34,6 +34,7 @@
#define LL_LLCALLBACKLIST_H
#include "llstl.h"
#include <boost/function.hpp>
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_t,void*> 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_t,void*> callback_pair_t;
typedef std::list<callback_pair_t > 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<void ()> nullary_func_t;
typedef boost::function<bool ()> 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

View File

@@ -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"

View File

@@ -16,6 +16,7 @@
#include "llviewerprecompiledheaders.h"
#include "llagent.h"
#include "llcallbacklist.h"
#include "llstartup.h"
#include "llviewerobject.h"
#include "llvoavatar.h"

View File

@@ -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<OnIdleCallbackOneTime*>(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<OnIdleCallbackRepeating*>(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

View File

@@ -29,18 +29,6 @@
#include "boost/function.hpp"
// ============================================================================
// From llappearancemgr.h
typedef boost::function<void ()> nullary_func_t;
typedef boost::function<bool ()> 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