From dc3833f31b8a20220ddb1775e1625c016c397435 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 19 Jun 2009 00:17:30 +0000 Subject: DEV-31980: extract dispatch-by-string-name logic from LLAresListener to new LLEventDispatcher and LLDispatchListener classes. See LLAresListener for example usage. --- indra/llcommon/lleventdispatcher.h | 108 +++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 indra/llcommon/lleventdispatcher.h (limited to 'indra/llcommon/lleventdispatcher.h') diff --git a/indra/llcommon/lleventdispatcher.h b/indra/llcommon/lleventdispatcher.h new file mode 100644 index 0000000000..d75055fd6f --- /dev/null +++ b/indra/llcommon/lleventdispatcher.h @@ -0,0 +1,108 @@ +/** + * @file lleventdispatcher.h + * @author Nat Goodspeed + * @date 2009-06-18 + * @brief Central mechanism for dispatching events by string name. This is + * useful when you have a single LLEventPump listener on which you can + * request different operations, vs. instantiating a different + * LLEventPump for each such operation. + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * Copyright (c) 2009, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_LLEVENTDISPATCHER_H) +#define LL_LLEVENTDISPATCHER_H + +#include +#include +#include +#include +#include +#include "llevents.h" + +class LLSD; + +/** + * Given an LLSD map, examine a string-valued key and call a corresponding + * callable. This class is designed to be contained by an LLEventPump + * listener class that will register some of its own methods, though any + * callable can be used. + */ +class LLEventDispatcher +{ +public: + LLEventDispatcher(const std::string& desc, const std::string& key); + virtual ~LLEventDispatcher(); + + /// Accept any C++ callable, typically a boost::bind() expression + typedef boost::function Callable; + + /// Register a @a callable by @a name. The optional @a required parameter + /// is used to validate the structure of each incoming event (see + /// llsd_matches()). + void add(const std::string& name, const Callable& callable, const LLSD& required=LLSD()); + + /// Special case: a subclass of this class can register a @a method + /// without explicitly specifying the boost::bind() expression. + /// The optional @a required parameter is used to validate the structure + /// of each incoming event (see llsd_matches()). + template + void add(const std::string& name, void (CLASS::*method)(const LLSD&), + const LLSD& required=LLSD()) + { + CLASS* downcast = dynamic_cast(this); + if (! downcast) + { + addFail(name, typeid(CLASS).name()); + } + else + { + add(name, boost::bind(method, downcast, _1), required); + } + } + + /// 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. + void operator()(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. + void operator()(const LLSD& event) const; + +private: + void addFail(const std::string& name, const std::string& classname) const; + /// try to dispatch, return @c true if success + bool attemptCall(const std::string& name, const LLSD& event) const; + + std::string mDesc, mKey; + typedef std::map > DispatchMap; + DispatchMap mDispatch; +}; + +/** + * Bundle an LLEventPump and a listener with an LLEventDispatcher. A class + * that contains (or derives from) LLDispatchListener need only specify the + * LLEventPump name and dispatch key, and add() its methods. Incoming events + * will automatically be dispatched. + */ +class LLDispatchListener: public LLEventDispatcher +{ +public: + LLDispatchListener(const std::string& pumpname, const std::string& key); + +private: + bool process(const LLSD& event); + + LLEventStream mPump; + LLTempBoundListener mBoundListener; +}; + +#endif /* ! defined(LL_LLEVENTDISPATCHER_H) */ -- cgit v1.2.3 From da46eb9e7e0f6e069e7fc06176849d213876bfe3 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 24 Jun 2009 01:54:57 +0000 Subject: DEV-31980: Extend LLEventDispatcher to handle const as well as non-const methods. Introduce LLAppViewerListener based on LLDispatchListener, instantiate a static one in llappviewer.cpp. Initial implementation only supports ["op"] == "requestQuit". --- indra/llcommon/lleventdispatcher.h | 131 ++++++++++++++++++++++++++++++++----- 1 file changed, 115 insertions(+), 16 deletions(-) (limited to 'indra/llcommon/lleventdispatcher.h') diff --git a/indra/llcommon/lleventdispatcher.h b/indra/llcommon/lleventdispatcher.h index d75055fd6f..e43d967ed4 100644 --- a/indra/llcommon/lleventdispatcher.h +++ b/indra/llcommon/lleventdispatcher.h @@ -23,6 +23,40 @@ #include "llevents.h" class LLSD; +/*==========================================================================*| +class LLEventDispatcher; + +namespace LLEventDetail +{ + /// For a given call to add(), decide whether we're being passed an + /// unbound member function pointer or a plain callable. + /// Default case. + template + struct AddCallable + { + void operator()(LLEventDispatcher& disp, const std::string& name, + const CALLABLE& callable, const LLSD& required); + }; + + /// Unbound member function pointer + template + struct AddCallable + { + typedef void (CLASS::*Method)(const LLSD&); + void operator()(LLEventDispatcher& disp, const std::string& name, + Method method, const LLSD& required); + }; + + /// Unbound const member function pointer + template + struct AddCallable + { + typedef void (CLASS::*Method)(const LLSD&) const; + void operator()(LLEventDispatcher& disp, const std::string& name, + Method method, const LLSD& required); + }; +} +|*==========================================================================*/ /** * Given an LLSD map, examine a string-valued key and call a corresponding @@ -39,28 +73,36 @@ public: /// Accept any C++ callable, typically a boost::bind() expression typedef boost::function Callable; - /// Register a @a callable by @a name. The optional @a required parameter - /// is used to validate the structure of each incoming event (see - /// llsd_matches()). + /** + * Register a @a callable by @a name. The optional @a required parameter + * is used to validate the structure of each incoming event (see + * llsd_matches()). + */ void add(const std::string& name, const Callable& callable, const LLSD& required=LLSD()); +/*==========================================================================*| + { + LLEventDetail::AddCallable()(*this, name, callable, required); + } +|*==========================================================================*/ - /// Special case: a subclass of this class can register a @a method - /// without explicitly specifying the boost::bind() expression. - /// The optional @a required parameter is used to validate the structure - /// of each incoming event (see llsd_matches()). + /** + * Special case: a subclass of this class can pass an unbound member + * function pointer without explicitly specifying the + * boost::bind() expression. + */ template void add(const std::string& name, void (CLASS::*method)(const LLSD&), const LLSD& required=LLSD()) { - CLASS* downcast = dynamic_cast(this); - if (! downcast) - { - addFail(name, typeid(CLASS).name()); - } - else - { - add(name, boost::bind(method, downcast, _1), required); - } + addMethod(name, method, required); + } + + /// Overload for both const and non-const methods + template + void add(const std::string& name, void (CLASS::*method)(const LLSD&) const, + const LLSD& required=LLSD()) + { + addMethod(name, method, required); } /// Unregister a callable @@ -78,6 +120,19 @@ public: void operator()(const LLSD& event) const; private: + template + void addMethod(const std::string& name, const METHOD& method, const LLSD& required) + { + CLASS* downcast = dynamic_cast(this); + if (! downcast) + { + addFail(name, typeid(CLASS).name()); + } + else + { + add(name, boost::bind(method, downcast, _1), required); + } + } void addFail(const std::string& name, const std::string& classname) const; /// try to dispatch, return @c true if success bool attemptCall(const std::string& name, const LLSD& event) const; @@ -87,6 +142,50 @@ private: DispatchMap mDispatch; }; +/*==========================================================================*| +/// Have to implement these template specialization methods after +/// LLEventDispatcher so they can use its methods +template +void LLEventDetail::AddCallable::operator()( + LLEventDispatcher& disp, const std::string& name, const CALLABLE& callable, const LLSD& required) +{ + disp.addImpl(name, callable, required); +} + +template +void LLEventDetail::AddCallable::operator()( + LLEventDispatcher& disp, const std::string& name, const Method& method, const LLSD& required) +{ + CLASS* downcast = dynamic_cast(&disp); + if (! downcast) + { + disp.addFail(name, typeid(CLASS).name()); + } + else + { + disp.addImpl(name, boost::bind(method, downcast, _1), required); + } +} + +/// Have to overload for both const and non-const methods +template +void LLEventDetail::AddCallable::operator()( + LLEventDispatcher& disp, const std::string& name, const Method& method, const LLSD& required) +{ + // I am severely bummed that I have, as yet, found no way short of a + // macro to avoid replicating the (admittedly brief) body of this overload. + CLASS* downcast = dynamic_cast(&disp); + if (! downcast) + { + disp.addFail(name, typeid(CLASS).name()); + } + else + { + disp.addImpl(name, boost::bind(method, downcast, _1), required); + } +} +|*==========================================================================*/ + /** * Bundle an LLEventPump and a listener with an LLEventDispatcher. A class * that contains (or derives from) LLDispatchListener need only specify the -- cgit v1.2.3 From 70d99b2528acb3bc503d3ac799e42d52515b6260 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 24 Jun 2009 16:25:33 +0000 Subject: DEV-31980: remove cruft from lleventdispatcher.h --- indra/llcommon/lleventdispatcher.h | 83 -------------------------------------- 1 file changed, 83 deletions(-) (limited to 'indra/llcommon/lleventdispatcher.h') diff --git a/indra/llcommon/lleventdispatcher.h b/indra/llcommon/lleventdispatcher.h index e43d967ed4..4da0a01c69 100644 --- a/indra/llcommon/lleventdispatcher.h +++ b/indra/llcommon/lleventdispatcher.h @@ -23,40 +23,6 @@ #include "llevents.h" class LLSD; -/*==========================================================================*| -class LLEventDispatcher; - -namespace LLEventDetail -{ - /// For a given call to add(), decide whether we're being passed an - /// unbound member function pointer or a plain callable. - /// Default case. - template - struct AddCallable - { - void operator()(LLEventDispatcher& disp, const std::string& name, - const CALLABLE& callable, const LLSD& required); - }; - - /// Unbound member function pointer - template - struct AddCallable - { - typedef void (CLASS::*Method)(const LLSD&); - void operator()(LLEventDispatcher& disp, const std::string& name, - Method method, const LLSD& required); - }; - - /// Unbound const member function pointer - template - struct AddCallable - { - typedef void (CLASS::*Method)(const LLSD&) const; - void operator()(LLEventDispatcher& disp, const std::string& name, - Method method, const LLSD& required); - }; -} -|*==========================================================================*/ /** * Given an LLSD map, examine a string-valued key and call a corresponding @@ -79,11 +45,6 @@ public: * llsd_matches()). */ void add(const std::string& name, const Callable& callable, const LLSD& required=LLSD()); -/*==========================================================================*| - { - LLEventDetail::AddCallable()(*this, name, callable, required); - } -|*==========================================================================*/ /** * Special case: a subclass of this class can pass an unbound member @@ -142,50 +103,6 @@ private: DispatchMap mDispatch; }; -/*==========================================================================*| -/// Have to implement these template specialization methods after -/// LLEventDispatcher so they can use its methods -template -void LLEventDetail::AddCallable::operator()( - LLEventDispatcher& disp, const std::string& name, const CALLABLE& callable, const LLSD& required) -{ - disp.addImpl(name, callable, required); -} - -template -void LLEventDetail::AddCallable::operator()( - LLEventDispatcher& disp, const std::string& name, const Method& method, const LLSD& required) -{ - CLASS* downcast = dynamic_cast(&disp); - if (! downcast) - { - disp.addFail(name, typeid(CLASS).name()); - } - else - { - disp.addImpl(name, boost::bind(method, downcast, _1), required); - } -} - -/// Have to overload for both const and non-const methods -template -void LLEventDetail::AddCallable::operator()( - LLEventDispatcher& disp, const std::string& name, const Method& method, const LLSD& required) -{ - // I am severely bummed that I have, as yet, found no way short of a - // macro to avoid replicating the (admittedly brief) body of this overload. - CLASS* downcast = dynamic_cast(&disp); - if (! downcast) - { - disp.addFail(name, typeid(CLASS).name()); - } - else - { - disp.addImpl(name, boost::bind(method, downcast, _1), required); - } -} -|*==========================================================================*/ - /** * Bundle an LLEventPump and a listener with an LLEventDispatcher. A class * that contains (or derives from) LLDispatchListener need only specify the -- cgit v1.2.3 From ca798b4fb243fbd85f71ea1b384181dd07ab6f66 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 1 Jul 2009 13:35:28 -0400 Subject: DEV-31980: provide a way to retrieve LLDispatchListener's tweaked LLEventPump name --- indra/llcommon/lleventdispatcher.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/llcommon/lleventdispatcher.h') diff --git a/indra/llcommon/lleventdispatcher.h b/indra/llcommon/lleventdispatcher.h index 4da0a01c69..ffc2f3eb00 100644 --- a/indra/llcommon/lleventdispatcher.h +++ b/indra/llcommon/lleventdispatcher.h @@ -114,6 +114,8 @@ class LLDispatchListener: public LLEventDispatcher public: LLDispatchListener(const std::string& pumpname, const std::string& key); + std::string getPumpName() const { return mPump.getName(); } + private: bool process(const LLSD& event); -- cgit v1.2.3 From f94d959e84cdcc552f6f5a39ee08a85c1e52d858 Mon Sep 17 00:00:00 2001 From: brad kittenbrink Date: Wed, 1 Jul 2009 19:02:42 -0400 Subject: Fixups for windows llcommon dll linkage errors that got dropped in the merge up to viewer-2.0.0-3 --- indra/llcommon/lleventdispatcher.h | 248 ++++++++++++++++++------------------- 1 file changed, 124 insertions(+), 124 deletions(-) (limited to 'indra/llcommon/lleventdispatcher.h') diff --git a/indra/llcommon/lleventdispatcher.h b/indra/llcommon/lleventdispatcher.h index 4da0a01c69..155fe0648f 100644 --- a/indra/llcommon/lleventdispatcher.h +++ b/indra/llcommon/lleventdispatcher.h @@ -1,124 +1,124 @@ -/** - * @file lleventdispatcher.h - * @author Nat Goodspeed - * @date 2009-06-18 - * @brief Central mechanism for dispatching events by string name. This is - * useful when you have a single LLEventPump listener on which you can - * request different operations, vs. instantiating a different - * LLEventPump for each such operation. - * - * $LicenseInfo:firstyear=2009&license=viewergpl$ - * Copyright (c) 2009, Linden Research, Inc. - * $/LicenseInfo$ - */ - -#if ! defined(LL_LLEVENTDISPATCHER_H) -#define LL_LLEVENTDISPATCHER_H - -#include -#include -#include -#include -#include -#include "llevents.h" - -class LLSD; - -/** - * Given an LLSD map, examine a string-valued key and call a corresponding - * callable. This class is designed to be contained by an LLEventPump - * listener class that will register some of its own methods, though any - * callable can be used. - */ -class LLEventDispatcher -{ -public: - LLEventDispatcher(const std::string& desc, const std::string& key); - virtual ~LLEventDispatcher(); - - /// Accept any C++ callable, typically a boost::bind() expression - typedef boost::function Callable; - - /** - * Register a @a callable by @a name. The optional @a required parameter - * is used to validate the structure of each incoming event (see - * llsd_matches()). - */ - void add(const std::string& name, const Callable& callable, const LLSD& required=LLSD()); - - /** - * Special case: a subclass of this class can pass an unbound member - * function pointer without explicitly specifying the - * boost::bind() expression. - */ - template - void add(const std::string& name, void (CLASS::*method)(const LLSD&), - const LLSD& required=LLSD()) - { - addMethod(name, method, required); - } - - /// Overload for both const and non-const methods - template - void add(const std::string& name, void (CLASS::*method)(const LLSD&) const, - const LLSD& required=LLSD()) - { - addMethod(name, method, required); - } - - /// 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. - void operator()(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. - void operator()(const LLSD& event) const; - -private: - template - void addMethod(const std::string& name, const METHOD& method, const LLSD& required) - { - CLASS* downcast = dynamic_cast(this); - if (! downcast) - { - addFail(name, typeid(CLASS).name()); - } - else - { - add(name, boost::bind(method, downcast, _1), required); - } - } - void addFail(const std::string& name, const std::string& classname) const; - /// try to dispatch, return @c true if success - bool attemptCall(const std::string& name, const LLSD& event) const; - - std::string mDesc, mKey; - typedef std::map > DispatchMap; - DispatchMap mDispatch; -}; - -/** - * Bundle an LLEventPump and a listener with an LLEventDispatcher. A class - * that contains (or derives from) LLDispatchListener need only specify the - * LLEventPump name and dispatch key, and add() its methods. Incoming events - * will automatically be dispatched. - */ -class LLDispatchListener: public LLEventDispatcher -{ -public: - LLDispatchListener(const std::string& pumpname, const std::string& key); - -private: - bool process(const LLSD& event); - - LLEventStream mPump; - LLTempBoundListener mBoundListener; -}; - -#endif /* ! defined(LL_LLEVENTDISPATCHER_H) */ +/** + * @file lleventdispatcher.h + * @author Nat Goodspeed + * @date 2009-06-18 + * @brief Central mechanism for dispatching events by string name. This is + * useful when you have a single LLEventPump listener on which you can + * request different operations, vs. instantiating a different + * LLEventPump for each such operation. + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * Copyright (c) 2009, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_LLEVENTDISPATCHER_H) +#define LL_LLEVENTDISPATCHER_H + +#include +#include +#include +#include +#include +#include "llevents.h" + +class LLSD; + +/** + * Given an LLSD map, examine a string-valued key and call a corresponding + * callable. This class is designed to be contained by an LLEventPump + * listener class that will register some of its own methods, though any + * callable can be used. + */ +class LL_COMMON_API LLEventDispatcher +{ +public: + LLEventDispatcher(const std::string& desc, const std::string& key); + virtual ~LLEventDispatcher(); + + /// Accept any C++ callable, typically a boost::bind() expression + typedef boost::function Callable; + + /** + * Register a @a callable by @a name. The optional @a required parameter + * is used to validate the structure of each incoming event (see + * llsd_matches()). + */ + void add(const std::string& name, const Callable& callable, const LLSD& required=LLSD()); + + /** + * Special case: a subclass of this class can pass an unbound member + * function pointer without explicitly specifying the + * boost::bind() expression. + */ + template + void add(const std::string& name, void (CLASS::*method)(const LLSD&), + const LLSD& required=LLSD()) + { + addMethod(name, method, required); + } + + /// Overload for both const and non-const methods + template + void add(const std::string& name, void (CLASS::*method)(const LLSD&) const, + const LLSD& required=LLSD()) + { + addMethod(name, method, required); + } + + /// 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. + void operator()(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. + void operator()(const LLSD& event) const; + +private: + template + void addMethod(const std::string& name, const METHOD& method, const LLSD& required) + { + CLASS* downcast = dynamic_cast(this); + if (! downcast) + { + addFail(name, typeid(CLASS).name()); + } + else + { + add(name, boost::bind(method, downcast, _1), required); + } + } + void addFail(const std::string& name, const std::string& classname) const; + /// try to dispatch, return @c true if success + bool attemptCall(const std::string& name, const LLSD& event) const; + + std::string mDesc, mKey; + typedef std::map > DispatchMap; + DispatchMap mDispatch; +}; + +/** + * Bundle an LLEventPump and a listener with an LLEventDispatcher. A class + * that contains (or derives from) LLDispatchListener need only specify the + * LLEventPump name and dispatch key, and add() its methods. Incoming events + * will automatically be dispatched. + */ +class LL_COMMON_API LLDispatchListener: public LLEventDispatcher +{ +public: + LLDispatchListener(const std::string& pumpname, const std::string& key); + +private: + bool process(const LLSD& event); + + LLEventStream mPump; + LLTempBoundListener mBoundListener; +}; + +#endif /* ! defined(LL_LLEVENTDISPATCHER_H) */ -- cgit v1.2.3 From e3a4e3dc10a96b0822674cea262f41774e55a660 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 9 Oct 2009 19:42:59 -0400 Subject: DEV-40930: Added ["change"] key to login-module status events. Changed existing event calls to use state as "offline" or "online", with "change" indicating the reason for this status event. Changed disconnect() to send state "offline", change "disconnect" -- instead of replaying last auth failure. Changed unit tests accordingly. Changed LLLoginInstance::handleLoginEvent() to use LLEventDispatcher to route calls to handleLoginFailure() et al. Added LLEventDispatcher::get() to allow retrieving Callable by name and testing for empty(). --- indra/llcommon/lleventdispatcher.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'indra/llcommon/lleventdispatcher.h') diff --git a/indra/llcommon/lleventdispatcher.h b/indra/llcommon/lleventdispatcher.h index ef83ebabc1..671f2a4d1c 100644 --- a/indra/llcommon/lleventdispatcher.h +++ b/indra/llcommon/lleventdispatcher.h @@ -80,6 +80,10 @@ public: /// @a required prototype specified at add() time, die with LL_ERRS. void operator()(const LLSD& event) const; + /// Fetch the Callable for the specified name. If no such name was + /// registered, return an empty() Callable. + Callable get(const std::string& name) const; + private: template void addMethod(const std::string& name, const METHOD& method, const LLSD& required) -- cgit v1.2.3