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
|