summaryrefslogtreecommitdiff
path: root/indra/llcommon/lleventdispatcher.h
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/lleventdispatcher.h')
-rw-r--r--indra/llcommon/lleventdispatcher.h155
1 files changed, 86 insertions, 69 deletions
diff --git a/indra/llcommon/lleventdispatcher.h b/indra/llcommon/lleventdispatcher.h
index 9e1244ef5b..6d1df86fea 100644
--- a/indra/llcommon/lleventdispatcher.h
+++ b/indra/llcommon/lleventdispatcher.h
@@ -61,7 +61,6 @@ static const auto& nil(nil_);
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/iterator/transform_iterator.hpp>
-#include <boost/utility/enable_if.hpp>
#include <boost/function_types/is_nonmember_callable_builtin.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/function_arity.hpp>
@@ -166,11 +165,12 @@ public:
* When calling this name, pass an LLSD::Array. Each entry in turn will be
* converted to the corresponding parameter type using LLSDParam.
*/
- template<typename Function>
- typename boost::enable_if< boost::function_types::is_nonmember_callable_builtin<Function>
- >::type add(const std::string& name,
- const std::string& desc,
- Function f);
+ // enable_if usage per https://stackoverflow.com/a/39913395/5533635
+ template<typename Function,
+ typename = typename std::enable_if<
+ boost::function_types::is_nonmember_callable_builtin<Function>::value
+ >::type>
+ void add(const std::string& name, const std::string& desc, Function f);
/**
* Register a nonstatic class method with arbitrary parameters.
@@ -189,12 +189,13 @@ public:
* When calling this name, pass an LLSD::Array. Each entry in turn will be
* converted to the corresponding parameter type using LLSDParam.
*/
- template<typename Method, typename InstanceGetter>
- typename boost::enable_if< boost::function_types::is_member_function_pointer<Method>
- >::type add(const std::string& name,
- const std::string& desc,
- Method f,
- const InstanceGetter& getter);
+ template<typename Method, typename InstanceGetter,
+ typename = typename std::enable_if<
+ boost::function_types::is_member_function_pointer<Method>::value &&
+ ! std::is_convertible<InstanceGetter, LLSD>::value
+ >::type>
+ void add(const std::string& name, const std::string& desc, Method f,
+ const InstanceGetter& getter);
/**
* Register a free function with arbitrary parameters. (This also works
@@ -211,13 +212,12 @@ public:
* an LLSD::Array using LLSDArgsMapper and then convert each entry in turn
* to the corresponding parameter type using LLSDParam.
*/
- template<typename Function>
- typename boost::enable_if< boost::function_types::is_nonmember_callable_builtin<Function>
- >::type add(const std::string& name,
- const std::string& desc,
- Function f,
- const LLSD& params,
- const LLSD& defaults=LLSD());
+ template<typename Function,
+ typename = typename std::enable_if<
+ boost::function_types::is_nonmember_callable_builtin<Function>::value
+ >::type>
+ void add(const std::string& name, const std::string& desc, Function f,
+ const LLSD& params, const LLSD& defaults=LLSD());
/**
* Register a nonstatic class method with arbitrary parameters.
@@ -240,42 +240,42 @@ public:
* an LLSD::Array using LLSDArgsMapper and then convert each entry in turn
* to the corresponding parameter type using LLSDParam.
*/
- template<typename Method, typename InstanceGetter>
- typename boost::enable_if< boost::function_types::is_member_function_pointer<Method>
- >::type add(const std::string& name,
- const std::string& desc,
- Method f,
- const InstanceGetter& getter,
- const LLSD& params,
- const LLSD& defaults=LLSD());
+ template<typename Method, typename InstanceGetter,
+ typename = typename std::enable_if<
+ boost::function_types::is_member_function_pointer<Method>::value &&
+ ! std::is_convertible<InstanceGetter, LLSD>::value
+ >::type>
+ void add(const std::string& name, const std::string& desc, Method f,
+ const InstanceGetter& getter, const LLSD& params,
+ const LLSD& defaults=LLSD());
//@}
/// Unregister a callable
bool remove(const std::string& name);
- /// Call a registered callable with an explicitly-specified name. If no
- /// such callable exists, die with LL_ERRS. If the @a event fails to match
- /// the @a required prototype specified at add() time, die with LL_ERRS.
+ /// Call a registered callable with an explicitly-specified name. It is an
+ /// error if no such callable exists. It is an error if the @a event fails
+ /// to match the @a required prototype specified at add() time.
void operator()(const std::string& name, const LLSD& event) const;
/// Call a registered callable with an explicitly-specified name and
/// return <tt>true</tt>. If no such callable exists, return
- /// <tt>false</tt>. If the @a event fails to match the @a required
- /// prototype specified at add() time, die with LL_ERRS.
+ /// <tt>false</tt>. It is an error if the @a event fails to match the @a
+ /// required prototype specified at add() time.
bool try_call(const std::string& name, const LLSD& event) const;
/// Extract the @a key value from the incoming @a event, and call the
- /// callable whose name is specified by that map @a key. If no such
- /// callable exists, die with LL_ERRS. If the @a event fails to match the
- /// @a required prototype specified at add() time, die with LL_ERRS.
+ /// callable whose name is specified by that map @a key. It is an error if
+ /// no such callable exists. It is an error if the @a event fails to match
+ /// the @a required prototype specified at add() time.
void operator()(const LLSD& event) const;
/// Extract the @a key value from the incoming @a event, call the callable
/// whose name is specified by that map @a key and return <tt>true</tt>.
- /// If no such callable exists, return <tt>false</tt>. If the @a event
- /// fails to match the @a required prototype specified at add() time, die
- /// with LL_ERRS.
+ /// If no such callable exists, return <tt>false</tt>. It is an error if
+ /// the @a event fails to match the @a required prototype specified at
+ /// add() time.
bool try_call(const LLSD& event) const;
/// @name Iterate over defined names
@@ -329,17 +329,16 @@ private:
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, boost::bind(method, downcast, _1), required);
- }
+ CLASS* downcast = static_cast<CLASS*>(this);
+ add(name, desc, boost::bind(method, downcast, _1), required);
}
- void addFail(const std::string& name, const std::string& classname) const;
+ std::string try_call_log(const std::string& key, const std::string& name,
+ const LLSD& event) const;
+ std::string try_call(const std::string& key, const std::string& name,
+ const LLSD& event) const;
+ // Implement "it is an error" semantics for attempted call operations: if
+ // the incoming event includes a "reply" key, log and send an error reply.
+ void callFail(const LLSD& event, const std::string& msg) const;
std::string mDesc, mKey;
DispatchMap mDispatch;
@@ -427,7 +426,25 @@ struct LLEventDispatcher::invoker
// Instead of grabbing the first item from argsrc and making an
// LLSDParam of it, call getter() and pass that as the instance param.
invoker<Function, next_iter_type, To>::apply
- ( func, argsrc, boost::fusion::push_back(boost::fusion::nil(), boost::ref(getter())));
+ ( func, argsrc, boost::fusion::push_back(boost::fusion::nil(), bindable(getter())));
+ }
+
+ template <typename T>
+ static inline
+ auto bindable(T&& value,
+ typename std::enable_if<std::is_pointer<T>::value, bool>::type=true)
+ {
+ // if passed a pointer, just return that pointer
+ return std::forward<T>(value);
+ }
+
+ template <typename T>
+ static inline
+ auto bindable(T&& value,
+ typename std::enable_if<! std::is_pointer<T>::value, bool>::type=true)
+ {
+ // if passed a reference, wrap it for binding
+ return std::ref(std::forward<T>(value));
}
};
@@ -446,9 +463,8 @@ struct LLEventDispatcher::invoker<Function,To,To>
}
};
-template<typename Function>
-typename boost::enable_if< boost::function_types::is_nonmember_callable_builtin<Function> >::type
-LLEventDispatcher::add(const std::string& name, const std::string& desc, Function f)
+template<typename Function, typename>
+void LLEventDispatcher::add(const std::string& name, const std::string& desc, Function f)
{
// Construct an invoker_function, a callable accepting const args_source&.
// Add to DispatchMap an ArrayParamsDispatchEntry that will handle the
@@ -457,10 +473,9 @@ LLEventDispatcher::add(const std::string& name, const std::string& desc, Functio
boost::function_types::function_arity<Function>::value);
}
-template<typename Method, typename InstanceGetter>
-typename boost::enable_if< boost::function_types::is_member_function_pointer<Method> >::type
-LLEventDispatcher::add(const std::string& name, const std::string& desc, Method f,
- const InstanceGetter& getter)
+template<typename Method, typename InstanceGetter, typename>
+void LLEventDispatcher::add(const std::string& name, const std::string& desc, Method f,
+ const InstanceGetter& getter)
{
// Subtract 1 from the compile-time arity because the getter takes care of
// the first parameter. We only need (arity - 1) additional arguments.
@@ -468,20 +483,18 @@ LLEventDispatcher::add(const std::string& name, const std::string& desc, Method
boost::function_types::function_arity<Method>::value - 1);
}
-template<typename Function>
-typename boost::enable_if< boost::function_types::is_nonmember_callable_builtin<Function> >::type
-LLEventDispatcher::add(const std::string& name, const std::string& desc, Function f,
- const LLSD& params, const LLSD& defaults)
+template<typename Function, typename>
+void LLEventDispatcher::add(const std::string& name, const std::string& desc, Function f,
+ const LLSD& params, const LLSD& defaults)
{
// See comments for previous is_nonmember_callable_builtin add().
addMapParamsDispatchEntry(name, desc, make_invoker(f), params, defaults);
}
-template<typename Method, typename InstanceGetter>
-typename boost::enable_if< boost::function_types::is_member_function_pointer<Method> >::type
-LLEventDispatcher::add(const std::string& name, const std::string& desc, Method f,
- const InstanceGetter& getter,
- const LLSD& params, const LLSD& defaults)
+template<typename Method, typename InstanceGetter, typename>
+void LLEventDispatcher::add(const std::string& name, const std::string& desc, Method f,
+ const InstanceGetter& getter,
+ const LLSD& params, const LLSD& defaults)
{
addMapParamsDispatchEntry(name, desc, make_invoker(f, getter), params, defaults);
}
@@ -524,17 +537,21 @@ LLEventDispatcher::make_invoker(Method f, const InstanceGetter& getter)
* LLEventPump name and dispatch key, and add() its methods. Incoming events
* will automatically be dispatched.
*/
-class LL_COMMON_API LLDispatchListener: public LLEventDispatcher
+// Instead of containing an LLEventStream, LLDispatchListener derives from it.
+// This allows an LLEventPumps::PumpFactory to return a pointer to an
+// LLDispatchListener (subclass) instance, and still have ~LLEventPumps()
+// properly clean it up.
+class LL_COMMON_API LLDispatchListener:
+ public LLEventDispatcher,
+ public LLEventStream
{
public:
LLDispatchListener(const std::string& pumpname, const std::string& key);
-
- std::string getPumpName() const { return mPump.getName(); }
+ virtual ~LLDispatchListener() {}
private:
bool process(const LLSD& event);
- LLEventStream mPump;
LLTempBoundListener mBoundListener;
};