-Moved LLCachedControl stuff to llxui/llcontrol.h to ease usage in other projects.

-Fixed mistakes in LLCachedCOAControl revealed by GCC. Thanks Siana.
-LLCacheControl'd stuff related to postprocessing, which I may mess with later.

GCC... Sigh.
This commit is contained in:
unknown
2010-10-11 04:08:24 -05:00
parent fe9a3d2ba2
commit f46d8a767b
5 changed files with 185 additions and 168 deletions

View File

@@ -69,6 +69,11 @@ class LLColor4U;
const BOOL NO_PERSIST = FALSE;
// Saved at end of session
class LLControlGroup; //Defined further down
extern LLControlGroup gSavedSettings; //Default control group used in LLCachedControl
extern LLControlGroup *gCOASavedSettings; //Used in LLCachedCOAControl
typedef enum e_control_type
{
TYPE_U32 = 0,
@@ -242,4 +247,165 @@ public:
void resetWarnings();
};
//! Helper function for LLCachedControl
template <class T>
eControlType get_control_type(const T& in, LLSD& out)
{
llerrs << "Usupported control type: " << typeid(T).name() << "." << llendl;
return TYPE_COUNT;
}
//! Publish/Subscribe object to interact with LLControlGroups.
//! 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 LLCachedControl
{
T mCachedValue;
LLPointer<LLControlVariable> mControl;
boost::signals::connection mConnection;
LLControlGroup *mControlGroup;
public:
LLCachedControl(const std::string& name, const T& default_value, LLControlGroup *group, const std::string& comment = "Declared In Code")
{Init(name,default_value,comment,*group);} //for gSavedPerAccountSettings, etc
LLCachedControl(const std::string& name, const T& default_value, LLControlGroup &group, const std::string& comment = "Declared In Code")
{Init(name,default_value,comment,group);} //for LLUI::sConfigGroup, etc
LLCachedControl(const std::string& name,
const T& default_value,
const std::string& comment = "Declared In Code",
LLControlGroup &group = gSavedSettings)
{Init(name,default_value,comment,group);} //for default (gSavedSettings)
private:
//Pulled out of ctor due to problems with initializer lists in template classes
void Init( const std::string& name,
const T& default_value,
const std::string& comment,
LLControlGroup &group )
{
mControlGroup = &group;
mControl = mControlGroup->getControl(name);
if(mControl.isNull())
{
declareTypedControl(*mControlGroup, name, default_value, comment);
mControl = mControlGroup->getControl(name);
if(mControl.isNull())
{
llerrs << "The control could not be created!!!" << llendl;
}
mCachedValue = default_value;
}
else
{
mCachedValue = (const T&)mControl->getValue();
}
// Add a listener to the controls signal...
// and store the connection...
mConnection = mControl->getSignal()->connect(
boost::bind(&LLCachedControl<T>::handleValueChange, this, _1)
);
}
public:
~LLCachedControl()
{
if(mConnection.connected())
{
mConnection.disconnect();
}
}
LLCachedControl& operator =(const T& newvalue)
{
setTypeValue(*mControl, newvalue);
return *this;
}
operator const T&() { return mCachedValue; }
LLPointer<LLControlVariable> getControl() const
{
return mControl;
}
private:
void declareTypedControl(LLControlGroup& group,
const std::string& name,
const T& default_value,
const std::string& comment)
{
LLSD init_value;
eControlType type = get_control_type<T>(default_value, init_value);
if(type < TYPE_COUNT)
{
group.declareControl(name, type, init_value, comment, FALSE);
}
}
bool handleValueChange(const LLSD& newvalue)
{
mCachedValue = (const T &)newvalue;
return true;
}
void setTypeValue(LLControlVariable& c, const T& v)
{
// Implicit conversion from T to LLSD...
c.set(v);
}
};
//Easiest way without messing with LLCachedControl even more..
template <class T>
class LLCachedCOAControl
{
LLCachedControl<T> *mCachedControl;
boost::signals::connection mCOAConnection;
const std::string mName;
const std::string mComment;
const T mDefault;
public:
LLCachedCOAControl(const std::string& name, const T& default_value,const std::string& comment = "Declared In Code")
: mName(name),mDefault(default_value),mComment(comment)
{
mCachedControl = new LLCachedControl<T>(mName,mDefault,gCOASavedSettings,mComment);
static LLCachedControl<bool> settings_per_account("AscentStoreSettingsPerAccount",false);
mCOAConnection = settings_per_account.getControl()->getSignal()->connect(
boost::bind(&LLCachedCOAControl<T>::handleCOAValueChange, this, _1));
}
~LLCachedCOAControl()
{
if(mCachedControl)
delete mCachedControl;
if(mCOAConnection.connected())
mCOAConnection.disconnect();
}
bool handleCOAValueChange(const LLSD& newvalue)
{
if(mCachedControl)
delete mCachedControl;
mCachedControl = new LLCachedControl<T>(mName,mDefault,gCOASavedSettings,mComment);
return true;
}
operator const T&() { return *mCachedControl; }
};
//Following is actually defined in newview/llviewercontrol.cpp, but extern access is fine (Unless GCC bites me)
template <> eControlType get_control_type<U32>(const U32& in, LLSD& out);
template <> eControlType get_control_type<S32>(const S32& in, LLSD& out);
template <> eControlType get_control_type<F32>(const F32& in, LLSD& out);
template <> eControlType get_control_type<bool> (const bool& in, LLSD& out);
// Yay BOOL, its really an S32.
//template <> eControlType get_control_type<BOOL> (const BOOL& in, LLSD& out)
template <> eControlType get_control_type<std::string>(const std::string& in, LLSD& out);
template <> eControlType get_control_type<LLVector3>(const LLVector3& in, LLSD& out);
template <> eControlType get_control_type<LLVector3d>(const LLVector3d& in, LLSD& out);
template <> eControlType get_control_type<LLRect>(const LLRect& in, LLSD& out);
template <> eControlType get_control_type<LLColor4>(const LLColor4& in, LLSD& out);
template <> eControlType get_control_type<LLColor3>(const LLColor3& in, LLSD& out);
template <> eControlType get_control_type<LLColor4U>(const LLColor4U& in, LLSD& out);
template <> eControlType get_control_type<LLSD>(const LLSD& in, LLSD& out);
#endif