/indra/llcommon/lleventapi.h

https://bitbucket.org/lindenlab/viewer-beta/ · C++ Header · 166 lines · 39 code · 13 blank · 114 comment · 0 complexity · f726b15ba21c27d765dfdaff41b8dead MD5 · raw file

  1. /**
  2. * @file lleventapi.h
  3. * @author Nat Goodspeed
  4. * @date 2009-10-28
  5. * @brief LLEventAPI is the base class for every class that wraps a C++ API
  6. * in an event API
  7. * (see https://wiki.lindenlab.com/wiki/Incremental_Viewer_Automation/Event_API).
  8. *
  9. * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  10. * Second Life Viewer Source Code
  11. * Copyright (C) 2010, Linden Research, Inc.
  12. *
  13. * This library is free software; you can redistribute it and/or
  14. * modify it under the terms of the GNU Lesser General Public
  15. * License as published by the Free Software Foundation;
  16. * version 2.1 of the License only.
  17. *
  18. * This library is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  21. * Lesser General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU Lesser General Public
  24. * License along with this library; if not, write to the Free Software
  25. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  26. *
  27. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  28. * $/LicenseInfo$
  29. */
  30. #if ! defined(LL_LLEVENTAPI_H)
  31. #define LL_LLEVENTAPI_H
  32. #include "lleventdispatcher.h"
  33. #include "llinstancetracker.h"
  34. #include <string>
  35. /**
  36. * LLEventAPI not only provides operation dispatch functionality, inherited
  37. * from LLDispatchListener -- it also gives us event API introspection.
  38. * Deriving from LLInstanceTracker lets us enumerate instances.
  39. */
  40. class LL_COMMON_API LLEventAPI: public LLDispatchListener,
  41. public LLInstanceTracker<LLEventAPI, std::string>
  42. {
  43. typedef LLDispatchListener lbase;
  44. typedef LLInstanceTracker<LLEventAPI, std::string> ibase;
  45. public:
  46. /**
  47. * @param name LLEventPump name on which this LLEventAPI will listen. This
  48. * also serves as the LLInstanceTracker instance key.
  49. * @param desc Documentation string shown to a client trying to discover
  50. * available event APIs.
  51. * @param field LLSD::Map key used by LLDispatchListener to look up the
  52. * subclass method to invoke [default "op"].
  53. */
  54. LLEventAPI(const std::string& name, const std::string& desc, const std::string& field="op");
  55. virtual ~LLEventAPI();
  56. /// Get the string name of this LLEventAPI
  57. std::string getName() const { return ibase::getKey(); }
  58. /// Get the documentation string
  59. std::string getDesc() const { return mDesc; }
  60. /**
  61. * Publish only selected add() methods from LLEventDispatcher.
  62. * Every LLEventAPI add() @em must have a description string.
  63. */
  64. template <typename CALLABLE>
  65. void add(const std::string& name,
  66. const std::string& desc,
  67. CALLABLE callable,
  68. const LLSD& required=LLSD())
  69. {
  70. LLEventDispatcher::add(name, desc, callable, required);
  71. }
  72. /**
  73. * Instantiate a Response object in any LLEventAPI subclass method that
  74. * wants to guarantee a reply (if requested) will be sent on exit from the
  75. * method. The reply will be sent if request.has(@a replyKey), default
  76. * "reply". If specified, the value of request[replyKey] is the name of
  77. * the LLEventPump on which to send the reply. Conventionally you might
  78. * code something like:
  79. *
  80. * @code
  81. * void MyEventAPI::someMethod(const LLSD& request)
  82. * {
  83. * // Send a reply event as long as request.has("reply")
  84. * Response response(LLSD(), request);
  85. * // ...
  86. * // will be sent in reply event
  87. * response["somekey"] = some_data;
  88. * }
  89. * @endcode
  90. */
  91. class LL_COMMON_API Response
  92. {
  93. public:
  94. /**
  95. * Instantiating a Response object in an LLEventAPI subclass method
  96. * ensures that, if desired, a reply event will be sent.
  97. *
  98. * @a seed is the initial reply LLSD that will be further decorated before
  99. * being sent as the reply
  100. *
  101. * @a request is the incoming request LLSD; we particularly care about
  102. * [replyKey] and ["reqid"]
  103. *
  104. * @a replyKey [default "reply"] is the string name of the LLEventPump
  105. * on which the caller wants a reply. If <tt>(!
  106. * request.has(replyKey))</tt>, no reply will be sent.
  107. */
  108. Response(const LLSD& seed, const LLSD& request, const LLSD::String& replyKey="reply");
  109. ~Response();
  110. /**
  111. * @code
  112. * if (some condition)
  113. * {
  114. * response.warn("warnings are logged and collected in [\"warnings\"]");
  115. * }
  116. * @endcode
  117. */
  118. void warn(const std::string& warning);
  119. /**
  120. * @code
  121. * if (some condition isn't met)
  122. * {
  123. * // In a function returning void, you can validly 'return
  124. * // expression' if the expression is itself of type void. But
  125. * // returning is up to you; response.error() has no effect on
  126. * // flow of control.
  127. * return response.error("error message, logged and also sent as [\"error\"]");
  128. * }
  129. * @endcode
  130. */
  131. void error(const std::string& error);
  132. /**
  133. * set other keys...
  134. *
  135. * @code
  136. * // set any attributes you want to be sent in the reply
  137. * response["info"] = some_value;
  138. * // ...
  139. * response["ok"] = went_well;
  140. * @endcode
  141. */
  142. LLSD& operator[](const LLSD::String& key) { return mResp[key]; }
  143. /**
  144. * set the response to the given data
  145. */
  146. void setResponse(LLSD const & response){ mResp = response; }
  147. LLSD mResp, mReq;
  148. LLSD::String mKey;
  149. };
  150. private:
  151. std::string mDesc;
  152. };
  153. #endif /* ! defined(LL_LLEVENTAPI_H) */