summaryrefslogtreecommitdiff
path: root/indra/llxml/llcontrol.h
blob: a1a2a4c85194c99561157d382fdf8b0dd9506550 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
/** 
 * @file llcontrol.h
 * @brief A mechanism for storing "control state" for a program
 *
 * $LicenseInfo:firstyear=2001&license=viewergpl$
 * 
 * Copyright (c) 2001-2007, Linden Research, Inc.
 * 
 * Second Life Viewer Source Code
 * The source code in this file ("Source Code") is provided by Linden Lab
 * to you under the terms of the GNU General Public License, version 2.0
 * ("GPL"), unless you have obtained a separate licensing agreement
 * ("Other License"), formally executed by you and Linden Lab.  Terms of
 * the GPL can be found in doc/GPL-license.txt in this distribution, or
 * online at http://secondlife.com/developers/opensource/gplv2
 * 
 * There are special exceptions to the terms and conditions of the GPL as
 * it is applied to this Source Code. View the full text of the exception
 * in the file doc/FLOSS-exception.txt in this software distribution, or
 * online at http://secondlife.com/developers/opensource/flossexception
 * 
 * By copying, modifying or distributing this software, you acknowledge
 * that you have read and understood your obligations described above,
 * and agree to abide by those obligations.
 * 
 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 * COMPLETENESS OR PERFORMANCE.
 * $/LicenseInfo$
 */

#ifndef LL_LLCONTROL_H
#define LL_LLCONTROL_H

#include "llevent.h"
#include "llnametable.h"
#include "llmap.h"
#include "llstring.h"
#include "llrect.h"

class LLVector3;
class LLVector3d;
class LLColor4;
class LLColor3;
class LLColor4U;

const BOOL NO_PERSIST = FALSE;

typedef enum e_control_type
{
	TYPE_U32,
	TYPE_S32,
	TYPE_F32,
	TYPE_BOOLEAN,
	TYPE_STRING,
	TYPE_VEC3,
	TYPE_VEC3D,
	TYPE_RECT,
	TYPE_COL4,
	TYPE_COL3,
	TYPE_COL4U
} eControlType;

class LLControlBase : public LLSimpleListenerObservable
{
friend class LLControlGroup;
protected:
	LLString		mName;
	LLString		mComment;
	eControlType	mType;
	BOOL			mHasRange;
	BOOL			mPersist;
	BOOL            mIsDefault;

	static	std::set<LLControlBase*>	mChangedControls;
	static	std::list<S32>				mFreeIDs;//These lists are used to store the ID's of registered event listeners.
	static	std::list<S32>				mUsedIDs;
	static	S32							mTopID;//This is the index of the highest ID event listener ID. When the free pool is exhausted, new IDs are allocated from here.

public:
	static	void						releaseListenerID(S32	id);
	static	S32							allocateListenerID();
	static	void						updateAllListeners();
	virtual void updateListeners() = 0;

	LLControlBase(const LLString& name, eControlType type, const LLString& comment, BOOL persist)
		: mName(name),
		mComment(comment),
		mType(type),
		mHasRange(FALSE),
		mPersist(persist),
		mIsDefault(TRUE)
	{ 
		if (mPersist && mComment.empty())
		{
			llerrs << "Must supply a comment for control " << mName << llendl;
		}
		sMaxControlNameLength = llmax((U32)mName.size(), sMaxControlNameLength);
	}

	virtual ~LLControlBase();

	const LLString& getName() const { return mName; }
	const LLString& getComment() const { return mComment; }

	eControlType type()		{ return mType; }
	BOOL	isType(eControlType tp) { return tp == mType; }

	// Defaults to no-op
	virtual void resetToDefault();

	LLSD registerListener(LLSimpleListenerObservable *listener, LLSD userdata = "");

	virtual LLSD get() const = 0;
	virtual LLSD getValue() const = 0;
	virtual void setValue(LLSD value) = 0;
	virtual void set(LLSD value) = 0;

	// From LLSimpleListener
	virtual bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata);

	void firePropertyChanged();

	static U32	sMaxControlNameLength;

protected:
	const char* name()			{ return mName.c_str(); }
	const char* comment()		{ return mComment.c_str(); }
};

class LLControl
: public LLControlBase
{
friend class LLControlGroup;
protected:
	LLSD mCurrent;
	LLSD mDefault;

public:	

	typedef void	tListenerCallback(const LLSD&	newValue,S32	listenerID, LLControl& control);
	typedef struct{
		S32					mID;
		LLSD			mNewValue;
		tListenerCallback*	mCBFN;
	}tPropertyChangedEvent;

	typedef std::list<tPropertyChangedEvent>::iterator tPropertyChangedListIter;
	std::list<tPropertyChangedEvent>	mChangeEvents;
	std::list< tListenerCallback* >		mListeners;
	std::list< S32 >					mListenerIDs;

	virtual void						updateListeners();
	S32									addListener(tListenerCallback*	cbfn);
	
	LLControl(
		const LLString& name,
		eControlType type,
		LLSD initial, const
		LLString& comment,
		BOOL persist = TRUE);

	void set(LLSD val)			{ setValue(val); }
	LLSD get()			const	{ return getValue(); } 
	LLSD getdefault()	const	{ return mDefault; }
	LLSD getValue()		const	{ return mCurrent; }
	BOOL llsd_compare(const LLSD& a, const LLSD& b);

	void setValue(LLSD value)			
	{ 
		if (llsd_compare(mCurrent, value) == FALSE)
		{
			mCurrent = value; 
			mIsDefault = llsd_compare(mCurrent, mDefault); 
			firePropertyChanged(); 
		}
	}

	/*virtual*/ void resetToDefault() 
	{ 
		setValue(mDefault);
	}

	virtual	~LLControl()
	{
		//Remove and deregister all listeners..
		while(mListenerIDs.size())
		{
			S32	id = mListenerIDs.front();
			mListenerIDs.pop_front();
			releaseListenerID(id);
		}
	}
};

//const U32 STRING_CACHE_SIZE = 10000;
class LLControlGroup
{
public:
	typedef std::map<LLString, LLPointer<LLControlBase> > ctrl_name_table_t;
	ctrl_name_table_t mNameTable;
	std::set<LLString> mWarnings;
	std::set<LLString> mLoadedSettings;	// Filled in with names loaded from settings.xml

public:
	LLControlGroup();
	~LLControlGroup();
	void cleanup();
	bool hasLoaded(const LLString& name) { return mLoadedSettings.find(name) != mLoadedSettings.end(); }
	void clearLoaded() { mLoadedSettings.clear(); } // Call once we've done any settings tweaks which may need this data
	
	LLControlBase*	getControl(const LLString& name);
	LLSD registerListener(const LLString& name, LLSimpleListenerObservable *listener);
	
	BOOL declareControl(const LLString& name, eControlType type, const LLSD initial_val, const LLString& comment, BOOL persist);
	BOOL declareU32(const LLString& name, U32 initial_val, const LLString& comment, BOOL persist = TRUE);
	BOOL declareS32(const LLString& name, S32 initial_val, const LLString& comment, BOOL persist = TRUE);
	BOOL declareF32(const LLString& name, F32 initial_val, const LLString& comment, BOOL persist = TRUE);
	BOOL declareBOOL(const LLString& name, BOOL initial_val, const LLString& comment, BOOL persist = TRUE);
	BOOL declareString(const LLString& name, const LLString &initial_val, const LLString& comment, BOOL persist = TRUE);
	BOOL declareVec3(const LLString& name, const LLVector3 &initial_val,const LLString& comment,  BOOL persist = TRUE);
	BOOL declareVec3d(const LLString& name, const LLVector3d &initial_val, const LLString& comment, BOOL persist = TRUE);
	BOOL declareRect(const LLString& name, const LLRect &initial_val, const LLString& comment, BOOL persist = TRUE);
	BOOL declareColor4U(const LLString& name, const LLColor4U &initial_val, const LLString& comment, BOOL persist = TRUE);
	BOOL declareColor4(const LLString& name, const LLColor4 &initial_val, const LLString& comment, BOOL persist = TRUE);
	BOOL declareColor3(const LLString& name, const LLColor3 &initial_val, const LLString& comment, BOOL persist = TRUE);
	
	LLString 	findString(const LLString& name);

	LLString 	getString(const LLString& name);
	LLWString	getWString(const LLString& name);
	LLString	getText(const LLString& name);
	LLVector3	getVector3(const LLString& name);
	LLVector3d	getVector3d(const LLString& name);
	LLRect		getRect(const LLString& name);
	BOOL		getBOOL(const LLString& name);
	S32			getS32(const LLString& name);
	F32			getF32(const LLString& name);
	U32			getU32(const LLString& name);
	LLSD		getValue(const LLString& name);


	// Note: If an LLColor4U control exists, it will cast it to the correct
	// LLColor4 for you.
	LLColor4	getColor(const LLString& name);
	LLColor4U	getColor4U(const LLString& name);
	LLColor4	getColor4(const LLString& name);
	LLColor3	getColor3(const LLString& name);

	void	setBOOL(const LLString& name, BOOL val);
	void	setS32(const LLString& name, S32 val);
	void	setF32(const LLString& name, F32 val);
	void	setU32(const LLString& name, U32 val);
	void	setString(const LLString&  name, const LLString& val);
	void	setVector3(const LLString& name, const LLVector3 &val);
	void	setVector3d(const LLString& name, const LLVector3d &val);
	void	setRect(const LLString& name, const LLRect &val);
	void	setColor4U(const LLString& name, const LLColor4U &val);
	void	setColor4(const LLString& name, const LLColor4 &val);
	void	setColor3(const LLString& name, const LLColor3 &val);
	void	setValue(const LLString& name, const LLSD& val);

	BOOL    controlExists(const LLString& name);

	// Returns number of controls loaded, 0 if failed
	// If require_declaration is false, will auto-declare controls it finds
	// as the given type.
	U32		loadFromFileLegacy(const LLString& filename, BOOL require_declaration = TRUE, eControlType declare_as = TYPE_STRING);
	U32		loadFromFile(const LLString& filename, BOOL require_declaration = TRUE, eControlType declare_as = TYPE_STRING);
	U32		saveToFile(const LLString& filename, BOOL skip_if_default);
	void	applyOverrides(const std::map<std::string, std::string>& overrides);
	void	resetToDefaults();

	// Ignorable Warnings
	
	// Add a config variable to be reset on resetWarnings()
	void addWarning(const LLString& name);
	BOOL getWarning(const LLString& name);
	void setWarning(const LLString& name, BOOL val);
	
	// Resets all ignorables
	void resetWarnings();
};

#endif