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

游戏引擎

开发平台:

C++ Builder

  1. /**
  2.  * @file   llcapabilitylistener.cpp
  3.  * @author Nat Goodspeed
  4.  * @date   2009-01-07
  5.  * @brief  Implementation for llcapabilitylistener.
  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. // Precompiled header
  35. #include "llviewerprecompiledheaders.h"
  36. // associated header
  37. #include "llcapabilitylistener.h"
  38. // STL headers
  39. #include <map>
  40. // std headers
  41. // external library headers
  42. #include <boost/bind.hpp>
  43. // other Linden headers
  44. #include "stringize.h"
  45. #include "llcapabilityprovider.h"
  46. #include "message.h"
  47. class LLCapabilityListener::CapabilityMappers: public LLSingleton<LLCapabilityListener::CapabilityMappers>
  48. {
  49. public:
  50.     void registerMapper(const LLCapabilityListener::CapabilityMapper*);
  51.     void unregisterMapper(const LLCapabilityListener::CapabilityMapper*);
  52.     const LLCapabilityListener::CapabilityMapper* find(const std::string& cap) const;
  53.     struct DupCapMapper: public std::runtime_error
  54.     {
  55.         DupCapMapper(const std::string& what):
  56.             std::runtime_error(std::string("DupCapMapper: ") + what)
  57.         {}
  58.     };
  59. private:
  60.     friend class LLSingleton<LLCapabilityListener::CapabilityMappers>;
  61.     CapabilityMappers();
  62.     typedef std::map<std::string, const LLCapabilityListener::CapabilityMapper*> CapabilityMap;
  63.     CapabilityMap mMap;
  64. };
  65. LLCapabilityListener::LLCapabilityListener(const std::string& name,
  66.                                            LLMessageSystem* messageSystem,
  67.                                            const LLCapabilityProvider& provider,
  68.                                            const LLUUID& agentID,
  69.                                            const LLUUID& sessionID):
  70.     mEventPump(name),
  71.     mMessageSystem(messageSystem),
  72.     mProvider(provider),
  73.     mAgentID(agentID),
  74.     mSessionID(sessionID)
  75. {
  76.     mEventPump.listen("self", boost::bind(&LLCapabilityListener::capListener, this, _1));
  77. }
  78. bool LLCapabilityListener::capListener(const LLSD& request)
  79. {
  80.     // Extract what we want from the request object. We do it all up front
  81.     // partly to document what we expect.
  82.     LLSD::String cap(request["message"]);
  83.     LLSD payload(request["payload"]);
  84.     LLSD::String reply(request["reply"]);
  85.     LLSD::String error(request["error"]);
  86.     LLSD::Real timeout(request["timeout"]);
  87.     // If the LLSD doesn't even have a "message" key, we doubt it was intended
  88.     // for this listener.
  89.     if (cap.empty())
  90.     {
  91.         LL_ERRS("capListener") << "capability request event without 'message' key to '"
  92.                                << getCapAPI().getName()
  93.                                << "' on regionn" << mProvider.getDescription()
  94.                                << LL_ENDL;
  95.         return false;               // in case fatal-error function isn't
  96.     }
  97.     // Establish default timeout. This test relies on LLSD::asReal() returning
  98.     // exactly 0.0 for an undef value.
  99.     if (! timeout)
  100.     {
  101.         timeout = HTTP_REQUEST_EXPIRY_SECS;
  102.     }
  103.     // Look up the url for the requested capability name.
  104.     std::string url = mProvider.getCapability(cap);
  105.     if (! url.empty())
  106.     {
  107.         // This capability is supported by the region to which we're talking.
  108.         LLHTTPClient::post(url, payload,
  109.                            new LLSDMessage::EventResponder(LLEventPumps::instance(),
  110.                                                            request,
  111.                                                            mProvider.getDescription(),
  112.                                                            cap, reply, error),
  113.                            LLSD(),  // headers
  114.                            timeout);
  115.     }
  116.     else
  117.     {
  118.         // Capability not supported -- do we have a registered mapper?
  119.         const CapabilityMapper* mapper = CapabilityMappers::instance().find(cap);
  120.         if (! mapper)               // capability neither supported nor mapped
  121.         {
  122.             LL_ERRS("capListener") << "unsupported capability '" << cap << "' request to '"
  123.                                    << getCapAPI().getName() << "' on regionn"
  124.                                    << mProvider.getDescription()
  125.                                    << LL_ENDL;
  126.         }
  127.         else if (! mapper->getReplyName().empty()) // mapper expects reply support
  128.         {
  129.             LL_ERRS("capListener") << "Mapper for capability '" << cap
  130.                                    << "' requires unimplemented support for reply message '"
  131.                                    << mapper->getReplyName()
  132.                                    << "' on '" << getCapAPI().getName() << "' on regionn"
  133.                                    << mProvider.getDescription()
  134.                                    << LL_ENDL;
  135.         }
  136.         else
  137.         {
  138.             LL_INFOS("capListener") << "fallback invoked for capability '" << cap
  139.                                     << "' request to '" << getCapAPI().getName()
  140.                                     << "' on regionn" << mProvider.getDescription()
  141.                                     << LL_ENDL;
  142.             mapper->buildMessage(mMessageSystem, mAgentID, mSessionID, cap, payload);
  143.             mMessageSystem->sendReliable(mProvider.getHost());
  144.         }
  145.     }
  146.     return false;
  147. }
  148. LLCapabilityListener::CapabilityMapper::CapabilityMapper(const std::string& cap, const std::string& reply):
  149.     mCapName(cap),
  150.     mReplyName(reply)
  151. {
  152.     LLCapabilityListener::CapabilityMappers::instance().registerMapper(this);
  153. }
  154. LLCapabilityListener::CapabilityMapper::~CapabilityMapper()
  155. {
  156.     LLCapabilityListener::CapabilityMappers::instance().unregisterMapper(this);
  157. }
  158. LLSD LLCapabilityListener::CapabilityMapper::readResponse(LLMessageSystem* messageSystem) const
  159. {
  160.     return LLSD();
  161. }
  162. LLCapabilityListener::CapabilityMappers::CapabilityMappers() {}
  163. void LLCapabilityListener::CapabilityMappers::registerMapper(const LLCapabilityListener::CapabilityMapper* mapper)
  164. {
  165.     // Try to insert a new map entry by which we can look up the passed mapper
  166.     // instance.
  167.     std::pair<CapabilityMap::iterator, bool> inserted =
  168.         mMap.insert(CapabilityMap::value_type(mapper->getCapName(), mapper));
  169.     // If we already have a mapper for that name, insert() merely located the
  170.     // existing iterator and returned false. It is a coding error to try to
  171.     // register more than one mapper for the same capability name.
  172.     if (! inserted.second)
  173.     {
  174.         throw DupCapMapper(std::string("Duplicate capability name ") + mapper->getCapName());
  175.     }
  176. }
  177. void LLCapabilityListener::CapabilityMappers::unregisterMapper(const LLCapabilityListener::CapabilityMapper* mapper)
  178. {
  179.     CapabilityMap::iterator found = mMap.find(mapper->getCapName());
  180.     if (found != mMap.end())
  181.     {
  182.         mMap.erase(found);
  183.     }
  184. }
  185. const LLCapabilityListener::CapabilityMapper*
  186. LLCapabilityListener::CapabilityMappers::find(const std::string& cap) const
  187. {
  188.     CapabilityMap::const_iterator found = mMap.find(cap);
  189.     if (found != mMap.end())
  190.     {
  191.         return found->second;
  192.     }
  193.     return NULL;
  194. }