summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llcommon/llevents.cpp56
-rw-r--r--indra/llcommon/llevents.h55
-rw-r--r--indra/llcommon/llleaplistener.cpp61
-rw-r--r--indra/llcommon/llleaplistener.h5
4 files changed, 95 insertions, 82 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.
diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h
index c55351919e..e380c108f4 100644
--- a/indra/llcommon/llevents.h
+++ b/indra/llcommon/llevents.h
@@ -211,8 +211,7 @@ public:
/// exception if you try to call when empty
struct Empty: public LLException
{
- Empty(const std::string& what):
- LLException(std::string("LLListenerOrPumpName::Empty: ") + what) {}
+ Empty(const std::string& what): LLException("LLListenerOrPumpName::Empty: " + what) {}
};
private:
@@ -247,6 +246,30 @@ public:
*/
LLEventPump& obtain(const std::string& name);
+ /// exception potentially thrown by make()
+ struct BadType: public LLException
+ {
+ BadType(const std::string& what): LLException("BadType: " + what) {}
+ };
+
+ /**
+ * Create an LLEventPump with suggested name (optionally of specified
+ * LLEventPump subclass type). As with obtain(), LLEventPumps owns the new
+ * instance.
+ *
+ * As with LLEventPump's constructor, make() could throw
+ * LLEventPump::DupPumpName unless you pass tweak=true.
+ *
+ * As with a hand-constructed LLEventPump subclass, if you pass
+ * tweak=true, the tweaked name can be obtained by LLEventPump::getName().
+ *
+ * Pass empty type to get the default LLEventStream.
+ *
+ * If you pass an unrecognized type string, make() throws BadType.
+ */
+ LLEventPump& make(const std::string& name, bool tweak=false,
+ const std::string& type=std::string());
+
/**
* Find the named LLEventPump instance. If it exists post the message to it.
* If the pump does not exist, do nothing.
@@ -303,10 +326,19 @@ testable:
// destroyed.
typedef std::set<LLEventPump*> PumpSet;
PumpSet mOurPumps;
- // 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;
+ // for make(), map string type name to LLEventPump subclass factory function
+ typedef std::map<std::string, std::function<LLEventPump*(const std::string&, bool)>> PumpFactories;
+ // Data used by make().
+ // One might think mFactories and mTypes could reasonably be static. So
+ // they could -- if not for the fact that make() or obtain() might be
+ // called before this module's static variables have been initialized.
+ // This is why we use singletons in the first place.
+ PumpFactories mFactories;
+
+ // for obtain(), map desired string instance name to string type when
+ // obtain() must create the instance
+ typedef std::map<std::string, std::string> InstanceTypes;
+ InstanceTypes mTypes;
};
/*****************************************************************************
@@ -372,8 +404,7 @@ public:
*/
struct DupPumpName: public LLException
{
- DupPumpName(const std::string& what):
- LLException(std::string("DupPumpName: ") + what) {}
+ DupPumpName(const std::string& what): LLException("DupPumpName: " + what) {}
};
/**
@@ -409,9 +440,7 @@ public:
*/
struct DupListenerName: public ListenError
{
- DupListenerName(const std::string& what):
- ListenError(std::string("DupListenerName: ") + what)
- {}
+ DupListenerName(const std::string& what): ListenError("DupListenerName: " + what) {}
};
/**
* exception thrown by listen(). The order dependencies specified for your
@@ -423,7 +452,7 @@ public:
*/
struct Cycle: public ListenError
{
- Cycle(const std::string& what): ListenError(std::string("Cycle: ") + what) {}
+ Cycle(const std::string& what): ListenError("Cycle: " + what) {}
};
/**
* exception thrown by listen(). This one means that your new listener
@@ -444,7 +473,7 @@ public:
*/
struct OrderChange: public ListenError
{
- OrderChange(const std::string& what): ListenError(std::string("OrderChange: ") + what) {}
+ OrderChange(const std::string& what): ListenError("OrderChange: " + what) {}
};
/// used by listen()
diff --git a/indra/llcommon/llleaplistener.cpp b/indra/llcommon/llleaplistener.cpp
index 0d18e5fff9..3e6ce9092c 100644
--- a/indra/llcommon/llleaplistener.cpp
+++ b/indra/llcommon/llleaplistener.cpp
@@ -62,16 +62,11 @@ LLLeapListener::LLLeapListener(const ConnectFunc& connect):
LLSD need_name(LLSDMap("name", LLSD()));
add("newpump",
"Instantiate a new LLEventPump named like [\"name\"] and listen to it.\n"
- "If [\"type\"] == \"LLEventQueue\", make LLEventQueue, else LLEventStream.\n"
+ "[\"type\"] == \"LLEventStream\", \"LLEventMailDrop\" et al.\n"
"Events sent through new LLEventPump will be decorated with [\"pump\"]=name.\n"
"Returns actual name in [\"name\"] (may be different if collision).",
&LLLeapListener::newpump,
need_name);
- add("killpump",
- "Delete LLEventPump [\"name\"] created by \"newpump\".\n"
- "Returns [\"status\"] boolean indicating whether such a pump existed.",
- &LLLeapListener::killpump,
- need_name);
LLSD need_source_listener(LLSDMap("source", LLSD())("listener", LLSD()));
add("listen",
"Listen to an existing LLEventPump named [\"source\"], with listener name\n"
@@ -121,58 +116,28 @@ 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);
std::string name = request["name"];
- LLSD const & type = request["type"];
+ std::string type = request["type"];
- LLEventPump * new_pump = NULL;
- auto found = factories.find(type.asString());
- if (found != factories.end())
+ try
{
- new_pump = (found->second)(name);
+ // tweak name for uniqueness
+ LLEventPump& new_pump(LLEventPumps::instance().make(name, true, type));
+ name = new_pump.getName();
+ reply["name"] = name;
+
+ // Now listen on this new pump with our plugin listener
+ std::string myname("llleap");
+ saveListener(name, myname, mConnect(new_pump, myname));
}
- else
+ catch (const LLEventPumps::BadType& error)
{
- if (! type.isUndefined())
- {
- reply.warn(STRINGIZE("unknown 'type' " << type << ", using LLEventStream"));
- }
- new_pump = new LLEventStream(name, true); // tweak name for uniqueness
+ reply.error(error.what());
}
-
- name = new_pump->getName();
-
- mEventPumps.insert(name, new_pump);
-
- // Now listen on this new pump with our plugin listener
- std::string myname("llleap");
- saveListener(name, myname, mConnect(*new_pump, myname));
-
- reply["name"] = name;
-}
-
-void LLLeapListener::killpump(const LLSD& request)
-{
- Response reply(LLSD(), request);
-
- std::string name = request["name"];
- // success == (nonzero number of entries were erased)
- reply["status"] = bool(mEventPumps.erase(name));
}
void LLLeapListener::listen(const LLSD& request)
diff --git a/indra/llcommon/llleaplistener.h b/indra/llcommon/llleaplistener.h
index 2193d81b9e..0ca5893657 100644
--- a/indra/llcommon/llleaplistener.h
+++ b/indra/llcommon/llleaplistener.h
@@ -40,7 +40,6 @@ public:
private:
void newpump(const LLSD&);
- void killpump(const LLSD&);
void listen(const LLSD&);
void stoplistening(const LLSD&);
void ping(const LLSD&) const;
@@ -64,10 +63,6 @@ private:
// and listener name.
typedef std::map<std::pair<std::string, std::string>, LLBoundListener> ListenersMap;
ListenersMap mListeners;
- // Similar lifespan reasoning applies to LLEventPumps instantiated by
- // newpump() operations.
- typedef boost::ptr_map<std::string, LLEventPump> EventPumpsMap;
- EventPumpsMap mEventPumps;
};
#endif /* ! defined(LL_LLLEAPLISTENER_H) */