Skip to content
Snippets Groups Projects
Commit 25ee39dc authored by Nat Goodspeed's avatar Nat Goodspeed
Browse files

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)
parent d2738b60
No related branches found
No related tags found
2 merge requests!3Update to main branch,!2Rebase onto current main branch
......@@ -517,27 +517,40 @@ class LL_COMMON_API LLEventDispatcher
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 @@ class LL_COMMON_API LLEventDispatcher
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;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment