PageRenderTime 142ms CodeModel.GetById 95ms app.highlight 43ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llviewercontrollistener.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 226 lines | 165 code | 23 blank | 38 comment | 12 complexity | a63445243470e17af6d72fc55261e479 MD5 | raw file
  1/**
  2 * @file   llviewercontrollistener.cpp
  3 * @author Brad Kittenbrink
  4 * @date   2009-07-09
  5 * @brief  Implementation for llviewercontrollistener.
  6 * 
  7 * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  8 * Second Life Viewer Source Code
  9 * Copyright (C) 2010, Linden Research, Inc.
 10 * 
 11 * This library is free software; you can redistribute it and/or
 12 * modify it under the terms of the GNU Lesser General Public
 13 * License as published by the Free Software Foundation;
 14 * version 2.1 of the License only.
 15 * 
 16 * This library is distributed in the hope that it will be useful,
 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 19 * Lesser General Public License for more details.
 20 * 
 21 * You should have received a copy of the GNU Lesser General Public
 22 * License along with this library; if not, write to the Free Software
 23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 24 * 
 25 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 26 * $/LicenseInfo$
 27 */
 28
 29#include "llviewerprecompiledheaders.h"
 30
 31#include "llviewercontrollistener.h"
 32
 33#include "llviewercontrol.h"
 34#include "llcontrol.h"
 35#include "llerror.h"
 36#include "llsdutil.h"
 37#include "stringize.h"
 38#include <sstream>
 39
 40namespace {
 41
 42LLViewerControlListener sSavedSettingsListener;
 43
 44} // unnamed namespace
 45
 46LLViewerControlListener::LLViewerControlListener()
 47	: LLEventAPI("LLViewerControl",
 48				 "LLViewerControl listener: set, toggle or set default for various controls")
 49{
 50	std::ostringstream groupnames;
 51	groupnames << "[\"group\"] is one of ";
 52	const char* delim = "";
 53	for (LLControlGroup::key_iter cgki(LLControlGroup::beginKeys()),
 54								  cgkend(LLControlGroup::endKeys());
 55		 cgki != cgkend; ++cgki)
 56	{
 57		groupnames << delim << '"' << *cgki << '"';
 58		delim = ", ";
 59	}
 60	groupnames << '\n';
 61	std::string grouphelp(groupnames.str());
 62	std::string replyhelp("If [\"reply\"] requested, send new [\"value\"] on specified LLEventPump\n");
 63
 64	add("set",
 65		std::string("Set [\"group\"] control [\"key\"] to optional value [\"value\"]\n"
 66					"If [\"value\"] omitted, set to control's defined default value\n") +
 67		grouphelp + replyhelp,
 68		&LLViewerControlListener::set,
 69		LLSDMap("group", LLSD())("key", LLSD()));
 70	add("toggle",
 71		std::string("Toggle [\"group\"] control [\"key\"], if boolean\n") + grouphelp + replyhelp,
 72		&LLViewerControlListener::toggle,
 73		LLSDMap("group", LLSD())("key", LLSD()));
 74	add("get",
 75		std::string("Query [\"group\"] control [\"key\"], replying on LLEventPump [\"reply\"]\n") +
 76		grouphelp,
 77		&LLViewerControlListener::get,
 78		LLSDMap("group", LLSD())("key", LLSD())("reply", LLSD()));
 79	add("groups",
 80		"Send on LLEventPump [\"reply\"] an array [\"groups\"] of valid group names",
 81		&LLViewerControlListener::groups,
 82		LLSDMap("reply", LLSD()));
 83	add("vars",
 84		std::string("For [\"group\"], send on LLEventPump [\"reply\"] an array [\"vars\"],\n"
 85					"each of whose entries looks like:\n"
 86					"  [\"name\"], [\"type\"], [\"value\"], [\"comment\"]\n") + grouphelp,
 87		&LLViewerControlListener::vars,
 88		LLSDMap("group", LLSD())("reply", LLSD()));
 89}
 90
 91struct Info
 92{
 93	Info(const LLSD& request):
 94		response(LLSD(), request),
 95		groupname(request["group"]),
 96		group(LLControlGroup::getInstance(groupname)),
 97		key(request["key"]),
 98		control(NULL)
 99	{
100		if (! group)
101		{
102			response.error(STRINGIZE("Unrecognized group '" << groupname << "'"));
103			return;
104		}
105
106		control = group->getControl(key);
107		if (! control)
108		{
109			response.error(STRINGIZE("In group '" << groupname
110									 << "', unrecognized control key '" << key << "'"));
111		}
112	}
113
114	~Info()
115	{
116		// If in fact the request passed to our constructor names a valid
117		// group and key, grab the final value of the indicated control and
118		// stuff it in our response. Since this outer destructor runs before
119		// the contained Response destructor, this data will go into the
120		// response we send.
121		if (control)
122		{
123			response["name"]	= control->getName();
124			response["type"]	= group->typeEnumToString(control->type());
125			response["value"]	= control->get();
126			response["comment"] = control->getComment();
127		}
128	}
129
130	LLEventAPI::Response response;
131	std::string groupname;
132	LLControlGroup* group;
133	std::string key;
134	LLControlVariable* control;
135};
136
137//static
138void LLViewerControlListener::set(LLSD const & request)
139{
140	Info info(request);
141	if (! info.control)
142		return;
143
144	if (request.has("value"))
145	{
146		info.control->setValue(request["value"]);
147	}
148	else
149	{
150		info.control->resetToDefault();
151	}
152}
153
154//static
155void LLViewerControlListener::toggle(LLSD const & request)
156{
157	Info info(request);
158	if (! info.control)
159		return;
160
161	if (info.control->isType(TYPE_BOOLEAN))
162	{
163		info.control->set(! info.control->get().asBoolean());
164	}
165	else
166	{
167		info.response.error(STRINGIZE("toggle of non-boolean '" << info.groupname
168									  << "' control '" << info.key
169									  << "', type is "
170									  << info.group->typeEnumToString(info.control->type())));
171	}
172}
173
174void LLViewerControlListener::get(LLSD const & request)
175{
176	// The Info constructor and destructor actually do all the work here.
177	Info info(request);
178}
179
180void LLViewerControlListener::groups(LLSD const & request)
181{
182	// No Info, we're not looking up either a group or a control name.
183	Response response(LLSD(), request);
184	for (LLControlGroup::key_iter cgki(LLControlGroup::beginKeys()),
185								  cgkend(LLControlGroup::endKeys());
186		 cgki != cgkend; ++cgki)
187	{
188		response["groups"].append(*cgki);
189	}
190}
191
192struct CollectVars: public LLControlGroup::ApplyFunctor
193{
194	CollectVars(LLControlGroup* g):
195		mGroup(g)
196	{}
197
198	virtual void apply(const std::string& name, LLControlVariable* control)
199	{
200		vars.append(LLSDMap
201					("name", name)
202					("type", mGroup->typeEnumToString(control->type()))
203					("value", control->get())
204					("comment", control->getComment()));
205	}
206
207	LLControlGroup* mGroup;
208	LLSD vars;
209};
210
211void LLViewerControlListener::vars(LLSD const & request)
212{
213	// This method doesn't use Info, because we're not looking up a specific
214	// control name.
215	Response response(LLSD(), request);
216	std::string groupname(request["group"]);
217	LLControlGroup* group(LLControlGroup::getInstance(groupname));
218	if (! group)
219	{
220		return response.error(STRINGIZE("Unrecognized group '" << groupname << "'"));
221	}
222
223	CollectVars collector(group);
224	group->applyToAll(&collector);
225	response["vars"] = collector.vars;
226}