aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llxml
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:45:42 -0500
committerJacek Antonelli2008-08-15 23:45:42 -0500
commitce28e056c20bf2723f565bbf464b87781ec248a2 (patch)
treeef7b0501c4de4b631a916305cbc2a5fdc125e52d /linden/indra/llxml
parentSecond Life viewer sources 1.19.1.4b (diff)
downloadmeta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.zip
meta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.tar.gz
meta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.tar.bz2
meta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.tar.xz
Second Life viewer sources 1.20.2
Diffstat (limited to 'linden/indra/llxml')
-rw-r--r--linden/indra/llxml/llcontrol.cpp817
-rw-r--r--linden/indra/llxml/llcontrol.h210
2 files changed, 328 insertions, 699 deletions
diff --git a/linden/indra/llxml/llcontrol.cpp b/linden/indra/llxml/llcontrol.cpp
index 5504a10..18292d2 100644
--- a/linden/indra/llxml/llcontrol.cpp
+++ b/linden/indra/llxml/llcontrol.cpp
@@ -39,7 +39,6 @@
39 39
40#include "llstl.h" 40#include "llstl.h"
41 41
42#include "linked_lists.h"
43#include "llstring.h" 42#include "llstring.h"
44#include "v3math.h" 43#include "v3math.h"
45#include "v3dmath.h" 44#include "v3dmath.h"
@@ -57,19 +56,9 @@
57#endif 56#endif
58 57
59//this defines the current version of the settings file 58//this defines the current version of the settings file
60U32 LLControlBase::sMaxControlNameLength = 0;
61
62//These lists are used to store the ID's of registered event listeners.
63std::list<S32> LLControlBase::mFreeIDs;
64std::list<S32> LLControlBase::mUsedIDs;
65
66S32 LLControlBase::mTopID;
67
68std::set<LLControlBase*> LLControlBase::mChangedControls;
69
70const S32 CURRENT_VERSION = 101; 59const S32 CURRENT_VERSION = 101;
71 60
72BOOL LLControl::llsd_compare(const LLSD& a, const LLSD & b) 61BOOL LLControlVariable::llsd_compare(const LLSD& a, const LLSD & b)
73{ 62{
74 switch (mType) 63 switch (mType)
75 { 64 {
@@ -101,58 +90,154 @@ BOOL LLControl::llsd_compare(const LLSD& a, const LLSD & b)
101 return FALSE; 90 return FALSE;
102} 91}
103 92
104LLControlBase::~LLControlBase() 93LLControlVariable::LLControlVariable(const LLString& name, eControlType type,
94 LLSD initial, const LLString& comment,
95 BOOL persist)
96 : mName(name),
97 mComment(comment),
98 mType(type),
99 mPersist(persist)
100{
101 if (mPersist && mComment.empty())
102 {
103 llerrs << "Must supply a comment for control " << mName << llendl;
104 }
105 //Push back versus setValue'ing here, since we don't want to call a signal yet
106 mValues.push_back(initial);
107}
108
109
110
111LLControlVariable::~LLControlVariable()
112{
113}
114
115void LLControlVariable::setValue(const LLSD& value, bool saved_value)
105{ 116{
117 bool value_changed = llsd_compare(getValue(), value) == FALSE;
118 if(saved_value)
119 {
120 // If we're going to save this value, return to default but don't fire
121 resetToDefault(false);
122 if (llsd_compare(mValues.back(), value) == FALSE)
123 {
124 mValues.push_back(value);
125 }
126 }
127 else
128 {
129 // This is a unsaved value. Its needs to reside at
130 // mValues[2] (or greater). It must not affect
131 // the result of getSaveValue()
132 if (llsd_compare(mValues.back(), value) == FALSE)
133 {
134 while(mValues.size() > 2)
135 {
136 // Remove any unsaved values.
137 mValues.pop_back();
138 }
139
140 if(mValues.size() < 2)
141 {
142 // Add the default to the 'save' value.
143 mValues.push_back(mValues[0]);
144 }
145
146 // Add the 'un-save' value.
147 mValues.push_back(value);
148 }
149 }
150
151 if(value_changed)
152 {
153 mSignal(value);
154 }
106} 155}
107 156
108// virtual 157void LLControlVariable::resetToDefault(bool fire_signal)
109void LLControlBase::resetToDefault()
110{ 158{
159 //The first setting is always the default
160 //Pop to it and fire off the listener
161 while(mValues.size() > 1) mValues.pop_back();
162 if(fire_signal) firePropertyChanged();
163}
164
165bool LLControlVariable::isSaveValueDefault()
166{
167 return (mValues.size() == 1)
168 || ((mValues.size() > 1) && llsd_compare(mValues[1], mValues[0]));
111} 169}
112 170
113LLControlGroup::LLControlGroup(): mNameTable() 171LLSD LLControlVariable::getSaveValue() const
114{ 172{
115 //mFreeStringOffset = 0; 173 //The first level of the stack is default
174 //We assume that the second level is user preferences that should be saved
175 if(mValues.size() > 1) return mValues[1];
176 return mValues[0];
116} 177}
117 178
118LLControlGroup::~LLControlGroup() 179LLControlVariable* LLControlGroup::getControl(const LLString& name)
180{
181 ctrl_name_table_t::iterator iter = mNameTable.find(name);
182 return iter == mNameTable.end() ? NULL : iter->second;
183}
184
185
186////////////////////////////////////////////////////////////////////////////
187
188LLControlGroup::LLControlGroup()
119{ 189{
190 mTypeString[TYPE_U32] = "U32";
191 mTypeString[TYPE_S32] = "S32";
192 mTypeString[TYPE_F32] = "F32";
193 mTypeString[TYPE_BOOLEAN] = "Boolean";
194 mTypeString[TYPE_STRING] = "String";
195 mTypeString[TYPE_VEC3] = "Vector3";
196 mTypeString[TYPE_VEC3D] = "Vector3D";
197 mTypeString[TYPE_RECT] = "Rect";
198 mTypeString[TYPE_COL4] = "Color4";
199 mTypeString[TYPE_COL3] = "Color3";
200 mTypeString[TYPE_COL4U] = "Color4u";
201 mTypeString[TYPE_LLSD] = "LLSD";
120} 202}
121 203
122LLSD LLControlBase::registerListener(LLSimpleListenerObservable *listener, LLSD userdata) 204LLControlGroup::~LLControlGroup()
123{ 205{
124 // Symmetric listener relationship 206 cleanup();
125 addListener(listener, "", userdata);
126 listener->addListener(this, "", userdata);
127 return getValue();
128} 207}
129 208
130void LLControlGroup::cleanup() 209void LLControlGroup::cleanup()
131{ 210{
211 for_each(mNameTable.begin(), mNameTable.end(), DeletePairedPointer());
132 mNameTable.clear(); 212 mNameTable.clear();
133} 213}
134 214
135LLControlBase* LLControlGroup::getControl(const LLString& name) 215eControlType LLControlGroup::typeStringToEnum(const LLString& typestr)
136{ 216{
137 ctrl_name_table_t::iterator iter = mNameTable.find(name); 217 for(int i = 0; i < (int)TYPE_COUNT; ++i)
138 return iter == mNameTable.end() ? NULL : (LLControlBase*)iter->second; 218 {
219 if(mTypeString[i] == typestr) return (eControlType)i;
220 }
221 return (eControlType)-1;
222}
223
224LLString LLControlGroup::typeEnumToString(eControlType typeenum)
225{
226 return mTypeString[typeenum];
139} 227}
140 228
141BOOL LLControlGroup::declareControl(const LLString& name, eControlType type, const LLSD initial_val, const LLString& comment, BOOL persist) 229BOOL LLControlGroup::declareControl(const LLString& name, eControlType type, const LLSD initial_val, const LLString& comment, BOOL persist)
142{ 230{
143 if(!mNameTable[name]) 231 if(mNameTable.find(name) != mNameTable.end())
144 {
145 // if not, create the control and add it to the name table
146 LLControl* control = new LLControl(name, type, initial_val, comment, persist);
147 mNameTable[name] = control;
148 return TRUE;
149 }
150 else
151 { 232 {
152 llwarns << "LLControlGroup::declareControl: Control named " << name << " already exists." << llendl; 233 llwarns << "LLControlGroup::declareControl: Control named " << name << " already exists." << llendl;
153 mNameTable.erase(name); 234 mNameTable[name]->setValue(initial_val);
154 return FALSE; 235 return TRUE;
155 } 236 }
237 // if not, create the control and add it to the name table
238 LLControlVariable* control = new LLControlVariable(name, type, initial_val, comment, persist);
239 mNameTable[name] = control;
240 return TRUE;
156} 241}
157 242
158BOOL LLControlGroup::declareU32(const LLString& name, const U32 initial_val, const LLString& comment, BOOL persist) 243BOOL LLControlGroup::declareU32(const LLString& name, const U32 initial_val, const LLString& comment, BOOL persist)
@@ -210,19 +295,14 @@ BOOL LLControlGroup::declareColor3(const LLString& name, const LLColor3 &initial
210 return declareControl(name, TYPE_COL3, initial_val.getValue(), comment, persist); 295 return declareControl(name, TYPE_COL3, initial_val.getValue(), comment, persist);
211} 296}
212 297
213LLSD LLControlGroup::registerListener(const LLString& name, LLSimpleListenerObservable *listener) 298BOOL LLControlGroup::declareLLSD(const LLString& name, const LLSD &initial_val, const LLString& comment, BOOL persist )
214{ 299{
215 LLControlBase *control = getControl(name); 300 return declareControl(name, TYPE_LLSD, initial_val, comment, persist);
216 if (control)
217 {
218 return control->registerListener(listener);
219 }
220 return LLSD();
221} 301}
222 302
223BOOL LLControlGroup::getBOOL(const LLString& name) 303BOOL LLControlGroup::getBOOL(const LLString& name)
224{ 304{
225 LLControlBase* control = getControl(name); 305 LLControlVariable* control = getControl(name);
226 306
227 if (control && control->isType(TYPE_BOOLEAN)) 307 if (control && control->isType(TYPE_BOOLEAN))
228 return control->get().asBoolean(); 308 return control->get().asBoolean();
@@ -235,7 +315,7 @@ BOOL LLControlGroup::getBOOL(const LLString& name)
235 315
236S32 LLControlGroup::getS32(const LLString& name) 316S32 LLControlGroup::getS32(const LLString& name)
237{ 317{
238 LLControlBase* control = getControl(name); 318 LLControlVariable* control = getControl(name);
239 319
240 if (control && control->isType(TYPE_S32)) 320 if (control && control->isType(TYPE_S32))
241 return control->get().asInteger(); 321 return control->get().asInteger();
@@ -248,7 +328,7 @@ S32 LLControlGroup::getS32(const LLString& name)
248 328
249U32 LLControlGroup::getU32(const LLString& name) 329U32 LLControlGroup::getU32(const LLString& name)
250{ 330{
251 LLControlBase* control = getControl(name); 331 LLControlVariable* control = getControl(name);
252 332
253 if (control && control->isType(TYPE_U32)) 333 if (control && control->isType(TYPE_U32))
254 return control->get().asInteger(); 334 return control->get().asInteger();
@@ -261,7 +341,7 @@ U32 LLControlGroup::getU32(const LLString& name)
261 341
262F32 LLControlGroup::getF32(const LLString& name) 342F32 LLControlGroup::getF32(const LLString& name)
263{ 343{
264 LLControlBase* control = getControl(name); 344 LLControlVariable* control = getControl(name);
265 345
266 if (control && control->isType(TYPE_F32)) 346 if (control && control->isType(TYPE_F32))
267 return (F32) control->get().asReal(); 347 return (F32) control->get().asReal();
@@ -274,7 +354,7 @@ F32 LLControlGroup::getF32(const LLString& name)
274 354
275LLString LLControlGroup::findString(const LLString& name) 355LLString LLControlGroup::findString(const LLString& name)
276{ 356{
277 LLControlBase* control = getControl(name); 357 LLControlVariable* control = getControl(name);
278 358
279 if (control && control->isType(TYPE_STRING)) 359 if (control && control->isType(TYPE_STRING))
280 return control->get().asString(); 360 return control->get().asString();
@@ -283,7 +363,7 @@ LLString LLControlGroup::findString(const LLString& name)
283 363
284LLString LLControlGroup::getString(const LLString& name) 364LLString LLControlGroup::getString(const LLString& name)
285{ 365{
286 LLControlBase* control = getControl(name); 366 LLControlVariable* control = getControl(name);
287 367
288 if (control && control->isType(TYPE_STRING)) 368 if (control && control->isType(TYPE_STRING))
289 return control->get().asString(); 369 return control->get().asString();
@@ -309,7 +389,7 @@ LLString LLControlGroup::getText(const LLString& name)
309 389
310LLVector3 LLControlGroup::getVector3(const LLString& name) 390LLVector3 LLControlGroup::getVector3(const LLString& name)
311{ 391{
312 LLControlBase* control = getControl(name); 392 LLControlVariable* control = getControl(name);
313 393
314 if (control && control->isType(TYPE_VEC3)) 394 if (control && control->isType(TYPE_VEC3))
315 return control->get(); 395 return control->get();
@@ -322,7 +402,7 @@ LLVector3 LLControlGroup::getVector3(const LLString& name)
322 402
323LLVector3d LLControlGroup::getVector3d(const LLString& name) 403LLVector3d LLControlGroup::getVector3d(const LLString& name)
324{ 404{
325 LLControlBase* control = getControl(name); 405 LLControlVariable* control = getControl(name);
326 406
327 if (control && control->isType(TYPE_VEC3D)) 407 if (control && control->isType(TYPE_VEC3D))
328 return control->get(); 408 return control->get();
@@ -335,7 +415,7 @@ LLVector3d LLControlGroup::getVector3d(const LLString& name)
335 415
336LLRect LLControlGroup::getRect(const LLString& name) 416LLRect LLControlGroup::getRect(const LLString& name)
337{ 417{
338 LLControlBase* control = getControl(name); 418 LLControlVariable* control = getControl(name);
339 419
340 if (control && control->isType(TYPE_RECT)) 420 if (control && control->isType(TYPE_RECT))
341 return control->get(); 421 return control->get();
@@ -353,7 +433,7 @@ LLColor4 LLControlGroup::getColor(const LLString& name)
353 433
354 if (i != mNameTable.end()) 434 if (i != mNameTable.end())
355 { 435 {
356 LLControlBase* control = i->second; 436 LLControlVariable* control = i->second;
357 437
358 switch(control->mType) 438 switch(control->mType)
359 { 439 {
@@ -381,7 +461,7 @@ LLColor4 LLControlGroup::getColor(const LLString& name)
381 461
382LLColor4U LLControlGroup::getColor4U(const LLString& name) 462LLColor4U LLControlGroup::getColor4U(const LLString& name)
383{ 463{
384 LLControlBase* control = getControl(name); 464 LLControlVariable* control = getControl(name);
385 465
386 if (control && control->isType(TYPE_COL4U)) 466 if (control && control->isType(TYPE_COL4U))
387 return control->get(); 467 return control->get();
@@ -394,7 +474,7 @@ LLColor4U LLControlGroup::getColor4U(const LLString& name)
394 474
395LLColor4 LLControlGroup::getColor4(const LLString& name) 475LLColor4 LLControlGroup::getColor4(const LLString& name)
396{ 476{
397 LLControlBase* control = getControl(name); 477 LLControlVariable* control = getControl(name);
398 478
399 if (control && control->isType(TYPE_COL4)) 479 if (control && control->isType(TYPE_COL4))
400 return control->get(); 480 return control->get();
@@ -407,7 +487,7 @@ LLColor4 LLControlGroup::getColor4(const LLString& name)
407 487
408LLColor3 LLControlGroup::getColor3(const LLString& name) 488LLColor3 LLControlGroup::getColor3(const LLString& name)
409{ 489{
410 LLControlBase* control = getControl(name); 490 LLControlVariable* control = getControl(name);
411 491
412 if (control && control->isType(TYPE_COL3)) 492 if (control && control->isType(TYPE_COL3))
413 return control->get(); 493 return control->get();
@@ -418,6 +498,16 @@ LLColor3 LLControlGroup::getColor3(const LLString& name)
418 } 498 }
419} 499}
420 500
501LLSD LLControlGroup::getLLSD(const LLString& name)
502{
503 LLControlVariable* control = getControl(name);
504
505 if (control && control->isType(TYPE_LLSD))
506 return control->getValue();
507 CONTROL_ERRS << "Invalid LLSD control " << name << llendl;
508 return LLSD();
509}
510
421BOOL LLControlGroup::controlExists(const LLString& name) 511BOOL LLControlGroup::controlExists(const LLString& name)
422{ 512{
423 ctrl_name_table_t::iterator iter = mNameTable.find(name); 513 ctrl_name_table_t::iterator iter = mNameTable.find(name);
@@ -430,7 +520,7 @@ BOOL LLControlGroup::controlExists(const LLString& name)
430 520
431void LLControlGroup::setBOOL(const LLString& name, BOOL val) 521void LLControlGroup::setBOOL(const LLString& name, BOOL val)
432{ 522{
433 LLControlBase* control = getControl(name); 523 LLControlVariable* control = getControl(name);
434 524
435 if (control && control->isType(TYPE_BOOLEAN)) 525 if (control && control->isType(TYPE_BOOLEAN))
436 { 526 {
@@ -445,7 +535,7 @@ void LLControlGroup::setBOOL(const LLString& name, BOOL val)
445 535
446void LLControlGroup::setS32(const LLString& name, S32 val) 536void LLControlGroup::setS32(const LLString& name, S32 val)
447{ 537{
448 LLControlBase* control = getControl(name); 538 LLControlVariable* control = getControl(name);
449 539
450 if (control && control->isType(TYPE_S32)) 540 if (control && control->isType(TYPE_S32))
451 { 541 {
@@ -460,7 +550,7 @@ void LLControlGroup::setS32(const LLString& name, S32 val)
460 550
461void LLControlGroup::setF32(const LLString& name, F32 val) 551void LLControlGroup::setF32(const LLString& name, F32 val)
462{ 552{
463 LLControlBase* control = getControl(name); 553 LLControlVariable* control = getControl(name);
464 554
465 if (control && control->isType(TYPE_F32)) 555 if (control && control->isType(TYPE_F32))
466 { 556 {
@@ -475,7 +565,7 @@ void LLControlGroup::setF32(const LLString& name, F32 val)
475 565
476void LLControlGroup::setU32(const LLString& name, U32 val) 566void LLControlGroup::setU32(const LLString& name, U32 val)
477{ 567{
478 LLControlBase* control = getControl(name); 568 LLControlVariable* control = getControl(name);
479 569
480 if (control && control->isType(TYPE_U32)) 570 if (control && control->isType(TYPE_U32))
481 { 571 {
@@ -490,7 +580,7 @@ void LLControlGroup::setU32(const LLString& name, U32 val)
490 580
491void LLControlGroup::setString(const LLString& name, const LLString &val) 581void LLControlGroup::setString(const LLString& name, const LLString &val)
492{ 582{
493 LLControlBase* control = getControl(name); 583 LLControlVariable* control = getControl(name);
494 584
495 if (control && control->isType(TYPE_STRING)) 585 if (control && control->isType(TYPE_STRING))
496 { 586 {
@@ -505,7 +595,7 @@ void LLControlGroup::setString(const LLString& name, const LLString &val)
505 595
506void LLControlGroup::setVector3(const LLString& name, const LLVector3 &val) 596void LLControlGroup::setVector3(const LLString& name, const LLVector3 &val)
507{ 597{
508 LLControlBase* control = getControl(name); 598 LLControlVariable* control = getControl(name);
509 599
510 if (control && control->isType(TYPE_VEC3)) 600 if (control && control->isType(TYPE_VEC3))
511 { 601 {
@@ -519,7 +609,7 @@ void LLControlGroup::setVector3(const LLString& name, const LLVector3 &val)
519 609
520void LLControlGroup::setVector3d(const LLString& name, const LLVector3d &val) 610void LLControlGroup::setVector3d(const LLString& name, const LLVector3d &val)
521{ 611{
522 LLControlBase* control = getControl(name); 612 LLControlVariable* control = getControl(name);
523 613
524 if (control && control->isType(TYPE_VEC3D)) 614 if (control && control->isType(TYPE_VEC3D))
525 { 615 {
@@ -533,7 +623,7 @@ void LLControlGroup::setVector3d(const LLString& name, const LLVector3d &val)
533 623
534void LLControlGroup::setRect(const LLString& name, const LLRect &val) 624void LLControlGroup::setRect(const LLString& name, const LLRect &val)
535{ 625{
536 LLControlBase* control = getControl(name); 626 LLControlVariable* control = getControl(name);
537 627
538 if (control && control->isType(TYPE_RECT)) 628 if (control && control->isType(TYPE_RECT))
539 { 629 {
@@ -547,7 +637,7 @@ void LLControlGroup::setRect(const LLString& name, const LLRect &val)
547 637
548void LLControlGroup::setColor4U(const LLString& name, const LLColor4U &val) 638void LLControlGroup::setColor4U(const LLString& name, const LLColor4U &val)
549{ 639{
550 LLControlBase* control = getControl(name); 640 LLControlVariable* control = getControl(name);
551 641
552 if (control && control->isType(TYPE_COL4U)) 642 if (control && control->isType(TYPE_COL4U))
553 { 643 {
@@ -561,7 +651,7 @@ void LLControlGroup::setColor4U(const LLString& name, const LLColor4U &val)
561 651
562void LLControlGroup::setColor4(const LLString& name, const LLColor4 &val) 652void LLControlGroup::setColor4(const LLString& name, const LLColor4 &val)
563{ 653{
564 LLControlBase* control = getControl(name); 654 LLControlVariable* control = getControl(name);
565 655
566 if (control && control->isType(TYPE_COL4)) 656 if (control && control->isType(TYPE_COL4))
567 { 657 {
@@ -573,6 +663,20 @@ void LLControlGroup::setColor4(const LLString& name, const LLColor4 &val)
573 } 663 }
574} 664}
575 665
666void LLControlGroup::setLLSD(const LLString& name, const LLSD& val)
667{
668 LLControlVariable* control = getControl(name);
669
670 if (control && control->isType(TYPE_LLSD))
671 {
672 setValue(name, val);
673 }
674 else
675 {
676 CONTROL_ERRS << "Invalid LLSD control " << name << llendl;
677 }
678}
679
576void LLControlGroup::setValue(const LLString& name, const LLSD& val) 680void LLControlGroup::setValue(const LLString& name, const LLSD& val)
577{ 681{
578 if (name.empty()) 682 if (name.empty())
@@ -580,7 +684,7 @@ void LLControlGroup::setValue(const LLString& name, const LLSD& val)
580 return; 684 return;
581 } 685 }
582 686
583 LLControlBase* control = getControl(name); 687 LLControlVariable* control = getControl(name);
584 688
585 if (control) 689 if (control)
586 { 690 {
@@ -596,238 +700,8 @@ void LLControlGroup::setValue(const LLString& name, const LLSD& val)
596// Load and save 700// Load and save
597//--------------------------------------------------------------- 701//---------------------------------------------------------------
598 702
599U32 LLControlGroup::loadFromFileLegacy(const LLString& filename, BOOL require_declaration, eControlType declare_as)
600{
601 U32 item = 0;
602 U32 validitems = 0;
603 llifstream file;
604 S32 version;
605
606 file.open(filename.c_str()); /*Flawfinder: ignore*/
607
608 if (!file)
609 {
610 llinfos << "LLControlGroup::loadFromFile unable to open." << llendl;
611 return 0;
612 }
613
614 // Check file version
615 LLString name;
616 file >> name;
617 file >> version;
618 if (name != "version" || version != CURRENT_VERSION)
619 {
620 llinfos << filename << " does not appear to be a version " << CURRENT_VERSION << " controls file" << llendl;
621 return 0;
622 }
623
624 while (!file.eof())
625 {
626 file >> name;
627
628 if (name.empty())
629 {
630 continue;
631 }
632
633 if (name.substr(0,2) == "//")
634 {
635 // This is a comment.
636 char buffer[MAX_STRING]; /*Flawfinder: ignore*/
637 file.getline(buffer, MAX_STRING);
638 continue;
639 }
640
641 BOOL declared = mNameTable.find(name) != mNameTable.end();
642
643 if (require_declaration && !declared)
644 {
645 // Declaration required, but this name not declared.
646 // Complain about non-empty names.
647 if (!name.empty())
648 {
649 //read in to end of line
650 char buffer[MAX_STRING]; /*Flawfinder: ignore*/
651 file.getline(buffer, MAX_STRING);
652 llwarns << "LLControlGroup::loadFromFile() : Trying to set \"" << name << "\", setting doesn't exist." << llendl;
653 }
654 continue;
655 }
656
657 // Got an item. Load it up.
658 item++;
659
660 // If not declared, assume it's a string
661 if (!declared)
662 {
663 switch(declare_as)
664 {
665 case TYPE_COL4:
666 declareColor4(name, LLColor4::white, LLString::null, NO_PERSIST);
667 break;
668 case TYPE_COL4U:
669 declareColor4U(name, LLColor4U::white, LLString::null, NO_PERSIST);
670 break;
671 case TYPE_STRING:
672 default:
673 declareString(name, LLString::null, LLString::null, NO_PERSIST);
674 break;
675 }
676 }
677
678 // Control name has been declared in code.
679 LLControlBase *control = getControl(name);
680
681 llassert(control);
682
683 mLoadedSettings.insert(name);
684
685 switch(control->mType)
686 {
687 case TYPE_F32:
688 {
689 F32 initial;
690
691 file >> initial;
692
693 control->set(initial);
694 validitems++;
695 }
696 break;
697 case TYPE_S32:
698 {
699 S32 initial;
700
701 file >> initial;
702
703 control->set(initial);
704 validitems++;
705 }
706 break;
707 case TYPE_U32:
708 {
709 U32 initial;
710
711 file >> initial;
712 control->set((LLSD::Integer) initial);
713 validitems++;
714 }
715 break;
716 case TYPE_BOOLEAN:
717 {
718 char boolstring[256]; /*Flawfinder: ignore*/
719 BOOL valid = FALSE;
720 BOOL initial = FALSE;
721
722 file >> boolstring;
723 if (!strcmp("TRUE", boolstring))
724 {
725 initial = TRUE;
726 valid = TRUE;
727 }
728 else if (!strcmp("FALSE", boolstring))
729 {
730 initial = FALSE;
731 valid = TRUE;
732 }
733
734 if (valid)
735 {
736 control->set(initial);
737 }
738 else
739 {
740 llinfos << filename << "Item " << item << ": Invalid BOOL control " << name << ", " << boolstring << llendl;
741 }
742
743 validitems++;
744 }
745 break;
746 case TYPE_STRING:
747 {
748 LLString string;
749
750 file >> string;
751
752 control->set(string);
753 validitems++;
754 }
755 break;
756 case TYPE_VEC3:
757 {
758 F32 x, y, z;
759
760 file >> x >> y >> z;
761
762 LLVector3 vector(x, y, z);
763
764 control->set(vector.getValue());
765 validitems++;
766 }
767 break;
768 case TYPE_VEC3D:
769 {
770 F64 x, y, z;
771
772 file >> x >> y >> z;
773
774 LLVector3d vector(x, y, z);
775
776 control->set(vector.getValue());
777 validitems++;
778 }
779 break;
780 case TYPE_RECT:
781 {
782 S32 left, bottom, width, height;
783
784 file >> left >> bottom >> width >> height;
785
786 LLRect rect;
787 rect.setOriginAndSize(left, bottom, width, height);
788
789 control->set(rect.getValue());
790 validitems++;
791 }
792 break;
793 case TYPE_COL4U:
794 {
795 S32 red, green, blue, alpha;
796 LLColor4U color;
797 file >> red >> green >> blue >> alpha;
798 color.setVec(red, green, blue, alpha);
799 control->set(color.getValue());
800 validitems++;
801 }
802 break;
803 case TYPE_COL4:
804 {
805 LLColor4 color;
806 file >> color.mV[VRED] >> color.mV[VGREEN]
807 >> color.mV[VBLUE] >> color.mV[VALPHA];
808 control->set(color.getValue());
809 validitems++;
810 }
811 break;
812 case TYPE_COL3:
813 {
814 LLColor3 color;
815 file >> color.mV[VRED] >> color.mV[VGREEN]
816 >> color.mV[VBLUE];
817 control->set(color.getValue());
818 validitems++;
819 }
820 break;
821 }
822 }
823
824 file.close();
825
826 return validitems;
827}
828
829// Returns number of controls loaded, so 0 if failure 703// Returns number of controls loaded, so 0 if failure
830U32 LLControlGroup::loadFromFile(const LLString& filename, BOOL require_declaration, eControlType declare_as) 704U32 LLControlGroup::loadFromFileLegacy(const LLString& filename, BOOL require_declaration, eControlType declare_as)
831{ 705{
832 LLString name; 706 LLString name;
833 707
@@ -901,11 +775,9 @@ U32 LLControlGroup::loadFromFile(const LLString& filename, BOOL require_declarat
901 } 775 }
902 776
903 // Control name has been declared in code. 777 // Control name has been declared in code.
904 LLControlBase *control = getControl(name); 778 LLControlVariable *control = getControl(name);
905 779
906 llassert(control); 780 llassert(control);
907
908 mLoadedSettings.insert(name);
909 781
910 switch(control->mType) 782 switch(control->mType)
911 { 783 {
@@ -1019,59 +891,43 @@ U32 LLControlGroup::loadFromFile(const LLString& filename, BOOL require_declarat
1019 LLVector3 color; 891 LLVector3 color;
1020 892
1021 child_nodep->getAttributeVector3("value", color); 893 child_nodep->getAttributeVector3("value", color);
1022 control->set(LLColor3(color.mV).getValue()); 894 control->set(LLColor3(color.mV).getValue());
1023 validitems++; 895 validitems++;
1024 } 896 }
1025 break; 897 break;
1026 }
1027 898
899 default:
900 break;
901
902 }
903
1028 child_nodep = rootp->getNextChild(); 904 child_nodep = rootp->getNextChild();
1029 } 905 }
1030 906
1031 return validitems; 907 return validitems;
1032} 908}
1033 909
1034struct compare_controls
1035{
1036 bool operator() (const LLControlBase* const a, const LLControlBase* const b) const
1037 {
1038 return a->getName() < b->getName();
1039 }
1040};
1041
1042U32 LLControlGroup::saveToFile(const LLString& filename, BOOL nondefault_only) 910U32 LLControlGroup::saveToFile(const LLString& filename, BOOL nondefault_only)
1043{ 911{
1044 const char ENDL = '\n'; 912 LLSD settings;
1045 913 int num_saved = 0;
1046 llinfos << "Saving settings to file: " << filename << llendl;
1047
1048 // place the objects in a temporary container that enforces a sort
1049 // order to ease manual editing of the file
1050
1051 typedef std::set< LLControlBase*, compare_controls > control_list_t;
1052 control_list_t controls;
1053
1054 for (ctrl_name_table_t::iterator iter = mNameTable.begin(); 914 for (ctrl_name_table_t::iterator iter = mNameTable.begin();
1055 iter != mNameTable.end(); iter++) 915 iter != mNameTable.end(); iter++)
1056 { 916 {
1057 LLString name = iter->first; 917 LLControlVariable* control = iter->second;
1058 if (name.empty())
1059 {
1060 CONTROL_ERRS << "Control with no name found!!!" << llendl;
1061 break;
1062 }
1063
1064 LLControlBase* control = (LLControlBase *)iter->second;
1065 if (!control) 918 if (!control)
1066 { 919 {
1067 llwarns << "Tried to save invalid control: " << name << llendl; 920 llwarns << "Tried to save invalid control: " << iter->first << llendl;
1068 } 921 }
1069 922
1070 if( control && control->mPersist ) 923 if( control && control->isPersisted() )
1071 { 924 {
1072 if (!(nondefault_only && (control->mIsDefault))) 925 if (!(nondefault_only && (control->isSaveValueDefault())))
1073 { 926 {
1074 controls.insert( control ); 927 settings[iter->first]["Type"] = typeEnumToString(control->type());
928 settings[iter->first]["Comment"] = control->getComment();
929 settings[iter->first]["Value"] = control->getSaveValue();
930 ++num_saved;
1075 } 931 }
1076 else 932 else
1077 { 933 {
@@ -1080,156 +936,58 @@ U32 LLControlGroup::saveToFile(const LLString& filename, BOOL nondefault_only)
1080 } 936 }
1081 } 937 }
1082 } 938 }
1083
1084 llofstream file; 939 llofstream file;
1085 file.open(filename.c_str()); /*Flawfinder: ignore*/ 940 file.open(filename.c_str());
1086 941 if (file.is_open())
1087 if (!file.is_open())
1088 { 942 {
1089 // This is a warning because sometime we want to use settings files which can't be written... 943 LLSDSerialize::toPrettyXML(settings, file);
1090 llwarns << "LLControlGroup::saveToFile unable to open file for writing" << llendl; 944 file.close();
1091 return 0; 945 llinfos << "Saved to " << filename << llendl;
1092 } 946 }
1093 947 else
1094 // Write file version
1095 file << "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>\n";
1096 file << "<settings version = \"" << CURRENT_VERSION << "\">\n";
1097 for (control_list_t::iterator iter = controls.begin();
1098 iter != controls.end(); ++iter)
1099 { 948 {
1100 LLControlBase* control = *iter; 949 // This is a warning because sometime we want to use settings files which can't be written...
1101 file << "\t<!--" << control->comment() << "-->" << ENDL; 950 llwarns << "Unable to open settings file: " << filename << llendl;
1102 LLString name = control->getName(); 951 return 0;
1103 switch (control->type()) 952 }
1104 { 953 return num_saved;
1105 case TYPE_U32:
1106 {
1107 file << "\t<" << name << " value=\"" << (U32) control->get().asInteger() << "\"/>\n";
1108 break;
1109 }
1110 case TYPE_S32:
1111 {
1112 file << "\t<" << name << " value=\"" << (S32) control->get().asInteger() << "\"/>\n";
1113 break;
1114 }
1115 case TYPE_F32:
1116 {
1117 file << "\t<" << name << " value=\"" << (F32) control->get().asReal() << "\"/>\n";
1118 break;
1119 }
1120 case TYPE_VEC3:
1121 {
1122 LLVector3 vector(control->get());
1123 file << "\t<" << name << " value=\"" << vector.mV[VX] << " " << vector.mV[VY] << " " << vector.mV[VZ] << "\"/>\n";
1124 break;
1125 }
1126 case TYPE_VEC3D:
1127 {
1128 LLVector3d vector(control->get());
1129 file << "\t<" << name << " value=\"" << vector.mdV[VX] << " " << vector.mdV[VY] << " " << vector.mdV[VZ] << "\"/>\n";
1130 break;
1131 }
1132 case TYPE_RECT:
1133 {
1134 LLRect rect(control->get());
1135 file << "\t<" << name << " value=\"" << rect.mLeft << " " << rect.mBottom << " " << rect.getWidth() << " " << rect.getHeight() << "\"/>\n";
1136 break;
1137 }
1138 case TYPE_COL4:
1139 {
1140 LLColor4 color(control->get());
1141 file << "\t<" << name << " value=\"" << color.mV[VRED] << ", " << color.mV[VGREEN] << ", " << color.mV[VBLUE] << ", " << color.mV[VALPHA] << "\"/>\n";
1142 break;
1143 }
1144 case TYPE_COL3:
1145 {
1146 LLColor3 color(control->get());
1147 file << "\t<" << name << " value=\"" << color.mV[VRED] << ", " << color.mV[VGREEN] << ", " << color.mV[VBLUE] << "\"/>\n";
1148 break;
1149 }
1150 case TYPE_BOOLEAN:
1151 {
1152 file << "\t<" << name << " value=\"" << (control->get().asBoolean() ? "TRUE" : "FALSE") << "\"/>\n";
1153 break;
1154 }
1155 case TYPE_STRING:
1156 {
1157 file << "\t<" << name << " value=\"" << LLSDXMLFormatter::escapeString(control->get().asString()) << "\"/>\n";
1158 break;
1159 }
1160 default:
1161 {
1162 CONTROL_ERRS << "LLControlGroup::saveToFile - unknown control type!" << llendl;
1163 break;
1164 }
1165 }
1166
1167 // Debug spam
1168 // llinfos << name << " " << control->getValue().asString() << llendl;
1169 }// next
1170
1171 file << "</settings>\n";
1172 file.close();
1173
1174 return controls.size();
1175} 954}
1176 955
1177void LLControlGroup::applyOverrides(const std::map<std::string, std::string>& overrides) 956U32 LLControlGroup::loadFromFile(const LLString& filename, BOOL require_declaration, eControlType declare_as)
1178{ 957{
1179 for (std::map<std::string, std::string>::const_iterator iter = overrides.begin(); 958 LLString name;
1180 iter != overrides.end(); ++iter) 959 LLSD settings;
960 LLSD control_map;
961 llifstream infile;
962 infile.open(filename.c_str());
963 if(!infile.is_open())
1181 { 964 {
1182 const std::string& command = iter->first; 965 llwarns << "Cannot find file " << filename << " to load." << llendl;
1183 const std::string& value = iter->second; 966 return 0;
1184 LLControlBase* control = (LLControlBase *)mNameTable[command]; 967 }
1185 if (control) 968 S32 ret = LLSDSerialize::fromXML(settings, infile);
1186 { 969 if (ret <= 0)
1187 switch(control->mType) 970 {
1188 { 971 infile.close();
1189 case TYPE_U32: 972 llwarns << "Unable to open LLSD control file " << filename << ". Trying Legacy Method." << llendl;
1190 control->set((LLSD::Integer)atof(value.c_str())); 973 return loadFromFileLegacy(filename, require_declaration, declare_as);
1191 break; 974 }
1192 case TYPE_S32: 975
1193 control->set((S32)atof(value.c_str())); 976 U32 validitems = 0;
1194 break; 977 int persist = 1;
1195 case TYPE_F32: 978 for(LLSD::map_const_iterator itr = settings.beginMap(); itr != settings.endMap(); ++itr)
1196 control->set((F32)atof(value.c_str())); 979 {
1197 break; 980 name = (*itr).first;
1198 case TYPE_BOOLEAN: 981 control_map = (*itr).second;
1199 if (!LLString::compareInsensitive(value.c_str(), "TRUE")) 982
1200 { 983 if(control_map.has("Persist")) persist = control_map["Persist"].asInteger();
1201 control->set(TRUE); 984
1202 } 985 declareControl(name, typeStringToEnum(control_map["Type"].asString()), control_map["Value"], control_map["Comment"].asString(), persist);
1203 else if (!LLString::compareInsensitive(value.c_str(), "FALSE")) 986
1204 { 987 ++validitems;
1205 control->set(FALSE);
1206 }
1207 else
1208 {
1209 control->set((BOOL)atof(value.c_str()));
1210 }
1211 break;
1212 case TYPE_STRING:
1213 control->set(value);
1214 break;
1215// // *FIX: implement this given time and need.
1216// case TYPE_UUID:
1217// break;
1218 // we don't support command line overrides of vec3 or col4
1219 // yet - requires parsing of multiple values
1220 case TYPE_VEC3:
1221 case TYPE_VEC3D:
1222 case TYPE_COL4:
1223 case TYPE_COL3:
1224 default:
1225 break;
1226 }
1227 }
1228 else
1229 {
1230 llinfos << "There is no control variable " << command << llendl;
1231 }
1232 } 988 }
989
990 return validitems;
1233} 991}
1234 992
1235void LLControlGroup::resetToDefaults() 993void LLControlGroup::resetToDefaults()
@@ -1239,11 +997,20 @@ void LLControlGroup::resetToDefaults()
1239 control_iter != mNameTable.end(); 997 control_iter != mNameTable.end();
1240 ++control_iter) 998 ++control_iter)
1241 { 999 {
1242 LLControlBase* control = (*control_iter).second; 1000 LLControlVariable* control = (*control_iter).second;
1243 control->resetToDefault(); 1001 control->resetToDefault();
1244 } 1002 }
1245} 1003}
1246 1004
1005void LLControlGroup::applyToAll(ApplyFunctor* func)
1006{
1007 for (ctrl_name_table_t::iterator iter = mNameTable.begin();
1008 iter != mNameTable.end(); iter++)
1009 {
1010 func->apply(iter->first, iter->second);
1011 }
1012}
1013
1247//============================================================================ 1014//============================================================================
1248// First-use 1015// First-use
1249 1016
@@ -1264,7 +1031,7 @@ static LLString get_warn_name(const LLString& name)
1264void LLControlGroup::addWarning(const LLString& name) 1031void LLControlGroup::addWarning(const LLString& name)
1265{ 1032{
1266 LLString warnname = get_warn_name(name); 1033 LLString warnname = get_warn_name(name);
1267 if(!mNameTable[warnname]) 1034 if(mNameTable.find(warnname) == mNameTable.end())
1268 { 1035 {
1269 LLString comment = LLString("Enables ") + name + LLString(" warning dialog"); 1036 LLString comment = LLString("Enables ") + name + LLString(" warning dialog");
1270 declareBOOL(warnname, TRUE, comment); 1037 declareBOOL(warnname, TRUE, comment);
@@ -1293,91 +1060,6 @@ void LLControlGroup::resetWarnings()
1293 } 1060 }
1294} 1061}
1295 1062
1296
1297
1298//=============================================================================
1299// Listener ID generator/management
1300
1301void LLControlBase::releaseListenerID(S32 id)
1302{
1303 mFreeIDs.push_back(id);
1304}
1305
1306S32 LLControlBase::allocateListenerID()
1307{
1308 if(mFreeIDs.size() == 0)
1309 { //Out of IDs so generate some new ones.
1310 for(int t=0;t<32;t++)
1311 {
1312 mFreeIDs.push_back(mTopID++);
1313 }
1314 }
1315 S32 rtn = mFreeIDs.front();
1316 mFreeIDs.pop_front();
1317 mUsedIDs.push_back(rtn);
1318 return rtn;
1319}
1320
1321bool LLControlBase::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1322{
1323 if (event->desc() == "value_changed")
1324 {
1325 setValue(((LLValueChangedEvent*)(LLEvent*)event)->mValue);
1326 return TRUE;
1327 }
1328 return TRUE;
1329}
1330
1331void LLControlBase::firePropertyChanged()
1332{
1333 LLValueChangedEvent *evt = new LLValueChangedEvent(this, getValue());
1334 fireEvent(evt, "");
1335}
1336
1337//============================================================================
1338// Used to add a listener callback that will be called on the frame that the controls value changes
1339
1340S32 LLControl::addListener(LLControl::tListenerCallback* cbfn)
1341{
1342 S32 id = allocateListenerID();
1343 mListeners.push_back(cbfn);
1344 mListenerIDs.push_back( id );
1345 return id;
1346}
1347
1348void LLControl::updateListeners() {
1349 LLControl::tPropertyChangedListIter iter = mChangeEvents.begin();
1350 while(iter!=mChangeEvents.end()){
1351 LLControl::tPropertyChangedEvent& evt = *iter;
1352 (*evt.mCBFN)(evt.mNewValue,evt.mID,*this);
1353 iter++;
1354 }
1355 mChangeEvents.clear();
1356}
1357
1358//static
1359void LLControlBase::updateAllListeners()
1360{
1361 std::set< LLControlBase* >::iterator iter = mChangedControls.begin();
1362 while(iter != mChangedControls.end()){
1363 (*iter)->updateListeners();
1364 iter++;
1365 }
1366 mChangedControls.clear();
1367}
1368
1369LLControl::LLControl(
1370 const LLString& name,
1371 eControlType type,
1372 LLSD initial,
1373 const LLString& comment,
1374 BOOL persist) :
1375 LLControlBase(name, type, comment, persist),
1376 mCurrent(initial),
1377 mDefault(initial)
1378{
1379}
1380
1381//============================================================================ 1063//============================================================================
1382 1064
1383#ifdef TEST_HARNESS 1065#ifdef TEST_HARNESS
@@ -1393,17 +1075,17 @@ void main()
1393 llinfos << "Loaded " << count << " controls" << llendl; 1075 llinfos << "Loaded " << count << " controls" << llendl;
1394 1076
1395 // test insertion 1077 // test insertion
1396 foo = new LLControl<F32>("gFoo", 5.f, 1.f, 20.f); 1078 foo = new LLControlVariable<F32>("gFoo", 5.f, 1.f, 20.f);
1397 gGlobals.addEntry("gFoo", foo); 1079 gGlobals.addEntry("gFoo", foo);
1398 1080
1399 bar = new LLControl<S32>("gBar", 10, 2, 22); 1081 bar = new LLControlVariable<S32>("gBar", 10, 2, 22);
1400 gGlobals.addEntry("gBar", bar); 1082 gGlobals.addEntry("gBar", bar);
1401 1083
1402 baz = new LLControl<BOOL>("gBaz", FALSE); 1084 baz = new LLControlVariable<BOOL>("gBaz", FALSE);
1403 gGlobals.addEntry("gBaz", baz); 1085 gGlobals.addEntry("gBaz", baz);
1404 1086
1405 // test retrieval 1087 // test retrieval
1406 getfoo = (LLControl<F32>*) gGlobals.resolveName("gFoo"); 1088 getfoo = (LLControlVariable<F32>*) gGlobals.resolveName("gFoo");
1407 getfoo->dump(); 1089 getfoo->dump();
1408 1090
1409 getbar = (S32_CONTROL) gGlobals.resolveName("gBar"); 1091 getbar = (S32_CONTROL) gGlobals.resolveName("gBar");
@@ -1416,10 +1098,10 @@ void main()
1416 // Failure modes 1098 // Failure modes
1417 1099
1418 // ...min > max 1100 // ...min > max
1419 // badfoo = new LLControl<F32>("gFoo2", 100.f, 20.f, 5.f); 1101 // badfoo = new LLControlVariable<F32>("gFoo2", 100.f, 20.f, 5.f);
1420 1102
1421 // ...initial > max 1103 // ...initial > max
1422 // badbar = new LLControl<S32>("gBar2", 10, 20, 100000); 1104 // badbar = new LLControlVariable<S32>("gBar2", 10, 20, 100000);
1423 1105
1424 // ...misspelled name 1106 // ...misspelled name
1425 // getfoo = (F32_CONTROL) gGlobals.resolveName("fooMisspelled"); 1107 // getfoo = (F32_CONTROL) gGlobals.resolveName("fooMisspelled");
@@ -1441,3 +1123,4 @@ void main()
1441} 1123}
1442#endif 1124#endif
1443 1125
1126
diff --git a/linden/indra/llxml/llcontrol.h b/linden/indra/llxml/llcontrol.h
index e717bf1..9e11628 100644
--- a/linden/indra/llxml/llcontrol.h
+++ b/linden/indra/llxml/llcontrol.h
@@ -38,6 +38,26 @@
38#include "llstring.h" 38#include "llstring.h"
39#include "llrect.h" 39#include "llrect.h"
40 40
41#include <vector>
42
43// *NOTE: boost::visit_each<> generates warning 4675 on .net 2003
44// Disable the warning for the boost includes.
45#if LL_WINDOWS
46# if (_MSC_VER >= 1300 && _MSC_VER < 1400)
47# pragma warning(push)
48# pragma warning( disable : 4675 )
49# endif
50#endif
51
52#include <boost/bind.hpp>
53#include <boost/signal.hpp>
54
55#if LL_WINDOWS
56# if (_MSC_VER >= 1300 && _MSC_VER < 1400)
57# pragma warning(pop)
58# endif
59#endif
60
41class LLVector3; 61class LLVector3;
42class LLVector3d; 62class LLVector3d;
43class LLColor4; 63class LLColor4;
@@ -48,7 +68,7 @@ const BOOL NO_PERSIST = FALSE;
48 68
49typedef enum e_control_type 69typedef enum e_control_type
50{ 70{
51 TYPE_U32, 71 TYPE_U32 = 0,
52 TYPE_S32, 72 TYPE_S32,
53 TYPE_F32, 73 TYPE_F32,
54 TYPE_BOOLEAN, 74 TYPE_BOOLEAN,
@@ -58,159 +78,82 @@ typedef enum e_control_type
58 TYPE_RECT, 78 TYPE_RECT,
59 TYPE_COL4, 79 TYPE_COL4,
60 TYPE_COL3, 80 TYPE_COL3,
61 TYPE_COL4U 81 TYPE_COL4U,
82 TYPE_LLSD,
83 TYPE_COUNT
62} eControlType; 84} eControlType;
63 85
64class LLControlBase : public LLSimpleListenerObservable 86class LLControlVariable
65{ 87{
66friend class LLControlGroup; 88 friend class LLControlGroup;
67protected: 89 typedef boost::signal<void(const LLSD&)> signal_t;
90
91private:
68 LLString mName; 92 LLString mName;
69 LLString mComment; 93 LLString mComment;
70 eControlType mType; 94 eControlType mType;
71 BOOL mHasRange;
72 BOOL mPersist; 95 BOOL mPersist;
73 BOOL mIsDefault; 96 std::vector<LLSD> mValues;
74 97
75 static std::set<LLControlBase*> mChangedControls; 98 signal_t mSignal;
76 static std::list<S32> mFreeIDs;//These lists are used to store the ID's of registered event listeners. 99
77 static std::list<S32> mUsedIDs;
78 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.
79
80public: 100public:
81 static void releaseListenerID(S32 id); 101 LLControlVariable(const LLString& name, eControlType type,
82 static S32 allocateListenerID(); 102 LLSD initial, const LLString& comment,
83 static void updateAllListeners(); 103 BOOL persist = TRUE);
84 virtual void updateListeners() = 0;
85
86 LLControlBase(const LLString& name, eControlType type, const LLString& comment, BOOL persist)
87 : mName(name),
88 mComment(comment),
89 mType(type),
90 mHasRange(FALSE),
91 mPersist(persist),
92 mIsDefault(TRUE)
93 {
94 if (mPersist && mComment.empty())
95 {
96 llerrs << "Must supply a comment for control " << mName << llendl;
97 }
98 sMaxControlNameLength = llmax((U32)mName.size(), sMaxControlNameLength);
99 }
100
101 virtual ~LLControlBase();
102 104
105 virtual ~LLControlVariable();
106
103 const LLString& getName() const { return mName; } 107 const LLString& getName() const { return mName; }
104 const LLString& getComment() const { return mComment; } 108 const LLString& getComment() const { return mComment; }
105 109
106 eControlType type() { return mType; } 110 eControlType type() { return mType; }
107 BOOL isType(eControlType tp) { return tp == mType; } 111 BOOL isType(eControlType tp) { return tp == mType; }
108 112
109 // Defaults to no-op 113 void resetToDefault(bool fire_signal = TRUE);
110 virtual void resetToDefault(); 114
111 115 signal_t* getSignal() { return &mSignal; }
112 LLSD registerListener(LLSimpleListenerObservable *listener, LLSD userdata = ""); 116
113 117 bool isDefault() { return (mValues.size() == 1); }
114 virtual LLSD get() const = 0; 118 bool isSaveValueDefault();
115 virtual LLSD getValue() const = 0; 119 bool isPersisted() { return mPersist; }
116 virtual void setValue(LLSD value) = 0; 120 void set(const LLSD& val) { setValue(val); }
117 virtual void set(LLSD value) = 0; 121 LLSD get() const { return getValue(); }
118 122 LLSD getDefault() const { return mValues.front(); }
119 // From LLSimpleListener 123 LLSD getValue() const { return mValues.back(); }
120 virtual bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata); 124 LLSD getSaveValue() const;
121 125 void setValue(const LLSD& value, bool saved_value = TRUE);
122 void firePropertyChanged(); 126 void firePropertyChanged()
123
124 static U32 sMaxControlNameLength;
125
126protected:
127 const char* name() { return mName.c_str(); }
128 const char* comment() { return mComment.c_str(); }
129};
130
131class LLControl
132: public LLControlBase
133{
134friend class LLControlGroup;
135protected:
136 LLSD mCurrent;
137 LLSD mDefault;
138
139public:
140
141 typedef void tListenerCallback(const LLSD& newValue,S32 listenerID, LLControl& control);
142 typedef struct{
143 S32 mID;
144 LLSD mNewValue;
145 tListenerCallback* mCBFN;
146 }tPropertyChangedEvent;
147
148 typedef std::list<tPropertyChangedEvent>::iterator tPropertyChangedListIter;
149 std::list<tPropertyChangedEvent> mChangeEvents;
150 std::list< tListenerCallback* > mListeners;
151 std::list< S32 > mListenerIDs;
152
153 virtual void updateListeners();
154 S32 addListener(tListenerCallback* cbfn);
155
156 LLControl(
157 const LLString& name,
158 eControlType type,
159 LLSD initial, const
160 LLString& comment,
161 BOOL persist = TRUE);
162
163 void set(LLSD val) { setValue(val); }
164 LLSD get() const { return getValue(); }
165 LLSD getdefault() const { return mDefault; }
166 LLSD getValue() const { return mCurrent; }
167 BOOL llsd_compare(const LLSD& a, const LLSD& b);
168
169 void setValue(LLSD value)
170 {
171 if (llsd_compare(mCurrent, value) == FALSE)
172 {
173 mCurrent = value;
174 mIsDefault = llsd_compare(mCurrent, mDefault);
175 firePropertyChanged();
176 }
177 }
178
179 /*virtual*/ void resetToDefault()
180 {
181 setValue(mDefault);
182 }
183
184 virtual ~LLControl()
185 { 127 {
186 //Remove and deregister all listeners.. 128 mSignal(mValues.back());
187 while(mListenerIDs.size())
188 {
189 S32 id = mListenerIDs.front();
190 mListenerIDs.pop_front();
191 releaseListenerID(id);
192 }
193 } 129 }
130 BOOL llsd_compare(const LLSD& a, const LLSD& b);
194}; 131};
195 132
196//const U32 STRING_CACHE_SIZE = 10000; 133//const U32 STRING_CACHE_SIZE = 10000;
197class LLControlGroup 134class LLControlGroup
198{ 135{
199public: 136protected:
200 typedef std::map<LLString, LLPointer<LLControlBase> > ctrl_name_table_t; 137 typedef std::map<LLString, LLControlVariable* > ctrl_name_table_t;
201 ctrl_name_table_t mNameTable; 138 ctrl_name_table_t mNameTable;
202 std::set<LLString> mWarnings; 139 std::set<LLString> mWarnings;
203 std::set<LLString> mLoadedSettings; // Filled in with names loaded from settings.xml 140 LLString mTypeString[TYPE_COUNT];
204 141
142 eControlType typeStringToEnum(const LLString& typestr);
143 LLString typeEnumToString(eControlType typeenum);
205public: 144public:
206 LLControlGroup(); 145 LLControlGroup();
207 ~LLControlGroup(); 146 ~LLControlGroup();
208 void cleanup(); 147 void cleanup();
209 bool hasLoaded(const LLString& name) { return mLoadedSettings.find(name) != mLoadedSettings.end(); }
210 void clearLoaded() { mLoadedSettings.clear(); } // Call once we've done any settings tweaks which may need this data
211 148
212 LLControlBase* getControl(const LLString& name); 149 LLControlVariable* getControl(const LLString& name);
213 LLSD registerListener(const LLString& name, LLSimpleListenerObservable *listener); 150
151 struct ApplyFunctor
152 {
153 virtual ~ApplyFunctor() {};
154 virtual void apply(const LLString& name, LLControlVariable* control) = 0;
155 };
156 void applyToAll(ApplyFunctor* func);
214 157
215 BOOL declareControl(const LLString& name, eControlType type, const LLSD initial_val, const LLString& comment, BOOL persist); 158 BOOL declareControl(const LLString& name, eControlType type, const LLSD initial_val, const LLString& comment, BOOL persist);
216 BOOL declareU32(const LLString& name, U32 initial_val, const LLString& comment, BOOL persist = TRUE); 159 BOOL declareU32(const LLString& name, U32 initial_val, const LLString& comment, BOOL persist = TRUE);
@@ -224,6 +167,7 @@ public:
224 BOOL declareColor4U(const LLString& name, const LLColor4U &initial_val, const LLString& comment, BOOL persist = TRUE); 167 BOOL declareColor4U(const LLString& name, const LLColor4U &initial_val, const LLString& comment, BOOL persist = TRUE);
225 BOOL declareColor4(const LLString& name, const LLColor4 &initial_val, const LLString& comment, BOOL persist = TRUE); 168 BOOL declareColor4(const LLString& name, const LLColor4 &initial_val, const LLString& comment, BOOL persist = TRUE);
226 BOOL declareColor3(const LLString& name, const LLColor3 &initial_val, const LLString& comment, BOOL persist = TRUE); 169 BOOL declareColor3(const LLString& name, const LLColor3 &initial_val, const LLString& comment, BOOL persist = TRUE);
170 BOOL declareLLSD(const LLString& name, const LLSD &initial_val, const LLString& comment, BOOL persist = TRUE);
227 171
228 LLString findString(const LLString& name); 172 LLString findString(const LLString& name);
229 173
@@ -237,7 +181,7 @@ public:
237 S32 getS32(const LLString& name); 181 S32 getS32(const LLString& name);
238 F32 getF32(const LLString& name); 182 F32 getF32(const LLString& name);
239 U32 getU32(const LLString& name); 183 U32 getU32(const LLString& name);
240 LLSD getValue(const LLString& name); 184 LLSD getLLSD(const LLString& name);
241 185
242 186
243 // Note: If an LLColor4U control exists, it will cast it to the correct 187 // Note: If an LLColor4U control exists, it will cast it to the correct
@@ -258,19 +202,21 @@ public:
258 void setColor4U(const LLString& name, const LLColor4U &val); 202 void setColor4U(const LLString& name, const LLColor4U &val);
259 void setColor4(const LLString& name, const LLColor4 &val); 203 void setColor4(const LLString& name, const LLColor4 &val);
260 void setColor3(const LLString& name, const LLColor3 &val); 204 void setColor3(const LLString& name, const LLColor3 &val);
205 void setLLSD(const LLString& name, const LLSD& val);
261 void setValue(const LLString& name, const LLSD& val); 206 void setValue(const LLString& name, const LLSD& val);
262 207
208
263 BOOL controlExists(const LLString& name); 209 BOOL controlExists(const LLString& name);
264 210
265 // Returns number of controls loaded, 0 if failed 211 // Returns number of controls loaded, 0 if failed
266 // If require_declaration is false, will auto-declare controls it finds 212 // If require_declaration is false, will auto-declare controls it finds
267 // as the given type. 213 // as the given type.
268 U32 loadFromFileLegacy(const LLString& filename, BOOL require_declaration = TRUE, eControlType declare_as = TYPE_STRING); 214 U32 loadFromFileLegacy(const LLString& filename, BOOL require_declaration = TRUE, eControlType declare_as = TYPE_STRING);
269 U32 loadFromFile(const LLString& filename, BOOL require_declaration = TRUE, eControlType declare_as = TYPE_STRING); 215 U32 saveToFile(const LLString& filename, BOOL nondefault_only);
270 U32 saveToFile(const LLString& filename, BOOL skip_if_default); 216 U32 loadFromFile(const LLString& filename, BOOL require_declaration = TRUE, eControlType declare_as = TYPE_STRING);
271 void applyOverrides(const std::map<std::string, std::string>& overrides);
272 void resetToDefaults(); 217 void resetToDefaults();
273 218
219
274 // Ignorable Warnings 220 // Ignorable Warnings
275 221
276 // Add a config variable to be reset on resetWarnings() 222 // Add a config variable to be reset on resetWarnings()