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

CHOP-763: Extend LLEventAPI "LLViewerControl" API; add queries.

This is a significant refactoring of planned (but as yet unimplemented) work,
though in fact it's almost completely compatible with the only implemented
operation. The set() operation now requires op="set", where before that was
inferred because set() was the only possibility.
Whereas before LLViewerControlListener dispatched to different bound methods
on the "group" key, with four known "group" string values, it now dispatches
on the "op" key, supporting "set", "toggle", "get", "groups", "vars" -- the
last two exposing query functionality. LLControlGroup is actually derived from
LLInstanceTracker, keyed on string names, so we can look up instances using
LLControlGroup::getInstance(const std::string&), or enumerate all such names.
LLControlGroup similarly permits iterating over all defined LLControlVariables.
The static LLViewerControlListener instance has been wrapped in an unnamed
namespace and removed from llviewercontrollistener.h. The availability of the
API depends on LLEventPumps::obtain(), rather than normal C++ visibility.
parent 3ddf3aef
No related branches found
No related tags found
No related merge requests found
...@@ -31,99 +31,196 @@ ...@@ -31,99 +31,196 @@
#include "llviewercontrollistener.h" #include "llviewercontrollistener.h"
#include "llviewercontrol.h" #include "llviewercontrol.h"
#include "llcontrol.h"
#include "llerror.h"
#include "llsdutil.h"
#include "stringize.h"
#include <sstream>
LLViewerControlListener gSavedSettingsListener; namespace {
LLViewerControlListener sSavedSettingsListener;
} // unnamed namespace
LLViewerControlListener::LLViewerControlListener() LLViewerControlListener::LLViewerControlListener()
: LLEventAPI("LLViewerControl", : LLEventAPI("LLViewerControl",
"LLViewerControl listener: set, toggle or set default for various controls", "LLViewerControl listener: set, toggle or set default for various controls")
"group")
{ {
add("Global", std::ostringstream groupnames;
"Set gSavedSettings control [\"key\"] to value [\"value\"]", groupnames << "[\"group\"] is one of ";
boost::bind(&LLViewerControlListener::set, &gSavedSettings, _1)); const char* delim = "";
add("PerAccount", for (LLControlGroup::key_iter cgki(LLControlGroup::beginKeys()),
"Set gSavedPerAccountSettings control [\"key\"] to value [\"value\"]", cgkend(LLControlGroup::endKeys());
boost::bind(&LLViewerControlListener::set, &gSavedPerAccountSettings, _1)); cgki != cgkend; ++cgki)
add("Warning", {
"Set gWarningSettings control [\"key\"] to value [\"value\"]", groupnames << delim << '"' << *cgki << '"';
boost::bind(&LLViewerControlListener::set, &gWarningSettings, _1)); delim = ", ";
add("Crash", }
"Set gCrashSettings control [\"key\"] to value [\"value\"]", groupnames << '\n';
boost::bind(&LLViewerControlListener::set, &gCrashSettings, _1)); std::string grouphelp(groupnames.str());
std::string replyhelp("If [\"reply\"] requested, send new [\"value\"] on specified LLEventPump\n");
#if 0
add(/*"toggleControl",*/ "Global", boost::bind(&LLViewerControlListener::toggleControl, &gSavedSettings, _1)); add("set",
add(/*"toggleControl",*/ "PerAccount", boost::bind(&LLViewerControlListener::toggleControl, &gSavedPerAccountSettings, _1)); std::string("Set [\"group\"] control [\"key\"] to optional value [\"value\"]\n"
add(/*"toggleControl",*/ "Warning", boost::bind(&LLViewerControlListener::toggleControl, &gWarningSettings, _1)); "If [\"value\"] omitted, set to control's defined default value\n") +
add(/*"toggleControl",*/ "Crash", boost::bind(&LLViewerControlListener::toggleControl, &gCrashSettings, _1)); grouphelp + replyhelp,
&LLViewerControlListener::set,
add(/*"setDefault",*/ "Global", boost::bind(&LLViewerControlListener::setDefault, &gSavedSettings, _1)); LLSDMap("group", LLSD())("key", LLSD()));
add(/*"setDefault",*/ "PerAccount", boost::bind(&LLViewerControlListener::setDefault, &gSavedPerAccountSettings, _1)); add("toggle",
add(/*"setDefault",*/ "Warning", boost::bind(&LLViewerControlListener::setDefault, &gWarningSettings, _1)); std::string("Toggle [\"group\"] control [\"key\"], if boolean\n") + grouphelp + replyhelp,
add(/*"setDefault",*/ "Crash", boost::bind(&LLViewerControlListener::setDefault, &gCrashSettings, _1)); &LLViewerControlListener::toggle,
#endif // 0 LLSDMap("group", LLSD())("key", LLSD()));
add("get",
std::string("Query [\"group\"] control [\"key\"], replying on LLEventPump [\"reply\"]\n") +
grouphelp,
&LLViewerControlListener::get,
LLSDMap("group", LLSD())("key", LLSD())("reply", LLSD()));
add("groups",
"Send on LLEventPump [\"reply\"] an array [\"groups\"] of valid group names",
&LLViewerControlListener::groups,
LLSDMap("reply", LLSD()));
add("vars",
std::string("For [\"group\"], send on LLEventPump [\"reply\"] an array [\"vars\"],\n"
"each of whose entries looks like:\n"
" [\"name\"], [\"type\"], [\"value\"], [\"comment\"]\n") + grouphelp,
&LLViewerControlListener::vars,
LLSDMap("group", LLSD())("reply", LLSD()));
} }
//static struct Info
void LLViewerControlListener::set(LLControlGroup * controls, LLSD const & event_data)
{ {
if(event_data.has("key")) Info(const LLSD& request):
response(LLSD(), request),
groupname(request["group"]),
group(LLControlGroup::getInstance(groupname)),
key(request["key"]),
control(NULL)
{ {
std::string key(event_data["key"]); if (! group)
{
response.error(STRINGIZE("Unrecognized group '" << groupname << "'"));
return;
}
if(controls->controlExists(key)) control = group->getControl(key);
if (! control)
{ {
controls->setUntypedValue(key, event_data["value"]); response.error(STRINGIZE("In group '" << groupname
<< "', unrecognized control key '" << key << "'"));
} }
else }
~Info()
{
// If in fact the request passed to our constructor names a valid
// group and key, grab the final value of the indicated control and
// stuff it in our response. Since this outer destructor runs before
// the contained Response destructor, this data will go into the
// response we send.
if (control)
{ {
llwarns << "requested unknown control: \"" << key << '\"' << llendl; response["name"] = control->getName();
response["type"] = group->typeEnumToString(control->type());
response["value"] = control->get();
response["comment"] = control->getComment();
} }
} }
LLEventAPI::Response response;
std::string groupname;
LLControlGroup* group;
std::string key;
LLControlVariable* control;
};
//static
void LLViewerControlListener::set(LLSD const & request)
{
Info info(request);
if (! info.control)
return;
if (request.has("value"))
{
info.control->setValue(request["value"]);
}
else
{
info.control->resetToDefault();
}
} }
//static //static
void LLViewerControlListener::toggleControl(LLControlGroup * controls, LLSD const & event_data) void LLViewerControlListener::toggle(LLSD const & request)
{ {
if(event_data.has("key")) Info info(request);
if (! info.control)
return;
if (info.control->isType(TYPE_BOOLEAN))
{
info.control->set(! info.control->get().asBoolean());
}
else
{ {
std::string key(event_data["key"]); info.response.error(STRINGIZE("toggle of non-boolean '" << info.groupname
<< "' control '" << info.key
<< "', type is "
<< info.group->typeEnumToString(info.control->type())));
}
}
if(controls->controlExists(key)) void LLViewerControlListener::get(LLSD const & request)
{ {
LLControlVariable * control = controls->getControl(key); // The Info constructor and destructor actually do all the work here.
if(control->isType(TYPE_BOOLEAN)) Info info(request);
{ }
control->set(!control->get().asBoolean());
} void LLViewerControlListener::groups(LLSD const & request)
else {
{ // No Info, we're not looking up either a group or a control name.
llwarns << "requested toggle of non-boolean control: \"" << key << "\", type is " << control->type() << llendl; Response response(LLSD(), request);
} for (LLControlGroup::key_iter cgki(LLControlGroup::beginKeys()),
} cgkend(LLControlGroup::endKeys());
else cgki != cgkend; ++cgki)
{ {
llwarns << "requested unknown control: \"" << key << '\"' << llendl; response["groups"].append(*cgki);
}
} }
} }
//static struct CollectVars: public LLControlGroup::ApplyFunctor
void LLViewerControlListener::setDefault(LLControlGroup * controls, LLSD const & event_data)
{ {
if(event_data.has("key")) CollectVars(LLControlGroup* g):
mGroup(g)
{}
virtual void apply(const std::string& name, LLControlVariable* control)
{ {
std::string key(event_data["key"]); vars.append(LLSDMap
("name", name)
("type", mGroup->typeEnumToString(control->type()))
("value", control->get())
("comment", control->getComment()));
}
if(controls->controlExists(key)) LLControlGroup* mGroup;
{ LLSD vars;
LLControlVariable * control = controls->getControl(key); };
control->resetToDefault();
} void LLViewerControlListener::vars(LLSD const & request)
else {
{ // This method doesn't use Info, because we're not looking up a specific
llwarns << "requested unknown control: \"" << key << '\"' << llendl; // control name.
} Response response(LLSD(), request);
std::string groupname(request["group"]);
LLControlGroup* group(LLControlGroup::getInstance(groupname));
if (! group)
{
return response.error(STRINGIZE("Unrecognized group '" << groupname << "'"));
} }
CollectVars collector(group);
group->applyToAll(&collector);
response["vars"] = collector.vars;
} }
...@@ -40,11 +40,11 @@ class LLViewerControlListener : public LLEventAPI ...@@ -40,11 +40,11 @@ class LLViewerControlListener : public LLEventAPI
LLViewerControlListener(); LLViewerControlListener();
private: private:
static void set(LLControlGroup *controls, LLSD const & event_data); static void set(LLSD const & event_data);
static void toggleControl(LLControlGroup *controls, LLSD const & event_data); static void toggle(LLSD const & event_data);
static void setDefault(LLControlGroup *controls, LLSD const & event_data); static void get(LLSD const & event_data);
static void groups(LLSD const & event_data);
static void vars(LLSD const & event_data);
}; };
extern LLViewerControlListener gSavedSettingsListener;
#endif // LL_LLVIEWERCONTROLLISTENER_H #endif // LL_LLVIEWERCONTROLLISTENER_H
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