diff options
Diffstat (limited to 'indra/llcommon')
-rw-r--r-- | indra/llcommon/llevents.cpp | 102 | ||||
-rw-r--r-- | indra/llcommon/llevents.h | 39 | ||||
-rw-r--r-- | indra/llcommon/llleaplistener.cpp | 21 |
3 files changed, 37 insertions, 125 deletions
diff --git a/indra/llcommon/llevents.cpp b/indra/llcommon/llevents.cpp index 186e710c43..d31f5f2d32 100644 --- a/indra/llcommon/llevents.cpp +++ b/indra/llcommon/llevents.cpp @@ -64,51 +64,16 @@ #endif /***************************************************************************** -* queue_names: specify LLEventPump names that should be instantiated as -* LLEventQueue -*****************************************************************************/ -/** - * At present, we recognize particular requested LLEventPump names as needing - * LLEventQueues. Later on we'll migrate this information to an external - * configuration file. - */ -const char* queue_names[] = -{ - "placeholder - replace with first real name string" -}; - -/***************************************************************************** -* If there's a "mainloop" pump, listen on that to flush all LLEventQueues +* LLEventPumps *****************************************************************************/ -struct RegisterFlush : public LLEventTrackable +LLEventPumps::PumpFactories LLEventPumps::mFactories { - RegisterFlush(): - pumps(LLEventPumps::instance()) - { - pumps.obtain("mainloop").listen("flushLLEventQueues", boost::bind(&RegisterFlush::flush, this, _1)); - } - bool flush(const LLSD&) - { - pumps.flush(); - return false; - } - ~RegisterFlush() - { - // LLEventTrackable handles stopListening for us. - } - LLEventPumps& pumps; + // LLEventStream is the default for obtain(), so even if somebody DOES + // call obtain("placeholder"), this sample entry won't break anything. + { "placeholder", [](const std::string& name) { return new LLEventStream(name); } } }; -static RegisterFlush registerFlush; -/***************************************************************************** -* LLEventPumps -*****************************************************************************/ -LLEventPumps::LLEventPumps(): - // Until we migrate this information to an external config file, - // initialize mQueueNames from the static queue_names array. - mQueueNames(boost::begin(queue_names), boost::end(queue_names)) -{ -} +LLEventPumps::LLEventPumps() {} LLEventPump& LLEventPumps::obtain(const std::string& name) { @@ -121,10 +86,10 @@ LLEventPump& LLEventPumps::obtain(const std::string& name) } // Here we must instantiate an LLEventPump subclass. LLEventPump* newInstance; - // Should this name be an LLEventQueue? - PumpNames::const_iterator nfound = mQueueNames.find(name); - if (nfound != mQueueNames.end()) - newInstance = new LLEventQueue(name); + // Do we have a predefined factory for this instance name? + PumpFactories::const_iterator nfound = mFactories.find(name); + if (nfound != mFactories.end()) + newInstance = (nfound->second)(name); else newInstance = new LLEventStream(name); // LLEventPump's constructor implicitly registers each new instance in @@ -144,14 +109,13 @@ bool LLEventPumps::post(const std::string&name, const LLSD&message) return (*found).second->post(message); } - void LLEventPumps::flush() { // Flush every known LLEventPump instance. Leave it up to each instance to // decide what to do with the flush() call. - for (PumpMap::iterator pmi = mPumpMap.begin(), pmend = mPumpMap.end(); pmi != pmend; ++pmi) + for (PumpMap::value_type& pair : mPumpMap) { - pmi->second->flush(); + pair.second->flush(); } } @@ -605,48 +569,6 @@ LLBoundListener LLEventMailDrop::listen_impl(const std::string& name, void LLEventMailDrop::discard() { mEventHistory.clear(); - LLEventStream::flush(); -} - -/***************************************************************************** -* LLEventQueue -*****************************************************************************/ -bool LLEventQueue::post(const LLSD& event) -{ - if (mEnabled) - { - // Defer sending this event by queueing it until flush() - mEventQueue.push_back(event); - } - // Unconditionally return false. We won't know until flush() whether a - // listener claims to have handled the event -- meanwhile, don't block - // other listeners. - return false; -} - -void LLEventQueue::flush() -{ - if(!mSignal) return; - - // Consider the case when a given listener on this LLEventQueue posts yet - // another event on the same queue. If we loop over mEventQueue directly, - // we'll end up processing all those events during the same flush() call - // -- rather like an EventStream. Instead, copy mEventQueue and clear it, - // so that any new events posted to this LLEventQueue during flush() will - // be processed in the *next* flush() call. - EventQueue queue(mEventQueue); - mEventQueue.clear(); - // NOTE NOTE NOTE: Any new access to member data beyond this point should - // cause us to move our LLStandardSignal object to a pimpl class along - // with said member data. Then the local shared_ptr will preserve both. - - // DEV-43463: capture a local copy of mSignal. See LLEventStream::post() - // for detailed comments. - boost::shared_ptr<LLStandardSignal> signal(mSignal); - for ( ; ! queue.empty(); queue.pop_front()) - { - (*signal)(queue.front()); - } } /***************************************************************************** diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h index ce2aa2f3c9..c55351919e 100644 --- a/indra/llcommon/llevents.h +++ b/indra/llcommon/llevents.h @@ -37,6 +37,7 @@ #include <set> #include <vector> #include <deque> +#include <functional> #if LL_WINDOWS #pragma warning (push) #pragma warning (disable : 4263) // boost::signals2::expired_slot::what() has const mismatch @@ -55,7 +56,6 @@ #include <boost/visit_each.hpp> #include <boost/ref.hpp> // reference_wrapper #include <boost/type_traits/is_pointer.hpp> -#include <boost/function.hpp> #include <boost/static_assert.hpp> #include "llsd.h" #include "llsingleton.h" @@ -303,10 +303,10 @@ testable: // destroyed. typedef std::set<LLEventPump*> PumpSet; PumpSet mOurPumps; - // LLEventPump names that should be instantiated as LLEventQueue rather - // than as LLEventStream - typedef std::set<std::string> PumpNames; - PumpNames mQueueNames; + // LLEventPump subclasses that should be instantiated for particular + // instance names + typedef std::map<std::string, std::function<LLEventPump*(const std::string&)>> PumpFactories; + static PumpFactories mFactories; }; /***************************************************************************** @@ -351,7 +351,7 @@ typedef boost::signals2::trackable LLEventTrackable; *****************************************************************************/ /** * LLEventPump is the base class interface through which we access the - * concrete subclasses LLEventStream and LLEventQueue. + * concrete subclasses such as LLEventStream. * * @NOTE * LLEventPump derives from LLEventTrackable so that when you "chain" @@ -594,11 +594,10 @@ public: * event *must* eventually reach a listener that will consume it, else the * queue will grow to arbitrary length. * - * @NOTE: When using an LLEventMailDrop (or LLEventQueue) with a LLEventTimeout or + * @NOTE: When using an LLEventMailDrop with an LLEventTimeout or * LLEventFilter attaching the filter downstream, using Timeout's constructor will * cause the MailDrop to discharge any of its stored events. The timeout should * instead be connected upstream using its listen() method. - * See llcoro::suspendUntilEventOnWithTimeout() for an example. */ class LL_COMMON_API LLEventMailDrop : public LLEventStream { @@ -623,30 +622,6 @@ private: }; /***************************************************************************** -* LLEventQueue -*****************************************************************************/ -/** - * LLEventQueue is a LLEventPump whose post() method defers calling registered - * listeners until flush() is called. - */ -class LL_COMMON_API LLEventQueue: public LLEventPump -{ -public: - LLEventQueue(const std::string& name, bool tweak=false): LLEventPump(name, tweak) {} - virtual ~LLEventQueue() {} - - /// Post an event to all listeners - virtual bool post(const LLSD& event); - - /// flush queued events - virtual void flush(); - -private: - typedef std::deque<LLSD> EventQueue; - EventQueue mEventQueue; -}; - -/***************************************************************************** * LLReqID *****************************************************************************/ /** diff --git a/indra/llcommon/llleaplistener.cpp b/indra/llcommon/llleaplistener.cpp index f50bacb1e8..0d18e5fff9 100644 --- a/indra/llcommon/llleaplistener.cpp +++ b/indra/llcommon/llleaplistener.cpp @@ -14,6 +14,8 @@ // associated header #include "llleaplistener.h" // STL headers +#include <map> +#include <functional> // std headers // external library headers #include <boost/foreach.hpp> @@ -119,6 +121,18 @@ LLLeapListener::~LLLeapListener() } } +namespace +{ + +static std::map<std::string, std::function<LLEventPump*(const std::string&)>> factories +{ + // tweak name for uniqueness + { "LLEventStream", [](const std::string& name){ return new LLEventStream(name, true); } }, + { "LLEventMailDrop", [](const std::string& name){ return new LLEventMailDrop(name, true); } } +}; + +} // anonymous namespace + void LLLeapListener::newpump(const LLSD& request) { Response reply(LLSD(), request); @@ -127,13 +141,14 @@ void LLLeapListener::newpump(const LLSD& request) LLSD const & type = request["type"]; LLEventPump * new_pump = NULL; - if (type.asString() == "LLEventQueue") + auto found = factories.find(type.asString()); + if (found != factories.end()) { - new_pump = new LLEventQueue(name, true); // tweak name for uniqueness + new_pump = (found->second)(name); } else { - if (! (type.isUndefined() || type.asString() == "LLEventStream")) + if (! type.isUndefined()) { reply.warn(STRINGIZE("unknown 'type' " << type << ", using LLEventStream")); } |