PageRenderTime 40ms CodeModel.GetById 19ms app.highlight 14ms RepoModel.GetById 1ms app.codeStats 1ms

/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
 31#if ! defined(LL_LLEVENTAPI_H)
 32#define LL_LLEVENTAPI_H
 33
 34#include "lleventdispatcher.h"
 35#include "llinstancetracker.h"
 36#include <string>
 37
 38/**
 39 * LLEventAPI not only provides operation dispatch functionality, inherited
 40 * from LLDispatchListener -- it also gives us event API introspection.
 41 * Deriving from LLInstanceTracker lets us enumerate instances.
 42 */
 43class LL_COMMON_API LLEventAPI: public LLDispatchListener,
 44                  public LLInstanceTracker<LLEventAPI, std::string>
 45{
 46    typedef LLDispatchListener lbase;
 47    typedef LLInstanceTracker<LLEventAPI, std::string> ibase;
 48
 49public:
 50    /**
 51     * @param name LLEventPump name on which this LLEventAPI will listen. This
 52     * also serves as the LLInstanceTracker instance key.
 53     * @param desc Documentation string shown to a client trying to discover
 54     * available event APIs.
 55     * @param field LLSD::Map key used by LLDispatchListener to look up the
 56     * subclass method to invoke [default "op"].
 57     */
 58    LLEventAPI(const std::string& name, const std::string& desc, const std::string& field="op");
 59    virtual ~LLEventAPI();
 60
 61    /// Get the string name of this LLEventAPI
 62    std::string getName() const { return ibase::getKey(); }
 63    /// Get the documentation string
 64    std::string getDesc() const { return mDesc; }
 65
 66    /**
 67     * Publish only selected add() methods from LLEventDispatcher.
 68     * Every LLEventAPI add() @em must have a description string.
 69     */
 70    template <typename CALLABLE>
 71    void add(const std::string& name,
 72             const std::string& desc,
 73             CALLABLE callable,
 74             const LLSD& required=LLSD())
 75    {
 76        LLEventDispatcher::add(name, desc, callable, required);
 77    }
 78
 79    /**
 80     * Instantiate a Response object in any LLEventAPI subclass method that
 81     * wants to guarantee a reply (if requested) will be sent on exit from the
 82     * method. The reply will be sent if request.has(@a replyKey), default
 83     * "reply". If specified, the value of request[replyKey] is the name of
 84     * the LLEventPump on which to send the reply. Conventionally you might
 85     * code something like:
 86     *
 87     * @code
 88     * void MyEventAPI::someMethod(const LLSD& request)
 89     * {
 90     *     // Send a reply event as long as request.has("reply")
 91     *     Response response(LLSD(), request);
 92     *     // ...
 93     *     // will be sent in reply event
 94     *     response["somekey"] = some_data;
 95     * }
 96     * @endcode
 97     */
 98    class LL_COMMON_API Response
 99    {
100    public:
101        /**
102         * Instantiating a Response object in an LLEventAPI subclass method
103         * ensures that, if desired, a reply event will be sent.
104         *
105         * @a seed is the initial reply LLSD that will be further decorated before
106         * being sent as the reply
107         *
108         * @a request is the incoming request LLSD; we particularly care about
109         * [replyKey] and ["reqid"]
110         *
111         * @a replyKey [default "reply"] is the string name of the LLEventPump
112         * on which the caller wants a reply. If <tt>(!
113         * request.has(replyKey))</tt>, no reply will be sent.
114         */
115        Response(const LLSD& seed, const LLSD& request, const LLSD::String& replyKey="reply");
116        ~Response();
117
118        /**
119         * @code
120         * if (some condition)
121         * {
122         *     response.warn("warnings are logged and collected in [\"warnings\"]");
123         * }
124         * @endcode
125         */
126        void warn(const std::string& warning);
127        /**
128         * @code
129         * if (some condition isn't met)
130         * {
131         *     // In a function returning void, you can validly 'return
132         *     // expression' if the expression is itself of type void. But
133         *     // returning is up to you; response.error() has no effect on
134         *     // flow of control.
135         *     return response.error("error message, logged and also sent as [\"error\"]");
136         * }
137         * @endcode
138         */
139        void error(const std::string& error);
140
141        /**
142         * set other keys...
143         *
144         * @code
145         * // set any attributes you want to be sent in the reply
146         * response["info"] = some_value;
147         * // ...
148         * response["ok"] = went_well;
149         * @endcode
150         */
151        LLSD& operator[](const LLSD::String& key) { return mResp[key]; }
152		
153		 /**
154		 * set the response to the given data
155		 */
156		void setResponse(LLSD const & response){ mResp = response; }
157
158        LLSD mResp, mReq;
159        LLSD::String mKey;
160    };
161
162private:
163    std::string mDesc;
164};
165
166#endif /* ! defined(LL_LLEVENTAPI_H) */