lleventdispatcher.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:6k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /**
  2.  * @file   lleventdispatcher.cpp
  3.  * @author Nat Goodspeed
  4.  * @date   2009-06-18
  5.  * @brief  Implementation for lleventdispatcher.
  6.  * 
  7.  * $LicenseInfo:firstyear=2009&license=viewergpl$
  8.  * 
  9.  * Copyright (c) 2009-2010, Linden Research, Inc.
  10.  * 
  11.  * Second Life Viewer Source Code
  12.  * The source code in this file ("Source Code") is provided by Linden Lab
  13.  * to you under the terms of the GNU General Public License, version 2.0
  14.  * ("GPL"), unless you have obtained a separate licensing agreement
  15.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  16.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  17.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  18.  * 
  19.  * There are special exceptions to the terms and conditions of the GPL as
  20.  * it is applied to this Source Code. View the full text of the exception
  21.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  22.  * online at
  23.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  24.  * 
  25.  * By copying, modifying or distributing this software, you acknowledge
  26.  * that you have read and understood your obligations described above,
  27.  * and agree to abide by those obligations.
  28.  * 
  29.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  30.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  31.  * COMPLETENESS OR PERFORMANCE.
  32.  * $/LicenseInfo$
  33.  */
  34. #if LL_WINDOWS
  35. #pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
  36. #endif
  37. // Precompiled header
  38. #include "linden_common.h"
  39. // associated header
  40. #include "lleventdispatcher.h"
  41. // STL headers
  42. // std headers
  43. // external library headers
  44. // other Linden headers
  45. #include "llevents.h"
  46. #include "llerror.h"
  47. #include "llsdutil.h"
  48. LLEventDispatcher::LLEventDispatcher(const std::string& desc, const std::string& key):
  49.     mDesc(desc),
  50.     mKey(key)
  51. {
  52. }
  53. LLEventDispatcher::~LLEventDispatcher()
  54. {
  55. }
  56. /// Register a callable by name
  57. void LLEventDispatcher::add(const std::string& name, const std::string& desc,
  58.                             const Callable& callable, const LLSD& required)
  59. {
  60.     mDispatch.insert(DispatchMap::value_type(name,
  61.                                              DispatchMap::mapped_type(callable, desc, required)));
  62. }
  63. void LLEventDispatcher::addFail(const std::string& name, const std::string& classname) const
  64. {
  65.     LL_ERRS("LLEventDispatcher") << "LLEventDispatcher(" << mDesc << ")::add(" << name
  66.                                  << "): " << classname << " is not a subclass "
  67.                                  << "of LLEventDispatcher" << LL_ENDL;
  68. }
  69. /// Unregister a callable
  70. bool LLEventDispatcher::remove(const std::string& name)
  71. {
  72.     DispatchMap::iterator found = mDispatch.find(name);
  73.     if (found == mDispatch.end())
  74.     {
  75.         return false;
  76.     }
  77.     mDispatch.erase(found);
  78.     return true;
  79. }
  80. /// Call a registered callable with an explicitly-specified name. If no
  81. /// such callable exists, die with LL_ERRS.
  82. void LLEventDispatcher::operator()(const std::string& name, const LLSD& event) const
  83. {
  84.     if (! attemptCall(name, event))
  85.     {
  86.         LL_ERRS("LLEventDispatcher") << "LLEventDispatcher(" << mDesc << "): '" << name
  87.                                      << "' not found" << LL_ENDL;
  88.     }
  89. }
  90. /// Extract the @a key value from the incoming @a event, and call the
  91. /// callable whose name is specified by that map @a key. If no such
  92. /// callable exists, die with LL_ERRS.
  93. void LLEventDispatcher::operator()(const LLSD& event) const
  94. {
  95.     // This could/should be implemented in terms of the two-arg overload.
  96.     // However -- we can produce a more informative error message.
  97.     std::string name(event[mKey]);
  98.     if (! attemptCall(name, event))
  99.     {
  100.         LL_ERRS("LLEventDispatcher") << "LLEventDispatcher(" << mDesc << "): bad " << mKey
  101.                                      << " value '" << name << "'" << LL_ENDL;
  102.     }
  103. }
  104. bool LLEventDispatcher::attemptCall(const std::string& name, const LLSD& event) const
  105. {
  106.     DispatchMap::const_iterator found = mDispatch.find(name);
  107.     if (found == mDispatch.end())
  108.     {
  109.         // The reason we only return false, leaving it up to our caller to die
  110.         // with LL_ERRS, is that different callers have different amounts of
  111.         // available information.
  112.         return false;
  113.     }
  114.     // Found the name, so it's plausible to even attempt the call. But first,
  115.     // validate the syntax of the event itself.
  116.     std::string mismatch(llsd_matches(found->second.mRequired, event));
  117.     if (! mismatch.empty())
  118.     {
  119.         LL_ERRS("LLEventDispatcher") << "LLEventDispatcher(" << mDesc << ") calling '" << name
  120.                                      << "': bad request: " << mismatch << LL_ENDL;
  121.     }
  122.     // Event syntax looks good, go for it!
  123.     (found->second.mFunc)(event);
  124.     return true;                    // tell caller we were able to call
  125. }
  126. LLEventDispatcher::Callable LLEventDispatcher::get(const std::string& name) const
  127. {
  128.     DispatchMap::const_iterator found = mDispatch.find(name);
  129.     if (found == mDispatch.end())
  130.     {
  131.         return Callable();
  132.     }
  133.     return found->second.mFunc;
  134. }
  135. LLSD LLEventDispatcher::getMetadata(const std::string& name) const
  136. {
  137.     DispatchMap::const_iterator found = mDispatch.find(name);
  138.     if (found == mDispatch.end())
  139.     {
  140.         return LLSD();
  141.     }
  142.     LLSD meta;
  143.     meta["name"] = name;
  144.     meta["desc"] = found->second.mDesc;
  145.     meta["required"] = found->second.mRequired;
  146.     return meta;
  147. }
  148. LLDispatchListener::LLDispatchListener(const std::string& pumpname, const std::string& key):
  149.     LLEventDispatcher(pumpname, key),
  150.     mPump(pumpname, true),          // allow tweaking for uniqueness
  151.     mBoundListener(mPump.listen("self", boost::bind(&LLDispatchListener::process, this, _1)))
  152. {
  153. }
  154. bool LLDispatchListener::process(const LLSD& event)
  155. {
  156.     (*this)(event);
  157.     return false;
  158. }