diff options
author | Kent Quirk <q@lindenlab.com> | 2009-01-05 18:59:12 +0000 |
---|---|---|
committer | Kent Quirk <q@lindenlab.com> | 2009-01-05 18:59:12 +0000 |
commit | 667ca55bad0108c4bdf8f007b89e1a52fc766aad (patch) | |
tree | 7bd62ac8d9af079c3994565f3f200ccc250bbc28 /indra/llui/llui.h | |
parent | 95f365789f4cebc7bd97ccefd538f14d481a8373 (diff) |
svn merge -r106715:HEAD svn+ssh://svn.lindenlab.com/svn/linden/branches/q/notifications-merge-r106715 . QAR-1149 -- Final merge of notifications to trunk.
Diffstat (limited to 'indra/llui/llui.h')
-rw-r--r-- | indra/llui/llui.h | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/indra/llui/llui.h b/indra/llui/llui.h index e2629ee2a4..4366c38740 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -42,6 +42,7 @@ #include "llgl.h" // *TODO: break this dependency #include <stack> //#include "llimagegl.h" +#include <boost/signal.hpp> // LLUIFactory #include "llsd.h" @@ -150,11 +151,13 @@ typedef void (*LLUIAudioCallback)(const LLUUID& uuid); class LLUI { + LOG_CLASS(LLUI); public: // // Methods // static void initClass(LLControlGroup* config, + LLControlGroup* ignores, LLControlGroup* colors, LLImageProviderInterface* image_provider, LLUIAudioCallback audio_callback = NULL, @@ -190,6 +193,7 @@ public: // Data // static LLControlGroup* sConfigGroup; + static LLControlGroup* sIgnoresGroup; static LLControlGroup* sColorsGroup; static LLImageProviderInterface* sImageProvider; static LLUIAudioCallback sAudioCallback; @@ -597,4 +601,237 @@ public: virtual void cleanUp() = 0; }; +// This mix-in class adds support for tracking all instances of the specificed class parameter T +// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup +// If KEY is not provided, then instances are stored in a simple list +template<typename T, typename KEY = T*> +class LLInstanceTracker : boost::noncopyable +{ +public: + typedef typename std::map<KEY, T*>::iterator instance_iter; + typedef typename std::map<KEY, T*>::const_iterator instance_const_iter; + + static T* getInstance(KEY k) { instance_iter found = sInstances.find(k); return (found == sInstances.end()) ? NULL : found->second; } + + static instance_iter beginInstances() { return sInstances.begin(); } + static instance_iter endInstances() { return sInstances.end(); } + static S32 instanceCount() { return sInstances.size(); } +protected: + LLInstanceTracker(KEY key) { add(key); } + virtual ~LLInstanceTracker() { remove(); } + virtual void setKey(KEY key) { remove(); add(key); } + virtual const KEY& getKey() const { return mKey; } + +private: + void add(KEY key) + { + mKey = key; + sInstances[key] = static_cast<T*>(this); + } + void remove() { sInstances.erase(mKey); } + +private: + + KEY mKey; + static std::map<KEY, T*> sInstances; +}; + +template<typename T> +class LLInstanceTracker<T, T*> : boost::noncopyable +{ +public: + typedef typename std::set<T*>::iterator instance_iter; + typedef typename std::set<T*>::const_iterator instance_const_iter; + + static instance_iter instancesBegin() { return sInstances.begin(); } + static instance_iter instancesEnd() { return sInstances.end(); } + static S32 instanceCount() { return sInstances.size(); } + +protected: + LLInstanceTracker() { sInstances.insert(static_cast<T*>(this)); } + virtual ~LLInstanceTracker() { sInstances.erase(static_cast<T*>(this)); } + + static std::set<T*> sInstances; +}; + +template <typename T, typename KEY> std::map<KEY, T*> LLInstanceTracker<T, KEY>::sInstances; +template <typename T> std::set<T*> LLInstanceTracker<T, T*>::sInstances; + +class LLCallbackRegistry +{ +public: + typedef boost::signal<void()> callback_signal_t; + + void registerCallback(const callback_signal_t::slot_type& slot) + { + mCallbacks.connect(slot); + } + + void fireCallbacks() + { + mCallbacks(); + } + +private: + callback_signal_t mCallbacks; +}; + +class LLInitClassList : + public LLCallbackRegistry, + public LLSingleton<LLInitClassList> +{ + friend class LLSingleton<LLInitClassList>; +private: + LLInitClassList() {} +}; + +class LLDestroyClassList : + public LLCallbackRegistry, + public LLSingleton<LLDestroyClassList> +{ + friend class LLSingleton<LLDestroyClassList>; +private: + LLDestroyClassList() {} +}; + +template<typename T> +class LLRegisterWith +{ +public: + LLRegisterWith(boost::function<void ()> func) + { + T::instance().registerCallback(func); + } + + // this avoids a MSVC bug where non-referenced static members are "optimized" away + // even if their constructors have side effects + void reference() + { + S32 dummy; + dummy = 0; + } +}; + +template<typename T> +class LLInitClass +{ +public: + LLInitClass() { sRegister.reference(); } + + static LLRegisterWith<LLInitClassList> sRegister; +private: + + static void initClass() + { + llerrs << "No static initClass() method defined for " << typeid(T).name() << llendl; + } +}; + +template<typename T> +class LLDestroyClass +{ +public: + LLDestroyClass() { sRegister.reference(); } + + static LLRegisterWith<LLDestroyClassList> sRegister; +private: + + static void destroyClass() + { + llerrs << "No static destroyClass() method defined for " << typeid(T).name() << llendl; + } +}; + +template <typename T> LLRegisterWith<LLInitClassList> LLInitClass<T>::sRegister(&T::initClass); +template <typename T> LLRegisterWith<LLDestroyClassList> LLDestroyClass<T>::sRegister(&T::destroyClass); + + +template <typename DERIVED> +class LLParamBlock +{ +protected: + LLParamBlock() { sBlock = (DERIVED*)this; } + + typedef typename boost::add_const<DERIVED>::type Tconst; + + template <typename T> + class LLMandatoryParam + { + public: + typedef typename boost::add_const<T>::type T_const; + + LLMandatoryParam(T_const initial_val) : mVal(initial_val), mBlock(sBlock) {} + LLMandatoryParam(const LLMandatoryParam<T>& other) : mVal(other.mVal) {} + + DERIVED& operator ()(T_const set_value) { mVal = set_value; return *mBlock; } + operator T() const { return mVal; } + T operator=(T_const set_value) { mVal = set_value; return mVal; } + + private: + T mVal; + DERIVED* mBlock; + }; + + template <typename T> + class LLOptionalParam + { + public: + typedef typename boost::add_const<T>::type T_const; + + LLOptionalParam(T_const initial_val) : mVal(initial_val), mBlock(sBlock) {} + LLOptionalParam() : mBlock(sBlock) {} + LLOptionalParam(const LLOptionalParam<T>& other) : mVal(other.mVal) {} + + DERIVED& operator ()(T_const set_value) { mVal = set_value; return *mBlock; } + operator T() const { return mVal; } + T operator=(T_const set_value) { mVal = set_value; return mVal; } + + private: + T mVal; + DERIVED* mBlock; + }; + + // specialization that requires initialization for reference types + template <typename T> + class LLOptionalParam <T&> + { + public: + typedef typename boost::add_const<T&>::type T_const; + + LLOptionalParam(T_const initial_val) : mVal(initial_val), mBlock(sBlock) {} + LLOptionalParam(const LLOptionalParam<T&>& other) : mVal(other.mVal) {} + + DERIVED& operator ()(T_const set_value) { mVal = set_value; return *mBlock; } + operator T&() const { return mVal; } + T& operator=(T_const set_value) { mVal = set_value; return mVal; } + + private: + T& mVal; + DERIVED* mBlock; + }; + + // specialization that initializes pointer params to NULL + template<typename T> + class LLOptionalParam<T*> + { + public: + typedef typename boost::add_const<T*>::type T_const; + + LLOptionalParam(T_const initial_val) : mVal(initial_val), mBlock(sBlock) {} + LLOptionalParam() : mVal((T*)NULL), mBlock(sBlock) {} + LLOptionalParam(const LLOptionalParam<T*>& other) : mVal(other.mVal) {} + + DERIVED& operator ()(T_const set_value) { mVal = set_value; return *mBlock; } + operator T*() const { return mVal; } + T* operator=(T_const set_value) { mVal = set_value; return mVal; } + private: + T* mVal; + DERIVED* mBlock; + }; + + static DERIVED* sBlock; +}; + +template <typename T> T* LLParamBlock<T>::sBlock = NULL; + #endif |