summaryrefslogtreecommitdiff
path: root/indra/llcommon/lleventdispatcher.h
diff options
context:
space:
mode:
authorDon Kjer <don@lindenlab.com>2011-03-01 02:13:55 +0000
committerDon Kjer <don@lindenlab.com>2011-03-01 02:13:55 +0000
commit627c28da811f00ddd02a5c2af0762f427ac02a1b (patch)
tree13e1deab87b9a3c56595b796bd17347e47a93658 /indra/llcommon/lleventdispatcher.h
parentf2764d24a3b3563d66a683c84af22b61648755cb (diff)
parent0929315ab103433275a71f26a4900ee0615932e9 (diff)
Merge with viewer-headless
Diffstat (limited to 'indra/llcommon/lleventdispatcher.h')
-rw-r--r--indra/llcommon/lleventdispatcher.h75
1 files changed, 43 insertions, 32 deletions
diff --git a/indra/llcommon/lleventdispatcher.h b/indra/llcommon/lleventdispatcher.h
index ce0fc7b585..7acc61de4e 100644
--- a/indra/llcommon/lleventdispatcher.h
+++ b/indra/llcommon/lleventdispatcher.h
@@ -57,7 +57,7 @@ static const int& nil(nil_);
#endif
#include <string>
-#include <boost/ptr_container/ptr_map.hpp>
+#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/iterator/transform_iterator.hpp>
@@ -112,6 +112,19 @@ public:
const LLSD& required=LLSD());
/**
+ * The case of a free function (or static method) accepting(const LLSD&)
+ * could also be intercepted by the arbitrary-args overload below. Ensure
+ * that it's directed to the Callable overload above instead.
+ */
+ void add(const std::string& name,
+ const std::string& desc,
+ void (*f)(const LLSD&),
+ const LLSD& required=LLSD())
+ {
+ add(name, desc, Callable(f), required);
+ }
+
+ /**
* Special case: a subclass of this class can pass an unbound member
* function pointer (of an LLEventDispatcher subclass) without explicitly
* specifying the <tt>boost::bind()</tt> expression. The passed @a method
@@ -137,19 +150,6 @@ public:
addMethod<CLASS>(name, desc, method, required);
}
-/*==========================================================================*|
- /// Convenience: for LLEventDispatcher, not every callable needs a
- /// documentation string. The passed @a callable accepts a single LLSD
- /// value, presumably containing other parameters.
- template <typename CALLABLE>
- void add(const std::string& name,
- CALLABLE callable,
- const LLSD& required=LLSD())
- {
- add(name, "", callable, required);
- }
-|*==========================================================================*/
-
//@}
/// @name Register functions with arbitrary param lists
@@ -159,6 +159,10 @@ public:
* Register a free function with arbitrary parameters. (This also works
* for static class methods.)
*
+ * @note This supports functions with up to about 6 parameters -- after
+ * that you start getting dismaying compile errors in which
+ * boost::fusion::joint_view is mentioned a surprising number of times.
+ *
* When calling this name, pass an LLSD::Array. Each entry in turn will be
* converted to the corresponding parameter type using LLSDParam.
*/
@@ -171,6 +175,10 @@ public:
/**
* Register a nonstatic class method with arbitrary parameters.
*
+ * @note This supports functions with up to about 6 parameters -- after
+ * that you start getting dismaying compile errors in which
+ * boost::fusion::joint_view is mentioned a surprising number of times.
+ *
* To cover cases such as a method on an LLSingleton we don't yet want to
* instantiate, instead of directly storing an instance pointer, accept a
* nullary callable returning a pointer/reference to the desired class
@@ -192,6 +200,10 @@ public:
* Register a free function with arbitrary parameters. (This also works
* for static class methods.)
*
+ * @note This supports functions with up to about 6 parameters -- after
+ * that you start getting dismaying compile errors in which
+ * boost::fusion::joint_view is mentioned a surprising number of times.
+ *
* Pass an LLSD::Array of parameter names, and optionally another
* LLSD::Array of default parameter values, a la LLSDArgsMapper.
*
@@ -210,6 +222,10 @@ public:
/**
* Register a nonstatic class method with arbitrary parameters.
*
+ * @note This supports functions with up to about 6 parameters -- after
+ * that you start getting dismaying compile errors in which
+ * boost::fusion::joint_view is mentioned a surprising number of times.
+ *
* To cover cases such as a method on an LLSingleton we don't yet want to
* instantiate, instead of directly storing an instance pointer, accept a
* nullary callable returning a pointer/reference to the desired class
@@ -270,40 +286,35 @@ private:
struct DispatchEntry
{
DispatchEntry(const std::string& desc);
+ virtual ~DispatchEntry() {} // suppress MSVC warning, sigh
std::string mDesc;
virtual void call(const std::string& desc, const LLSD& event) const = 0;
virtual LLSD addMetadata(LLSD) const = 0;
};
- typedef boost::ptr_map<std::string, DispatchEntry> DispatchMap;
+ // Tried using boost::ptr_map<std::string, DispatchEntry>, but ptr_map<>
+ // wants its value type to be "clonable," even just to dereference an
+ // iterator. I don't want to clone entries -- if I have to copy an entry
+ // around, I want it to continue pointing to the same DispatchEntry
+ // subclass object. However, I definitely want DispatchMap to destroy
+ // DispatchEntry if no references are outstanding at the time an entry is
+ // removed. This looks like a job for boost::shared_ptr.
+ typedef std::map<std::string, boost::shared_ptr<DispatchEntry> > DispatchMap;
public:
/// We want the flexibility to redefine what data we store per name,
/// therefore our public interface doesn't expose DispatchMap iterators,
/// or DispatchMap itself, or DispatchEntry. Instead we explicitly
/// transform each DispatchMap item to NameDesc on dereferencing.
- typedef boost::transform_iterator<NameDesc(*)(DispatchMap::value_type), DispatchMap::iterator> const_iterator;
+ typedef boost::transform_iterator<NameDesc(*)(const DispatchMap::value_type&), DispatchMap::const_iterator> const_iterator;
const_iterator begin() const
{
- // Originally we used DispatchMap::const_iterator, which Just Worked
- // when DispatchMap was a std::map. Now that it's a boost::ptr_map,
- // using DispatchMap::const_iterator doesn't work so well: it
- // dereferences to a pair<string, const T*>, whereas
- // DispatchMap::value_type is just pair<string, T*>. Trying to pass a
- // dereferenced iterator to the value_type didn't work because the
- // compiler won't let you convert from const T* to plain T*. Changing
- // our const_iterator definition above to be based on non-const
- // DispatchMap::iterator works better, but of course we have to cast
- // away the constness of mDispatch to use non-const iterator. (Sigh.)
- return boost::make_transform_iterator(const_cast<DispatchMap&>(mDispatch).begin(),
- makeNameDesc);
+ return boost::make_transform_iterator(mDispatch.begin(), makeNameDesc);
}
const_iterator end() const
{
- // see begin() comments
- return boost::make_transform_iterator(const_cast<DispatchMap&>(mDispatch).end(),
- makeNameDesc);
+ return boost::make_transform_iterator(mDispatch.end(), makeNameDesc);
}
//@}
@@ -333,7 +344,7 @@ private:
std::string mDesc, mKey;
DispatchMap mDispatch;
- static NameDesc makeNameDesc(DispatchMap::value_type item)
+ static NameDesc makeNameDesc(const DispatchMap::value_type& item)
{
return NameDesc(item.first, item.second->mDesc);
}