diff options
author | Nat Goodspeed <nat@lindenlab.com> | 2019-10-18 14:46:05 -0400 |
---|---|---|
committer | Nat Goodspeed <nat@lindenlab.com> | 2020-03-25 18:58:16 -0400 |
commit | 95a218fcc0d22cdf02a7c81c555b9c909e24bd40 (patch) | |
tree | be668f687ffd3d67384150ad64f6ec52b83d0798 /indra/llcommon/llevents.cpp | |
parent | 3ec92b0eded755fe9e1965c6300385effdf733cf (diff) |
DRTVWR-476: Eliminate static LLEventPump factory maps.
Having a map from std::string to a factory function returning LLEventPump* is
a cool idea, especially since you could statically populate such a map with
string literals and little lambdas.
Unfortunately, static initialization of any data is a bad idea when control
can reach consuming code before that module's static data are constructed.
Since LLEventPumps is already an LLSingleton, it's simple enough to make its
map non-static and initialize it in the constructor.
But another recent static factory-function map was introduced in
llleaplistener.cpp to support the LLLeapListener::newpump() operation. That
involves no LLSingletons.
Introduce LLEventPumps::make(name, tweak, type) to instantiate an LLEventPump
subclass of the specified type with specified (name, tweak) parameters.
Instances returned by make() are owned by LLEventPumps, as with obtain().
Introduce LLEventPumps::BadType exception for when the type string isn't
recognized.
LLEventPumps::obtain() can then simply call make() when the specified instance
name doesn't already exist. The configuration data used internally by obtain()
becomes { string instance name, string subclass name }. Although this too is
currently initialized in the LLEventPumps constructor, migrating it to a
configuration file would now be far more straightforward than before.
LLLeapListener::newpump(), too, can call LLEventPumps::make() with the
caller-specified type string. This eliminates that static factory map.
newpump() must catch BadType and report the error back to its invoker.
Given that the LLEventPump subclass instances returned by make() are owned by
LLEventPumps rather than LLLeapListener, there is no further need for the
LLLeapListener::mEventPumps ptr_map, which was used only to manage lifetime.
Also remove LLLeapListener's "killpump" operation since LLEventPumps provides
no corresponding functionality.
Diffstat (limited to 'indra/llcommon/llevents.cpp')
-rw-r--r-- | indra/llcommon/llevents.cpp | 56 |
1 files changed, 40 insertions, 16 deletions
diff --git a/indra/llcommon/llevents.cpp b/indra/llcommon/llevents.cpp index d31f5f2d32..281a1121bd 100644 --- a/indra/llcommon/llevents.cpp +++ b/indra/llcommon/llevents.cpp @@ -66,14 +66,21 @@ /***************************************************************************** * LLEventPumps *****************************************************************************/ -LLEventPumps::PumpFactories LLEventPumps::mFactories -{ - // 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); } } -}; - -LLEventPumps::LLEventPumps() {} +LLEventPumps::LLEventPumps(): + mFactories + { + { "LLEventStream", [](const std::string& name, bool tweak) + { return new LLEventStream(name, tweak); } }, + { "LLEventMailDrop", [](const std::string& name, bool tweak) + { return new LLEventMailDrop(name, tweak); } } + }, + mTypes + { + // LLEventStream is the default for obtain(), so even if somebody DOES + // call obtain("placeholder"), this sample entry won't break anything. + { "placeholder", "LLEventStream" } + } +{} LLEventPump& LLEventPumps::obtain(const std::string& name) { @@ -84,14 +91,31 @@ LLEventPump& LLEventPumps::obtain(const std::string& name) // name. return *found->second; } - // Here we must instantiate an LLEventPump subclass. - LLEventPump* newInstance; - // 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); + + // Here we must instantiate an LLEventPump subclass. Is there a + // preregistered class name override for this specific instance name? + auto nfound = mTypes.find(name); + std::string type; + if (nfound != mTypes.end()) + { + type = nfound->second; + } + // pass tweak=false: we already know there's no existing instance with + // this name + return make(name, false, type); +} + +LLEventPump& LLEventPumps::make(const std::string& name, bool tweak, + const std::string& type) +{ + // find the relevant factory for this (or default) type + auto found = mFactories.find(type.empty()? "LLEventStream" : type); + if (found == mFactories.end()) + { + // Passing an unrecognized type name is a no-no + LLTHROW(BadType(type)); + } + auto newInstance = (found->second)(name, tweak); // LLEventPump's constructor implicitly registers each new instance in // mPumpMap. But remember that we instantiated it (in mOurPumps) so we'll // delete it later. |