llcontrol.h
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:15k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llcontrol.h
  3.  * @brief A mechanism for storing "control state" for a program
  4.  *
  5.  * $LicenseInfo:firstyear=2001&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2001-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #ifndef LL_LLCONTROL_H
  33. #define LL_LLCONTROL_H
  34. #include "llboost.h"
  35. #include "llevent.h"
  36. #include "llnametable.h"
  37. #include "llmap.h"
  38. #include "llstring.h"
  39. #include "llrect.h"
  40. #include "llrefcount.h"
  41. #include "llinstancetracker.h"
  42. #include "llcontrolgroupreader.h"
  43. #include <vector>
  44. // *NOTE: boost::visit_each<> generates warning 4675 on .net 2003
  45. // Disable the warning for the boost includes.
  46. #if LL_WINDOWS
  47. # if (_MSC_VER >= 1300 && _MSC_VER < 1400)
  48. #   pragma warning(push)
  49. #   pragma warning( disable : 4675 )
  50. # endif
  51. #endif
  52. #include <boost/bind.hpp>
  53. #if LL_WINDOWS
  54. #pragma warning (push)
  55. #pragma warning (disable : 4263) // boost::signals2::expired_slot::what() has const mismatch
  56. #pragma warning (disable : 4264) 
  57. #endif
  58. #include <boost/signals2.hpp>
  59. #if LL_WINDOWS
  60. #pragma warning (pop)
  61. #endif
  62. #if LL_WINDOWS
  63. # if (_MSC_VER >= 1300 && _MSC_VER < 1400)
  64. #   pragma warning(pop)
  65. # endif
  66. #endif
  67. class LLVector3;
  68. class LLVector3d;
  69. class LLColor4;
  70. class LLColor3;
  71. const BOOL NO_PERSIST = FALSE;
  72. typedef enum e_control_type
  73. {
  74. TYPE_U32 = 0,
  75. TYPE_S32,
  76. TYPE_F32,
  77. TYPE_BOOLEAN,
  78. TYPE_STRING,
  79. TYPE_VEC3,
  80. TYPE_VEC3D,
  81. TYPE_RECT,
  82. TYPE_COL4,
  83. TYPE_COL3,
  84. TYPE_LLSD,
  85. TYPE_COUNT
  86. } eControlType;
  87. class LLControlVariable : public LLRefCount
  88. {
  89. friend class LLControlGroup;
  90. public:
  91. typedef boost::signals2::signal<bool(LLControlVariable* control, const LLSD&), boost_boolean_combiner> validate_signal_t;
  92. typedef boost::signals2::signal<void(LLControlVariable* control, const LLSD&)> commit_signal_t;
  93. private:
  94. std::string mName;
  95. std::string mComment;
  96. eControlType mType;
  97. bool mPersist;
  98. bool mHideFromSettingsEditor;
  99. std::vector<LLSD> mValues;
  100. commit_signal_t mCommitSignal;
  101. validate_signal_t mValidateSignal;
  102. public:
  103. LLControlVariable(const std::string& name, eControlType type,
  104.   LLSD initial, const std::string& comment,
  105.   bool persist = true, bool hidefromsettingseditor = false);
  106. virtual ~LLControlVariable();
  107. const std::string& getName() const { return mName; }
  108. const std::string& getComment() const { return mComment; }
  109. eControlType type() { return mType; }
  110. bool isType(eControlType tp) { return tp == mType; }
  111. void resetToDefault(bool fire_signal = false);
  112. commit_signal_t* getSignal() { return &mCommitSignal; } // shorthand for commit signal
  113. commit_signal_t* getCommitSignal() { return &mCommitSignal; }
  114. validate_signal_t* getValidateSignal() { return &mValidateSignal; }
  115. bool isDefault() { return (mValues.size() == 1); }
  116. bool isSaveValueDefault();
  117. bool isPersisted() { return mPersist; }
  118. bool isHiddenFromSettingsEditor() { return mHideFromSettingsEditor; }
  119. LLSD get() const { return getValue(); }
  120. LLSD getValue() const { return mValues.back(); }
  121. LLSD getDefault() const { return mValues.front(); }
  122. LLSD getSaveValue() const;
  123. void set(const LLSD& val) { setValue(val); }
  124. void setValue(const LLSD& value, bool saved_value = TRUE);
  125. void setDefaultValue(const LLSD& value);
  126. void setPersist(bool state);
  127. void setHiddenFromSettingsEditor(bool hide);
  128. void setComment(const std::string& comment);
  129. void firePropertyChanged()
  130. {
  131. mCommitSignal(this, mValues.back());
  132. }
  133. private:
  134. LLSD getComparableValue(const LLSD& value);
  135. bool llsd_compare(const LLSD& a, const LLSD & b);
  136. };
  137. typedef LLPointer<LLControlVariable> LLControlVariablePtr;
  138. //! Helper functions for converting between static types and LLControl values
  139. template <class T> 
  140. eControlType get_control_type()
  141. {
  142. llwarns << "Usupported control type: " << typeid(T).name() << "." << llendl;
  143. return TYPE_COUNT;
  144. }
  145. template <class T> 
  146. LLSD convert_to_llsd(const T& in)
  147. {
  148. // default implementation
  149. return LLSD(in);
  150. }
  151. template <class T>
  152. T convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name)
  153. {
  154. // needs specialization
  155. return T(sd);
  156. }
  157. //const U32 STRING_CACHE_SIZE = 10000;
  158. class LLControlGroup : public LLInstanceTracker<LLControlGroup, std::string>
  159. {
  160. protected:
  161. typedef std::map<std::string, LLControlVariablePtr > ctrl_name_table_t;
  162. ctrl_name_table_t mNameTable;
  163. std::string mTypeString[TYPE_COUNT];
  164. eControlType typeStringToEnum(const std::string& typestr);
  165. std::string typeEnumToString(eControlType typeenum);
  166. public:
  167. LLControlGroup(const std::string& name);
  168. ~LLControlGroup();
  169. void cleanup();
  170. typedef LLInstanceTracker<LLControlGroup, std::string>::instance_iter instance_iter;
  171. LLControlVariablePtr getControl(const std::string& name);
  172. struct ApplyFunctor
  173. {
  174. virtual ~ApplyFunctor() {};
  175. virtual void apply(const std::string& name, LLControlVariable* control) = 0;
  176. };
  177. void applyToAll(ApplyFunctor* func);
  178. BOOL declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, BOOL persist, BOOL hidefromsettingseditor = FALSE);
  179. BOOL declareU32(const std::string& name, U32 initial_val, const std::string& comment, BOOL persist = TRUE);
  180. BOOL declareS32(const std::string& name, S32 initial_val, const std::string& comment, BOOL persist = TRUE);
  181. BOOL declareF32(const std::string& name, F32 initial_val, const std::string& comment, BOOL persist = TRUE);
  182. BOOL declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, BOOL persist = TRUE);
  183. BOOL declareString(const std::string& name, const std::string &initial_val, const std::string& comment, BOOL persist = TRUE);
  184. BOOL declareVec3(const std::string& name, const LLVector3 &initial_val,const std::string& comment,  BOOL persist = TRUE);
  185. BOOL declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, BOOL persist = TRUE);
  186. BOOL declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, BOOL persist = TRUE);
  187. BOOL declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, BOOL persist = TRUE);
  188. BOOL declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, BOOL persist = TRUE);
  189. BOOL declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, BOOL persist = TRUE);
  190. std::string getString(const std::string& name);
  191. std::string getText(const std::string& name);
  192. BOOL getBOOL(const std::string& name);
  193. S32 getS32(const std::string& name);
  194. F32 getF32(const std::string& name);
  195. U32 getU32(const std::string& name);
  196. LLWString getWString(const std::string& name);
  197. LLVector3 getVector3(const std::string& name);
  198. LLVector3d getVector3d(const std::string& name);
  199. LLRect getRect(const std::string& name);
  200. LLSD        getLLSD(const std::string& name);
  201. LLColor4 getColor(const std::string& name);
  202. LLColor4 getColor4(const std::string& name);
  203. LLColor3 getColor3(const std::string& name);
  204. // generic getter
  205. template<typename T> T get(const std::string& name)
  206. {
  207. LLControlVariable* control = getControl(name);
  208. LLSD value;
  209. eControlType type = TYPE_COUNT;
  210. if (control)
  211. {
  212. value = control->get();
  213. type = control->type();
  214. }
  215. else
  216. {
  217. llwarns << "Control " << name << " not found." << llendl;
  218. }
  219. return convert_from_llsd<T>(value, type, name);
  220. }
  221. void setBOOL(const std::string& name, BOOL val);
  222. void setS32(const std::string& name, S32 val);
  223. void setF32(const std::string& name, F32 val);
  224. void setU32(const std::string& name, U32 val);
  225. void setString(const std::string&  name, const std::string& val);
  226. void setVector3(const std::string& name, const LLVector3 &val);
  227. void setVector3d(const std::string& name, const LLVector3d &val);
  228. void setRect(const std::string& name, const LLRect &val);
  229. void setColor4(const std::string& name, const LLColor4 &val);
  230. void    setLLSD(const std::string& name, const LLSD& val);
  231. // type agnostic setter that takes LLSD
  232. void setUntypedValue(const std::string& name, const LLSD& val);
  233. // generic setter
  234. template<typename T> void set(const std::string& name, const T& val)
  235. {
  236. LLControlVariable* control = getControl(name);
  237. if (control && control->isType(get_control_type<T>()))
  238. {
  239. control->set(convert_to_llsd(val));
  240. }
  241. else
  242. {
  243. llwarns << "Invalid control " << name << llendl;
  244. }
  245. }
  246. BOOL    controlExists(const std::string& name);
  247. // Returns number of controls loaded, 0 if failed
  248. // If require_declaration is false, will auto-declare controls it finds
  249. // as the given type.
  250. U32 loadFromFileLegacy(const std::string& filename, BOOL require_declaration = TRUE, eControlType declare_as = TYPE_STRING);
  251.   U32 saveToFile(const std::string& filename, BOOL nondefault_only);
  252.   U32 loadFromFile(const std::string& filename, bool default_values = false);
  253. void resetToDefaults();
  254. };
  255. //! Publish/Subscribe object to interact with LLControlGroups.
  256. //! Use an LLCachedControl instance to connect to a LLControlVariable
  257. //! without have to manually create and bind a listener to a local
  258. //! object.
  259. template <class T>
  260. class LLControlCache : public LLRefCount, public LLInstanceTracker<LLControlCache<T>, std::string>
  261. {
  262. public:
  263. // This constructor will declare a control if it doesn't exist in the contol group
  264. LLControlCache(LLControlGroup& group,
  265. const std::string& name, 
  266. const T& default_value, 
  267. const std::string& comment)
  268. : LLInstanceTracker<LLControlCache<T>, std::string >(name)
  269. {
  270. if(!group.controlExists(name))
  271. {
  272. if(!declareTypedControl(group, name, default_value, comment))
  273. {
  274. llerrs << "The control could not be created!!!" << llendl;
  275. }
  276. }
  277. bindToControl(group, name);
  278. }
  279. LLControlCache(LLControlGroup& group,
  280. const std::string& name)
  281. : LLInstanceTracker<LLControlCache<T>, std::string >(name)
  282. {
  283. if(!group.controlExists(name))
  284. {
  285. llerrs << "Control named " << name << "not found." << llendl;
  286. }
  287. bindToControl(group, name);
  288. }
  289. ~LLControlCache()
  290. {
  291. }
  292. const T& getValue() const { return mCachedValue; }
  293. private:
  294. void bindToControl(LLControlGroup& group, const std::string& name)
  295. {
  296. LLControlVariablePtr controlp = group.getControl(name);
  297. mType = controlp->type();
  298. mCachedValue = convert_from_llsd<T>(controlp->get(), mType, name);
  299. // Add a listener to the controls signal...
  300. mConnection = controlp->getSignal()->connect(
  301. boost::bind(&LLControlCache<T>::handleValueChange, this, _2)
  302. );
  303. mType = controlp->type();
  304. }
  305. bool declareTypedControl(LLControlGroup& group,
  306. const std::string& name, 
  307.  const T& default_value,
  308.  const std::string& comment)
  309. {
  310. LLSD init_value;
  311. eControlType type = get_control_type<T>();
  312. init_value = convert_to_llsd(default_value);
  313. if(type < TYPE_COUNT)
  314. {
  315. group.declareControl(name, type, init_value, comment, FALSE);
  316. return true;
  317. }
  318. return false;
  319. }
  320. bool handleValueChange(const LLSD& newvalue)
  321. {
  322. mCachedValue = convert_from_llsd<T>(newvalue, mType, "");
  323. return true;
  324. }
  325. private:
  326.     T mCachedValue;
  327. eControlType mType;
  328.     boost::signals2::scoped_connection mConnection;
  329. };
  330. template <typename T>
  331. class LLCachedControl
  332. {
  333. public:
  334. LLCachedControl(LLControlGroup& group,
  335. const std::string& name, 
  336. const T& default_value, 
  337. const std::string& comment = "Declared In Code")
  338. {
  339. mCachedControlPtr = LLControlCache<T>::getInstance(name);
  340. if (mCachedControlPtr.isNull())
  341. {
  342. mCachedControlPtr = new LLControlCache<T>(group, name, default_value, comment);
  343. }
  344. }
  345. LLCachedControl(LLControlGroup& group,
  346. const std::string& name)
  347. {
  348. mCachedControlPtr = LLControlCache<T>::getInstance(name);
  349. if (mCachedControlPtr.isNull())
  350. {
  351. mCachedControlPtr = new LLControlCache<T>(group, name);
  352. }
  353. }
  354. operator const T&() const { return mCachedControlPtr->getValue(); }
  355. operator boost::function<const T&()> () const { return boost::function<const T&()>(*this); }
  356. const T& operator()() { return mCachedControlPtr->getValue(); }
  357. private:
  358. LLPointer<LLControlCache<T> > mCachedControlPtr;
  359. };
  360. template <> eControlType get_control_type<U32>();
  361. template <> eControlType get_control_type<S32>();
  362. template <> eControlType get_control_type<F32>();
  363. template <> eControlType get_control_type<bool>(); 
  364. // Yay BOOL, its really an S32.
  365. //template <> eControlType get_control_type<BOOL> () 
  366. template <> eControlType get_control_type<std::string>();
  367. template <> eControlType get_control_type<LLVector3>();
  368. template <> eControlType get_control_type<LLVector3d>(); 
  369. template <> eControlType get_control_type<LLRect>();
  370. template <> eControlType get_control_type<LLColor4>();
  371. template <> eControlType get_control_type<LLColor3>();
  372. template <> eControlType get_control_type<LLSD>();
  373. template <> LLSD convert_to_llsd<U32>(const U32& in);
  374. template <> LLSD convert_to_llsd<LLVector3>(const LLVector3& in);
  375. template <> LLSD convert_to_llsd<LLVector3d>(const LLVector3d& in); 
  376. template <> LLSD convert_to_llsd<LLRect>(const LLRect& in);
  377. template <> LLSD convert_to_llsd<LLColor4>(const LLColor4& in);
  378. template <> LLSD convert_to_llsd<LLColor3>(const LLColor3& in);
  379. template<> std::string convert_from_llsd<std::string>(const LLSD& sd, eControlType type, const std::string& control_name);
  380. template<> LLWString convert_from_llsd<LLWString>(const LLSD& sd, eControlType type, const std::string& control_name);
  381. template<> LLVector3 convert_from_llsd<LLVector3>(const LLSD& sd, eControlType type, const std::string& control_name);
  382. template<> LLVector3d convert_from_llsd<LLVector3d>(const LLSD& sd, eControlType type, const std::string& control_name);
  383. template<> LLRect convert_from_llsd<LLRect>(const LLSD& sd, eControlType type, const std::string& control_name);
  384. template<> bool convert_from_llsd<bool>(const LLSD& sd, eControlType type, const std::string& control_name);
  385. template<> S32 convert_from_llsd<S32>(const LLSD& sd, eControlType type, const std::string& control_name);
  386. template<> F32 convert_from_llsd<F32>(const LLSD& sd, eControlType type, const std::string& control_name);
  387. template<> U32 convert_from_llsd<U32>(const LLSD& sd, eControlType type, const std::string& control_name);
  388. template<> LLColor3 convert_from_llsd<LLColor3>(const LLSD& sd, eControlType type, const std::string& control_name);
  389. template<> LLColor4 convert_from_llsd<LLColor4>(const LLSD& sd, eControlType type, const std::string& control_name);
  390. template<> LLSD convert_from_llsd<LLSD>(const LLSD& sd, eControlType type, const std::string& control_name);
  391. //#define TEST_CACHED_CONTROL 1
  392. #ifdef TEST_CACHED_CONTROL
  393. void test_cached_control();
  394. #endif // TEST_CACHED_CONTROL
  395. #endif