Skip to content
Snippets Groups Projects
Commit 3ddf3aef authored by Nat Goodspeed's avatar Nat Goodspeed
Browse files

CHOP-763: Promote Response class from llwindowlistener.cpp to LLEventAPI.

This is a generally-useful idiom, extending the sendReply() convenience
function -- it shouldn't remain buried in a single .cpp file.
parent 54399f1f
No related branches found
No related tags found
No related merge requests found
......@@ -34,6 +34,7 @@
// std headers
// external library headers
// other Linden headers
#include "llerror.h"
LLEventAPI::LLEventAPI(const std::string& name, const std::string& desc, const std::string& field):
lbase(name, field),
......@@ -45,3 +46,32 @@ LLEventAPI::LLEventAPI(const std::string& name, const std::string& desc, const s
LLEventAPI::~LLEventAPI()
{
}
LLEventAPI::Response::Response(const LLSD& seed, const LLSD& request, const LLSD::String& replyKey):
mResp(seed),
mReq(request),
mKey(replyKey)
{}
LLEventAPI::Response::~Response()
{
// When you instantiate a stack Response object, if the original
// request requested a reply, send it when we leave this block, no
// matter how.
sendReply(mResp, mReq, mKey);
}
void LLEventAPI::Response::warn(const std::string& warning)
{
LL_WARNS("LLEventAPI::Response") << warning << LL_ENDL;
mResp["warnings"].append(warning);
}
void LLEventAPI::Response::error(const std::string& error)
{
// Use LL_WARNS rather than LL_ERROR: we don't want the viewer to shut
// down altogether.
LL_WARNS("LLEventAPI::Response") << error << LL_ENDL;
mResp["error"] = error;
}
......@@ -76,6 +76,84 @@ class LL_COMMON_API LLEventAPI: public LLDispatchListener,
LLEventDispatcher::add(name, desc, callable, required);
}
/**
* Instantiate a Response object in any LLEventAPI subclass method that
* wants to guarantee a reply (if requested) will be sent on exit from the
* method. The reply will be sent if request.has(@a replyKey), default
* "reply". If specified, the value of request[replyKey] is the name of
* the LLEventPump on which to send the reply. Conventionally you might
* code something like:
*
* @code
* void MyEventAPI::someMethod(const LLSD& request)
* {
* // Send a reply event as long as request.has("reply")
* Response response(LLSD(), request);
* // ...
* // will be sent in reply event
* response["somekey"] = some_data;
* }
* @endcode
*/
class Response
{
public:
/**
* Instantiating a Response object in an LLEventAPI subclass method
* ensures that, if desired, a reply event will be sent.
*
* @a seed is the initial reply LLSD that will be further decorated before
* being sent as the reply
*
* @a request is the incoming request LLSD; we particularly care about
* [replyKey] and ["reqid"]
*
* @a replyKey [default "reply"] is the string name of the LLEventPump
* on which the caller wants a reply. If <tt>(!
* request.has(replyKey))</tt>, no reply will be sent.
*/
Response(const LLSD& seed, const LLSD& request, const LLSD::String& replyKey="reply");
~Response();
/**
* @code
* if (some condition)
* {
* response.warn("warnings are logged and collected in [\"warnings\"]");
* }
* @endcode
*/
void warn(const std::string& warning);
/**
* @code
* if (some condition isn't met)
* {
* // In a function returning void, you can validly 'return
* // expression' if the expression is itself of type void. But
* // returning is up to you; response.error() has no effect on
* // flow of control.
* return response.error("error message, logged and also sent as [\"error\"]");
* }
* @endcode
*/
void error(const std::string& error);
/**
* set other keys...
*
* @code
* // set any attributes you want to be sent in the reply
* response["info"] = some_value;
* // ...
* response["ok"] = went_well;
* @endcode
*/
LLSD& operator[](const LLSD::String& key) { return mResp[key]; }
LLSD mResp, mReq;
LLSD::String mKey;
};
private:
std::string mDesc;
};
......
......@@ -134,46 +134,7 @@ class StringLookup
namespace {
class Response
{
public:
Response(const LLSD& seed, const LLSD& request, const LLSD::String& replyKey="reply"):
mResp(seed),
mReq(request),
mKey(replyKey)
{}
~Response()
{
// When you instantiate a stack Response object, if the original
// request requested a reply, send it when we leave this block, no
// matter how.
sendReply(mResp, mReq, mKey);
}
void warn(const std::string& warning)
{
LL_WARNS("LLWindowListener") << warning << LL_ENDL;
mResp["warnings"].append(warning);
}
void error(const std::string& error)
{
// Use LL_WARNS rather than LL_ERROR: we don't want the viewer to shut
// down altogether.
LL_WARNS("LLWindowListener") << error << LL_ENDL;
mResp["error"] = error;
}
// set other keys...
LLSD& operator[](const LLSD::String& key) { return mResp[key]; }
LLSD mResp, mReq;
LLSD::String mKey;
};
void insertViewInformation(Response & response, LLView * target)
void insertViewInformation(LLEventAPI::Response & response, LLView * target)
{
// Get info about this LLView* for when we send response.
response["path"] = target->getPathname();
......@@ -346,7 +307,7 @@ typedef boost::function<bool(LLCoordGL, MASK)> MouseFunc;
static void mouseEvent(const MouseFunc& func, const LLSD& request)
{
// Ensure we send response
Response response(LLSD(), request);
LLEventAPI::Response response(LLSD(), request);
// We haven't yet established whether the incoming request has "x" and "y",
// but capture this anyway, with 0 for omitted values.
LLCoordGL pos(request["x"].asInteger(), request["y"].asInteger());
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment