llcontrol.h
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:15k
- /**
- * @file llcontrol.h
- * @brief A mechanism for storing "control state" for a program
- *
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2010, 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://secondlifegrid.net/programs/open_source/licensing/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://secondlifegrid.net/programs/open_source/licensing/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 "llboost.h"
- #include "llevent.h"
- #include "llnametable.h"
- #include "llmap.h"
- #include "llstring.h"
- #include "llrect.h"
- #include "llrefcount.h"
- #include "llinstancetracker.h"
- #include "llcontrolgroupreader.h"
- #include <vector>
- // *NOTE: boost::visit_each<> generates warning 4675 on .net 2003
- // Disable the warning for the boost includes.
- #if LL_WINDOWS
- # if (_MSC_VER >= 1300 && _MSC_VER < 1400)
- # pragma warning(push)
- # pragma warning( disable : 4675 )
- # endif
- #endif
- #include <boost/bind.hpp>
- #if LL_WINDOWS
- #pragma warning (push)
- #pragma warning (disable : 4263) // boost::signals2::expired_slot::what() has const mismatch
- #pragma warning (disable : 4264)
- #endif
- #include <boost/signals2.hpp>
- #if LL_WINDOWS
- #pragma warning (pop)
- #endif
- #if LL_WINDOWS
- # if (_MSC_VER >= 1300 && _MSC_VER < 1400)
- # pragma warning(pop)
- # endif
- #endif
- class LLVector3;
- class LLVector3d;
- class LLColor4;
- class LLColor3;
- const BOOL NO_PERSIST = FALSE;
- typedef enum e_control_type
- {
- TYPE_U32 = 0,
- TYPE_S32,
- TYPE_F32,
- TYPE_BOOLEAN,
- TYPE_STRING,
- TYPE_VEC3,
- TYPE_VEC3D,
- TYPE_RECT,
- TYPE_COL4,
- TYPE_COL3,
- TYPE_LLSD,
- TYPE_COUNT
- } eControlType;
- class LLControlVariable : public LLRefCount
- {
- friend class LLControlGroup;
-
- public:
- typedef boost::signals2::signal<bool(LLControlVariable* control, const LLSD&), boost_boolean_combiner> validate_signal_t;
- typedef boost::signals2::signal<void(LLControlVariable* control, const LLSD&)> commit_signal_t;
- private:
- std::string mName;
- std::string mComment;
- eControlType mType;
- bool mPersist;
- bool mHideFromSettingsEditor;
- std::vector<LLSD> mValues;
-
- commit_signal_t mCommitSignal;
- validate_signal_t mValidateSignal;
-
- public:
- LLControlVariable(const std::string& name, eControlType type,
- LLSD initial, const std::string& comment,
- bool persist = true, bool hidefromsettingseditor = false);
- virtual ~LLControlVariable();
-
- const std::string& getName() const { return mName; }
- const std::string& getComment() const { return mComment; }
- eControlType type() { return mType; }
- bool isType(eControlType tp) { return tp == mType; }
- void resetToDefault(bool fire_signal = false);
- commit_signal_t* getSignal() { return &mCommitSignal; } // shorthand for commit signal
- commit_signal_t* getCommitSignal() { return &mCommitSignal; }
- validate_signal_t* getValidateSignal() { return &mValidateSignal; }
- bool isDefault() { return (mValues.size() == 1); }
- bool isSaveValueDefault();
- bool isPersisted() { return mPersist; }
- bool isHiddenFromSettingsEditor() { return mHideFromSettingsEditor; }
- LLSD get() const { return getValue(); }
- LLSD getValue() const { return mValues.back(); }
- LLSD getDefault() const { return mValues.front(); }
- LLSD getSaveValue() const;
- void set(const LLSD& val) { setValue(val); }
- void setValue(const LLSD& value, bool saved_value = TRUE);
- void setDefaultValue(const LLSD& value);
- void setPersist(bool state);
- void setHiddenFromSettingsEditor(bool hide);
- void setComment(const std::string& comment);
- void firePropertyChanged()
- {
- mCommitSignal(this, mValues.back());
- }
- private:
- LLSD getComparableValue(const LLSD& value);
- bool llsd_compare(const LLSD& a, const LLSD & b);
- };
- typedef LLPointer<LLControlVariable> LLControlVariablePtr;
- //! Helper functions for converting between static types and LLControl values
- template <class T>
- eControlType get_control_type()
- {
- llwarns << "Usupported control type: " << typeid(T).name() << "." << llendl;
- return TYPE_COUNT;
- }
- template <class T>
- LLSD convert_to_llsd(const T& in)
- {
- // default implementation
- return LLSD(in);
- }
- template <class T>
- T convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name)
- {
- // needs specialization
- return T(sd);
- }
- //const U32 STRING_CACHE_SIZE = 10000;
- class LLControlGroup : public LLInstanceTracker<LLControlGroup, std::string>
- {
- protected:
- typedef std::map<std::string, LLControlVariablePtr > ctrl_name_table_t;
- ctrl_name_table_t mNameTable;
- std::string mTypeString[TYPE_COUNT];
- eControlType typeStringToEnum(const std::string& typestr);
- std::string typeEnumToString(eControlType typeenum);
- public:
- LLControlGroup(const std::string& name);
- ~LLControlGroup();
- void cleanup();
-
- typedef LLInstanceTracker<LLControlGroup, std::string>::instance_iter instance_iter;
- LLControlVariablePtr getControl(const std::string& name);
- struct ApplyFunctor
- {
- virtual ~ApplyFunctor() {};
- virtual void apply(const std::string& name, LLControlVariable* control) = 0;
- };
- void applyToAll(ApplyFunctor* func);
-
- BOOL declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, BOOL persist, BOOL hidefromsettingseditor = FALSE);
- BOOL declareU32(const std::string& name, U32 initial_val, const std::string& comment, BOOL persist = TRUE);
- BOOL declareS32(const std::string& name, S32 initial_val, const std::string& comment, BOOL persist = TRUE);
- BOOL declareF32(const std::string& name, F32 initial_val, const std::string& comment, BOOL persist = TRUE);
- BOOL declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, BOOL persist = TRUE);
- BOOL declareString(const std::string& name, const std::string &initial_val, const std::string& comment, BOOL persist = TRUE);
- BOOL declareVec3(const std::string& name, const LLVector3 &initial_val,const std::string& comment, BOOL persist = TRUE);
- BOOL declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, BOOL persist = TRUE);
- BOOL declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, BOOL persist = TRUE);
- BOOL declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, BOOL persist = TRUE);
- BOOL declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, BOOL persist = TRUE);
- BOOL declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, BOOL persist = TRUE);
- std::string getString(const std::string& name);
- std::string getText(const std::string& name);
- BOOL getBOOL(const std::string& name);
- S32 getS32(const std::string& name);
- F32 getF32(const std::string& name);
- U32 getU32(const std::string& name);
-
- LLWString getWString(const std::string& name);
- LLVector3 getVector3(const std::string& name);
- LLVector3d getVector3d(const std::string& name);
- LLRect getRect(const std::string& name);
- LLSD getLLSD(const std::string& name);
- LLColor4 getColor(const std::string& name);
- LLColor4 getColor4(const std::string& name);
- LLColor3 getColor3(const std::string& name);
- // generic getter
- template<typename T> T get(const std::string& name)
- {
- LLControlVariable* control = getControl(name);
- LLSD value;
- eControlType type = TYPE_COUNT;
- if (control)
- {
- value = control->get();
- type = control->type();
- }
- else
- {
- llwarns << "Control " << name << " not found." << llendl;
- }
- return convert_from_llsd<T>(value, type, name);
- }
- void setBOOL(const std::string& name, BOOL val);
- void setS32(const std::string& name, S32 val);
- void setF32(const std::string& name, F32 val);
- void setU32(const std::string& name, U32 val);
- void setString(const std::string& name, const std::string& val);
- void setVector3(const std::string& name, const LLVector3 &val);
- void setVector3d(const std::string& name, const LLVector3d &val);
- void setRect(const std::string& name, const LLRect &val);
- void setColor4(const std::string& name, const LLColor4 &val);
- void setLLSD(const std::string& name, const LLSD& val);
- // type agnostic setter that takes LLSD
- void setUntypedValue(const std::string& name, const LLSD& val);
- // generic setter
- template<typename T> void set(const std::string& name, const T& val)
- {
- LLControlVariable* control = getControl(name);
-
- if (control && control->isType(get_control_type<T>()))
- {
- control->set(convert_to_llsd(val));
- }
- else
- {
- llwarns << "Invalid control " << name << llendl;
- }
- }
-
- BOOL controlExists(const std::string& 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 std::string& filename, BOOL require_declaration = TRUE, eControlType declare_as = TYPE_STRING);
- U32 saveToFile(const std::string& filename, BOOL nondefault_only);
- U32 loadFromFile(const std::string& filename, bool default_values = false);
- void resetToDefaults();
- };
- //! Publish/Subscribe object to interact with LLControlGroups.
- //! Use an LLCachedControl instance to connect to a LLControlVariable
- //! without have to manually create and bind a listener to a local
- //! object.
- template <class T>
- class LLControlCache : public LLRefCount, public LLInstanceTracker<LLControlCache<T>, std::string>
- {
- public:
- // This constructor will declare a control if it doesn't exist in the contol group
- LLControlCache(LLControlGroup& group,
- const std::string& name,
- const T& default_value,
- const std::string& comment)
- : LLInstanceTracker<LLControlCache<T>, std::string >(name)
- {
- if(!group.controlExists(name))
- {
- if(!declareTypedControl(group, name, default_value, comment))
- {
- llerrs << "The control could not be created!!!" << llendl;
- }
- }
- bindToControl(group, name);
- }
- LLControlCache(LLControlGroup& group,
- const std::string& name)
- : LLInstanceTracker<LLControlCache<T>, std::string >(name)
- {
- if(!group.controlExists(name))
- {
- llerrs << "Control named " << name << "not found." << llendl;
- }
- bindToControl(group, name);
- }
- ~LLControlCache()
- {
- }
- const T& getValue() const { return mCachedValue; }
-
- private:
- void bindToControl(LLControlGroup& group, const std::string& name)
- {
- LLControlVariablePtr controlp = group.getControl(name);
- mType = controlp->type();
- mCachedValue = convert_from_llsd<T>(controlp->get(), mType, name);
- // Add a listener to the controls signal...
- mConnection = controlp->getSignal()->connect(
- boost::bind(&LLControlCache<T>::handleValueChange, this, _2)
- );
- mType = controlp->type();
- }
- bool declareTypedControl(LLControlGroup& group,
- const std::string& name,
- const T& default_value,
- const std::string& comment)
- {
- LLSD init_value;
- eControlType type = get_control_type<T>();
- init_value = convert_to_llsd(default_value);
- if(type < TYPE_COUNT)
- {
- group.declareControl(name, type, init_value, comment, FALSE);
- return true;
- }
- return false;
- }
- bool handleValueChange(const LLSD& newvalue)
- {
- mCachedValue = convert_from_llsd<T>(newvalue, mType, "");
- return true;
- }
- private:
- T mCachedValue;
- eControlType mType;
- boost::signals2::scoped_connection mConnection;
- };
- template <typename T>
- class LLCachedControl
- {
- public:
- LLCachedControl(LLControlGroup& group,
- const std::string& name,
- const T& default_value,
- const std::string& comment = "Declared In Code")
- {
- mCachedControlPtr = LLControlCache<T>::getInstance(name);
- if (mCachedControlPtr.isNull())
- {
- mCachedControlPtr = new LLControlCache<T>(group, name, default_value, comment);
- }
- }
- LLCachedControl(LLControlGroup& group,
- const std::string& name)
- {
- mCachedControlPtr = LLControlCache<T>::getInstance(name);
- if (mCachedControlPtr.isNull())
- {
- mCachedControlPtr = new LLControlCache<T>(group, name);
- }
- }
- operator const T&() const { return mCachedControlPtr->getValue(); }
- operator boost::function<const T&()> () const { return boost::function<const T&()>(*this); }
- const T& operator()() { return mCachedControlPtr->getValue(); }
- private:
- LLPointer<LLControlCache<T> > mCachedControlPtr;
- };
- template <> eControlType get_control_type<U32>();
- template <> eControlType get_control_type<S32>();
- template <> eControlType get_control_type<F32>();
- template <> eControlType get_control_type<bool>();
- // Yay BOOL, its really an S32.
- //template <> eControlType get_control_type<BOOL> ()
- template <> eControlType get_control_type<std::string>();
- template <> eControlType get_control_type<LLVector3>();
- template <> eControlType get_control_type<LLVector3d>();
- template <> eControlType get_control_type<LLRect>();
- template <> eControlType get_control_type<LLColor4>();
- template <> eControlType get_control_type<LLColor3>();
- template <> eControlType get_control_type<LLSD>();
- template <> LLSD convert_to_llsd<U32>(const U32& in);
- template <> LLSD convert_to_llsd<LLVector3>(const LLVector3& in);
- template <> LLSD convert_to_llsd<LLVector3d>(const LLVector3d& in);
- template <> LLSD convert_to_llsd<LLRect>(const LLRect& in);
- template <> LLSD convert_to_llsd<LLColor4>(const LLColor4& in);
- template <> LLSD convert_to_llsd<LLColor3>(const LLColor3& in);
- template<> std::string convert_from_llsd<std::string>(const LLSD& sd, eControlType type, const std::string& control_name);
- template<> LLWString convert_from_llsd<LLWString>(const LLSD& sd, eControlType type, const std::string& control_name);
- template<> LLVector3 convert_from_llsd<LLVector3>(const LLSD& sd, eControlType type, const std::string& control_name);
- template<> LLVector3d convert_from_llsd<LLVector3d>(const LLSD& sd, eControlType type, const std::string& control_name);
- template<> LLRect convert_from_llsd<LLRect>(const LLSD& sd, eControlType type, const std::string& control_name);
- template<> bool convert_from_llsd<bool>(const LLSD& sd, eControlType type, const std::string& control_name);
- template<> S32 convert_from_llsd<S32>(const LLSD& sd, eControlType type, const std::string& control_name);
- template<> F32 convert_from_llsd<F32>(const LLSD& sd, eControlType type, const std::string& control_name);
- template<> U32 convert_from_llsd<U32>(const LLSD& sd, eControlType type, const std::string& control_name);
- template<> LLColor3 convert_from_llsd<LLColor3>(const LLSD& sd, eControlType type, const std::string& control_name);
- template<> LLColor4 convert_from_llsd<LLColor4>(const LLSD& sd, eControlType type, const std::string& control_name);
- template<> LLSD convert_from_llsd<LLSD>(const LLSD& sd, eControlType type, const std::string& control_name);
- //#define TEST_CACHED_CONTROL 1
- #ifdef TEST_CACHED_CONTROL
- void test_cached_control();
- #endif // TEST_CACHED_CONTROL
- #endif