summaryrefslogtreecommitdiff
path: root/indra/llcommon/lleventdispatcher.h
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2023-01-24 13:41:02 -0500
committerNat Goodspeed <nat@lindenlab.com>2023-07-13 12:49:39 -0400
commit25ee39dcbe7277552d8eee1ef5ad5c367f5763f9 (patch)
tree2e5b0bd233ce8e5d7cf1c3d492dd0ebdf7b915e0 /indra/llcommon/lleventdispatcher.h
parentd2738b60e2dfa255e504247f2b5009bc1dc24954 (diff)
DRTVWR-558: Fix LLEventDispatcher::addMethod() for LazyEventAPI.
addMethod() was using dynamic_cast<target class*>(this) and testing for nullptr to decide whether the class owning the passed method is, or is not, a subclass of LLEventDispatcher. The trouble is that it doesn't work for the deferred add() calls queued by LazyEventAPI: the dynamic_cast was always returning nullptr. static_cast works better, but that leaves us with the problem we were trying to solve with dynamic_cast: what if the target class really isn't a subclass? Use std::is_base_of to pick which of two addMethod() overloads to invoke, one of which calls addFail(). (cherry picked from commit a4d520aa5d023d80cfeec4f40c3464b54cbcfc5b)
Diffstat (limited to 'indra/llcommon/lleventdispatcher.h')
-rw-r--r--indra/llcommon/lleventdispatcher.h51
1 files changed, 32 insertions, 19 deletions
diff --git a/indra/llcommon/lleventdispatcher.h b/indra/llcommon/lleventdispatcher.h
index 4ca8a7c735..db67d1b361 100644
--- a/indra/llcommon/lleventdispatcher.h
+++ b/indra/llcommon/lleventdispatcher.h
@@ -517,27 +517,40 @@ private:
const Callable& callable,
const LLSD& required);
- template <class CLASS, typename METHOD>
+ template <class CLASS, typename METHOD,
+ typename std::enable_if<
+ std::is_base_of<LLEventDispatcher, CLASS>::value,
+ bool
+ >::type=true>
void addMethod(const std::string& name, const std::string& desc,
const METHOD& method, const LLSD& required)
{
- CLASS* downcast = dynamic_cast<CLASS*>(this);
- if (! downcast)
- {
- addFail(name, typeid(CLASS).name());
- }
- else
- {
- add(name,
- desc,
- Callable(LL::make_always_return<LLSD>(
- [downcast, method]
- (const LLSD& args)
- {
- return (downcast->*method)(args);
- })),
- required);
- }
+ // Why two overloaded addMethod() methods, discriminated with
+ // std::is_base_of? It might seem simpler to use dynamic_cast and test
+ // for nullptr. The trouble is that it doesn't work for LazyEventAPI
+ // deferred registration: we get nullptr even for a method of an
+ // LLEventAPI subclass.
+ CLASS* downcast = static_cast<CLASS*>(this);
+ add(name,
+ desc,
+ Callable(LL::make_always_return<LLSD>(
+ [downcast, method]
+ (const LLSD& args)
+ {
+ return (downcast->*method)(args);
+ })),
+ required);
+ }
+
+ template <class CLASS, typename METHOD,
+ typename std::enable_if<
+ ! std::is_base_of<LLEventDispatcher, CLASS>::value,
+ bool
+ >::type=true>
+ void addMethod(const std::string& name, const std::string& desc,
+ const METHOD&, const LLSD&)
+ {
+ addFail(name, typeid(CLASS).name());
}
template <class CLASS, typename METHOD>
@@ -562,7 +575,7 @@ private:
template <typename Function>
void addV(const std::string& name, const std::string& desc, Function f);
- void addFail(const std::string& name, const std::string& classname) const;
+ void addFail(const std::string& name, const char* classname) const;
LLSD try_call(const std::string& key, const std::string& name,
const LLSD& event) const;