From 8c90e4d468f2b4d7f1ce3b3faec163886cbf9fd5 Mon Sep 17 00:00:00 2001
From: richard <none@none>
Date: Thu, 12 Nov 2009 13:54:30 -0800
Subject: DEV-42747 - lltreeiterators_test.cpp broken on Windows

reviewed by Nat
---
 indra/llcommon/llpreprocessor.h               | 1 +
 indra/llcommon/tests/lltreeiterators_test.cpp | 3 ---
 2 files changed, 1 insertion(+), 3 deletions(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h
index 48244480b1..bb3301df9f 100644
--- a/indra/llcommon/llpreprocessor.h
+++ b/indra/llcommon/llpreprocessor.h
@@ -122,6 +122,7 @@
 #pragma warning( 3      :  4264 )	// "'virtual_function' : no override available for virtual member function from base 'class'; function is hidden"
 #pragma warning( 3       : 4265 )	// "class has virtual functions, but destructor is not virtual"
 #pragma warning( 3      :  4266 )	// 'function' : no override available for virtual member function from base 'type'; function is hidden
+#pragma warning (disable : 4180)	// qualifier applied to function type has no meaning; ignored
 #pragma warning( disable : 4284 )	// silly MS warning deep inside their <map> include file
 #pragma warning( disable : 4503 )	// 'decorated name length exceeded, name was truncated'. Does not seem to affect compilation.
 #pragma warning( disable : 4800 )	// 'BOOL' : forcing value to bool 'true' or 'false' (performance warning)
diff --git a/indra/llcommon/tests/lltreeiterators_test.cpp b/indra/llcommon/tests/lltreeiterators_test.cpp
index d6d9f68110..31c70b4daa 100644
--- a/indra/llcommon/tests/lltreeiterators_test.cpp
+++ b/indra/llcommon/tests/lltreeiterators_test.cpp
@@ -35,9 +35,6 @@
 // Precompiled header
 #include "linden_common.h"
 
-#if LL_WINDOWS
-#pragma warning (disable : 4180) // qualifier applied to function type has no meaning; ignored
-#endif
 
 // STL headers
 // std headers
-- 
cgit v1.2.3


From 2f97829aab549a4d65daead298361a0c25399be2 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 12 Nov 2009 20:11:53 -0500
Subject: Introduce LLEventDispatcher::begin()/end() to iterate over (name,
 desc) pairs for all registered operations. (untested) Introduce
 LLEventDispatcher::getMetadata(name) query so you can discover, for a given
 named operation, its query string and required parameters. (untested)
 Introduce LLEventDispatcher::add() convenience methods allowing you to omit
 description strings. Fix LLLoginInstance (which uses a non-LLEventAPI
 LLEventDispatcher) back to description-less add() calls. However, filter
 LLEventDispatcher::add() methods inherited by LLEventAPI so that an
 LLEventAPI subclass *must* provide a description string.

---
 indra/llcommon/lleventapi.h          | 13 ++++++++
 indra/llcommon/lleventdispatcher.cpp | 14 ++++++++
 indra/llcommon/lleventdispatcher.h   | 65 +++++++++++++++++++++++++++++-------
 3 files changed, 80 insertions(+), 12 deletions(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/lleventapi.h b/indra/llcommon/lleventapi.h
index fef12988cb..b45be6802b 100644
--- a/indra/llcommon/lleventapi.h
+++ b/indra/llcommon/lleventapi.h
@@ -46,6 +46,19 @@ public:
     /// Get the documentation string
     std::string getDesc() const { return mDesc; }
 
+    /**
+     * Publish only selected add() methods from LLEventDispatcher.
+     * Every LLEventAPI add() @em must have a description string.
+     */
+    template <typename CALLABLE>
+    void add(const std::string& name,
+             const std::string& desc,
+             CALLABLE callable,
+             const LLSD& required=LLSD())
+    {
+        LLEventDispatcher::add(name, desc, callable, required);
+    }
+
 private:
     std::string mDesc;
 };
diff --git a/indra/llcommon/lleventdispatcher.cpp b/indra/llcommon/lleventdispatcher.cpp
index 017bf3a521..5fa6059718 100644
--- a/indra/llcommon/lleventdispatcher.cpp
+++ b/indra/llcommon/lleventdispatcher.cpp
@@ -121,6 +121,20 @@ LLEventDispatcher::Callable LLEventDispatcher::get(const std::string& name) cons
     return found->second.mFunc;
 }
 
+LLSD LLEventDispatcher::getMetadata(const std::string& name) const
+{
+    DispatchMap::const_iterator found = mDispatch.find(name);
+    if (found == mDispatch.end())
+    {
+        return LLSD();
+    }
+    LLSD meta;
+    meta["name"] = name;
+    meta["desc"] = found->second.mDesc;
+    meta["required"] = found->second.mRequired;
+    return meta;
+}
+
 LLDispatchListener::LLDispatchListener(const std::string& pumpname, const std::string& key):
     LLEventDispatcher(pumpname, key),
     mPump(pumpname, true),          // allow tweaking for uniqueness
diff --git a/indra/llcommon/lleventdispatcher.h b/indra/llcommon/lleventdispatcher.h
index eba7b607f1..c8c4fe0c3c 100644
--- a/indra/llcommon/lleventdispatcher.h
+++ b/indra/llcommon/lleventdispatcher.h
@@ -19,6 +19,7 @@
 #include <map>
 #include <boost/function.hpp>
 #include <boost/bind.hpp>
+#include <boost/iterator/transform_iterator.hpp>
 #include <typeinfo>
 #include "llevents.h"
 
@@ -73,6 +74,16 @@ public:
         addMethod<CLASS>(name, desc, method, required);
     }
 
+    /// Convenience: for LLEventDispatcher, not every callable needs a
+    /// documentation string.
+    template <typename CALLABLE>
+    void add(const std::string& name,
+             CALLABLE callable,
+             const LLSD& required=LLSD())
+    {
+        add(name, "", callable, required);
+    }
+
     /// Unregister a callable
     bool remove(const std::string& name);
 
@@ -87,10 +98,47 @@ public:
     /// @a required prototype specified at add() time, die with LL_ERRS.
     void operator()(const LLSD& event) const;
 
+    /// @name Iterate over defined names
+    //@{
+    typedef std::pair<std::string, std::string> NameDesc;
+
+private:
+    struct DispatchEntry
+    {
+        DispatchEntry(const Callable& func, const std::string& desc, const LLSD& required):
+            mFunc(func),
+            mDesc(desc),
+            mRequired(required)
+        {}
+        Callable mFunc;
+        std::string mDesc;
+        LLSD mRequired;
+    };
+    typedef std::map<std::string, 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(*)(const DispatchMap::value_type&), DispatchMap::const_iterator> const_iterator;
+    const_iterator begin() const
+    {
+        return boost::make_transform_iterator(mDispatch.begin(), makeNameDesc);
+    }
+    const_iterator end() const
+    {
+        return boost::make_transform_iterator(mDispatch.end(), makeNameDesc);
+    }
+    //@}
+
     /// Fetch the Callable for the specified name. If no such name was
     /// registered, return an empty() Callable.
     Callable get(const std::string& name) const;
 
+    /// Get information about a specific Callable
+    LLSD getMetadata(const std::string& name) const;
+
 private:
     template <class CLASS, typename METHOD>
     void addMethod(const std::string& name, const std::string& desc,
@@ -111,19 +159,12 @@ private:
     bool attemptCall(const std::string& name, const LLSD& event) const;
 
     std::string mDesc, mKey;
-    struct DispatchEntry
-    {
-        DispatchEntry(const Callable& func, const std::string& desc, const LLSD& required):
-            mFunc(func),
-            mDesc(desc),
-            mRequired(required)
-        {}
-        Callable mFunc;
-        std::string mDesc;
-        LLSD mRequired;
-    };
-    typedef std::map<std::string, DispatchEntry> DispatchMap;
     DispatchMap mDispatch;
+
+    static NameDesc makeNameDesc(const DispatchMap::value_type& item)
+    {
+        return NameDesc(item.first, item.second.mDesc);
+    }
 };
 
 /**
-- 
cgit v1.2.3