Implement IGUIObject settings as a template class and IGUIObject::AddSetting as a template function.

This means the type information is available for all methods operating
with the setting type, which is easier for the authors, allows for
compile-time checks and optimizations.
Remove the enum that was used to indirectly obtain the setting type at
runtime.
Revises SGUISetting and enum from e326ebae46 (5122b0f906),
std::function from 82f1d2718b.

Differential Revision: https://code.wildfiregames.com/D2145
Tested on: gcc, clang, VS2015, Jenkins

This was SVN commit r22604.
This commit is contained in:
elexis 2019-08-04 02:20:08 +00:00
parent 5a1da77ce4
commit 85a622b13a
19 changed files with 313 additions and 392 deletions

View File

@ -25,27 +25,27 @@
CButton::CButton(CGUI* pGUI)
: IGUIObject(pGUI), IGUIButtonBehavior(pGUI), IGUITextOwner(pGUI)
{
AddSetting(GUIST_float, "buffer_zone");
AddSetting(GUIST_CGUIString, "caption");
AddSetting(GUIST_int, "cell_id");
AddSetting(GUIST_CStrW, "font");
AddSetting(GUIST_CStrW, "sound_disabled");
AddSetting(GUIST_CStrW, "sound_enter");
AddSetting(GUIST_CStrW, "sound_leave");
AddSetting(GUIST_CStrW, "sound_pressed");
AddSetting(GUIST_CStrW, "sound_released");
AddSetting(GUIST_CGUISpriteInstance, "sprite");
AddSetting(GUIST_CGUISpriteInstance, "sprite_over");
AddSetting(GUIST_CGUISpriteInstance, "sprite_pressed");
AddSetting(GUIST_CGUISpriteInstance, "sprite_disabled");
AddSetting(GUIST_EAlign, "text_align");
AddSetting(GUIST_EVAlign, "text_valign");
AddSetting(GUIST_CGUIColor, "textcolor");
AddSetting(GUIST_CGUIColor, "textcolor_over");
AddSetting(GUIST_CGUIColor, "textcolor_pressed");
AddSetting(GUIST_CGUIColor, "textcolor_disabled");
AddSetting(GUIST_CStrW, "tooltip");
AddSetting(GUIST_CStr, "tooltip_style");
AddSetting<float>("buffer_zone");
AddSetting<CGUIString>("caption");
AddSetting<int>("cell_id");
AddSetting<CStrW>("font");
AddSetting<CStrW>("sound_disabled");
AddSetting<CStrW>("sound_enter");
AddSetting<CStrW>("sound_leave");
AddSetting<CStrW>("sound_pressed");
AddSetting<CStrW>("sound_released");
AddSetting<CGUISpriteInstance>("sprite");
AddSetting<CGUISpriteInstance>("sprite_over");
AddSetting<CGUISpriteInstance>("sprite_pressed");
AddSetting<CGUISpriteInstance>("sprite_disabled");
AddSetting<EAlign>("text_align");
AddSetting<EVAlign>("text_valign");
AddSetting<CGUIColor>("textcolor");
AddSetting<CGUIColor>("textcolor_over");
AddSetting<CGUIColor>("textcolor_pressed");
AddSetting<CGUIColor>("textcolor_disabled");
AddSetting<CStrW>("tooltip");
AddSetting<CStr>("tooltip_style");
// Add text
AddText(new SGUIText());

View File

@ -32,15 +32,15 @@
CChart::CChart(CGUI* pGUI)
: IGUIObject(pGUI), IGUITextOwner(pGUI)
{
AddSetting(GUIST_CGUIColor, "axis_color");
AddSetting(GUIST_float, "axis_width");
AddSetting(GUIST_float, "buffer_zone");
AddSetting(GUIST_CStrW, "font");
AddSetting(GUIST_CStrW, "format_x");
AddSetting(GUIST_CStrW, "format_y");
AddSetting(GUIST_CGUIList, "series_color");
AddSetting(GUIST_CGUISeries, "series");
AddSetting(GUIST_EAlign, "text_align");
AddSetting<CGUIColor>("axis_color");
AddSetting<float>("axis_width");
AddSetting<float>("buffer_zone");
AddSetting<CStrW>("font");
AddSetting<CStrW>("format_x");
AddSetting<CStrW>("format_y");
AddSetting<CGUIList>("series_color");
AddSetting<CGUISeries>("series");
AddSetting<EAlign>("text_align");
GUI<float>::GetSetting(this, "axis_width", m_AxisWidth);
GUI<CStrW>::GetSetting(this, "format_x", m_FormatX);

View File

@ -31,31 +31,31 @@
CCheckBox::CCheckBox(CGUI* pGUI)
: IGUIObject(pGUI), IGUITextOwner(pGUI), IGUIButtonBehavior(pGUI)
{
AddSetting(GUIST_float, "buffer_zone");
AddSetting(GUIST_CGUIString, "caption");
AddSetting(GUIST_int, "cell_id");
AddSetting(GUIST_bool, "checked");
AddSetting(GUIST_CStrW, "font");
AddSetting(GUIST_CStrW, "sound_disabled");
AddSetting(GUIST_CStrW, "sound_enter");
AddSetting(GUIST_CStrW, "sound_leave");
AddSetting(GUIST_CStrW, "sound_pressed");
AddSetting(GUIST_CStrW, "sound_released");
AddSetting(GUIST_CGUISpriteInstance, "sprite");
AddSetting(GUIST_CGUISpriteInstance, "sprite_over");
AddSetting(GUIST_CGUISpriteInstance, "sprite_pressed");
AddSetting(GUIST_CGUISpriteInstance, "sprite_disabled");
AddSetting(GUIST_CGUISpriteInstance, "sprite2");
AddSetting(GUIST_CGUISpriteInstance, "sprite2_over");
AddSetting(GUIST_CGUISpriteInstance, "sprite2_pressed");
AddSetting(GUIST_CGUISpriteInstance, "sprite2_disabled");
AddSetting(GUIST_float, "square_side");
AddSetting(GUIST_CGUIColor, "textcolor");
AddSetting(GUIST_CGUIColor, "textcolor_over");
AddSetting(GUIST_CGUIColor, "textcolor_pressed");
AddSetting(GUIST_CGUIColor, "textcolor_disabled");
AddSetting(GUIST_CStrW, "tooltip");
AddSetting(GUIST_CStr, "tooltip_style");
AddSetting<float>("buffer_zone");
AddSetting<CGUIString>("caption");
AddSetting<int>("cell_id");
AddSetting<bool>("checked");
AddSetting<CStrW>("font");
AddSetting<CStrW>("sound_disabled");
AddSetting<CStrW>("sound_enter");
AddSetting<CStrW>("sound_leave");
AddSetting<CStrW>("sound_pressed");
AddSetting<CStrW>("sound_released");
AddSetting<CGUISpriteInstance>("sprite");
AddSetting<CGUISpriteInstance>("sprite_over");
AddSetting<CGUISpriteInstance>("sprite_pressed");
AddSetting<CGUISpriteInstance>("sprite_disabled");
AddSetting<CGUISpriteInstance>("sprite2");
AddSetting<CGUISpriteInstance>("sprite2_over");
AddSetting<CGUISpriteInstance>("sprite2_pressed");
AddSetting<CGUISpriteInstance>("sprite2_disabled");
AddSetting<float>("square_side");
AddSetting<CGUIColor>("textcolor");
AddSetting<CGUIColor>("textcolor_over");
AddSetting<CGUIColor>("textcolor_pressed");
AddSetting<CGUIColor>("textcolor_disabled");
AddSetting<CStrW>("tooltip");
AddSetting<CStr>("tooltip_style");
AddText(new SGUIText());
}

View File

@ -30,30 +30,30 @@ CDropDown::CDropDown(CGUI* pGUI)
: CList(pGUI), IGUIObject(pGUI),
m_Open(false), m_HideScrollBar(false), m_ElementHighlight(-1)
{
AddSetting(GUIST_float, "button_width");
AddSetting(GUIST_float, "dropdown_size");
AddSetting(GUIST_float, "dropdown_buffer");
AddSetting(GUIST_uint, "minimum_visible_items");
// AddSetting(GUIST_CStrW, "font");
AddSetting(GUIST_CStrW, "sound_closed");
AddSetting(GUIST_CStrW, "sound_disabled");
AddSetting(GUIST_CStrW, "sound_enter");
AddSetting(GUIST_CStrW, "sound_leave");
AddSetting(GUIST_CStrW, "sound_opened");
AddSetting(GUIST_CGUISpriteInstance, "sprite"); // Background that sits around the size
AddSetting(GUIST_CGUISpriteInstance, "sprite_disabled");
AddSetting(GUIST_CGUISpriteInstance, "sprite_list"); // Background of the drop down list
AddSetting(GUIST_CGUISpriteInstance, "sprite2"); // Button that sits to the right
AddSetting(GUIST_CGUISpriteInstance, "sprite2_over");
AddSetting(GUIST_CGUISpriteInstance, "sprite2_pressed");
AddSetting(GUIST_CGUISpriteInstance, "sprite2_disabled");
AddSetting(GUIST_EVAlign, "text_valign");
AddSetting<float>("button_width");
AddSetting<float>("dropdown_size");
AddSetting<float>("dropdown_buffer");
AddSetting<uint>("minimum_visible_items");
// AddSetting<CStrW, "font");
AddSetting<CStrW>("sound_closed");
AddSetting<CStrW>("sound_disabled");
AddSetting<CStrW>("sound_enter");
AddSetting<CStrW>("sound_leave");
AddSetting<CStrW>("sound_opened");
AddSetting<CGUISpriteInstance>("sprite"); // Background that sits around the size
AddSetting<CGUISpriteInstance>("sprite_disabled");
AddSetting<CGUISpriteInstance>("sprite_list"); // Background of the drop down list
AddSetting<CGUISpriteInstance>("sprite2"); // Button that sits to the right
AddSetting<CGUISpriteInstance>("sprite2_over");
AddSetting<CGUISpriteInstance>("sprite2_pressed");
AddSetting<CGUISpriteInstance>("sprite2_disabled");
AddSetting<EVAlign>("text_valign");
// Add these in CList! And implement TODO
//AddSetting(GUIST_CGUIColor, "textcolor_over");
//AddSetting(GUIST_CGUIColor, "textcolor_pressed");
AddSetting(GUIST_CGUIColor, "textcolor_selected");
AddSetting(GUIST_CGUIColor, "textcolor_disabled");
//AddSetting<CGUIColor>("textcolor_over");
//AddSetting<CGUIColor>("textcolor_pressed");
AddSetting<CGUIColor>("textcolor_selected");
AddSetting<CGUIColor>("textcolor_disabled");
// Scrollbar is forced to be true.
GUI<bool>::SetSetting(this, "scrollbar", true);

View File

@ -26,10 +26,10 @@
CImage::CImage(CGUI* pGUI)
: IGUIObject(pGUI)
{
AddSetting(GUIST_CGUISpriteInstance, "sprite");
AddSetting(GUIST_int, "cell_id");
AddSetting(GUIST_CStrW, "tooltip");
AddSetting(GUIST_CStr, "tooltip_style");
AddSetting<CGUISpriteInstance>("sprite");
AddSetting<int>("cell_id");
AddSetting<CStrW>("tooltip");
AddSetting<CStr>("tooltip_style");
}
CImage::~CImage()

View File

@ -45,24 +45,24 @@ CInput::CInput(CGUI* pGUI)
m_PrevTime(0.0), m_CursorVisState(true), m_CursorBlinkRate(0.5), m_ComposingText(false),
m_iComposedLength(0), m_iComposedPos(0), m_iInsertPos(0), m_Readonly(false)
{
AddSetting(GUIST_int, "buffer_position");
AddSetting(GUIST_float, "buffer_zone");
AddSetting(GUIST_CStrW, "caption");
AddSetting(GUIST_int, "cell_id");
AddSetting(GUIST_CStrW, "font");
AddSetting(GUIST_CStrW, "mask_char");
AddSetting(GUIST_bool, "mask");
AddSetting(GUIST_int, "max_length");
AddSetting(GUIST_bool, "multiline");
AddSetting(GUIST_bool, "readonly");
AddSetting(GUIST_bool, "scrollbar");
AddSetting(GUIST_CStr, "scrollbar_style");
AddSetting(GUIST_CGUISpriteInstance, "sprite");
AddSetting(GUIST_CGUISpriteInstance, "sprite_selectarea");
AddSetting(GUIST_CGUIColor, "textcolor");
AddSetting(GUIST_CGUIColor, "textcolor_selected");
AddSetting(GUIST_CStrW, "tooltip");
AddSetting(GUIST_CStr, "tooltip_style");
AddSetting<i32>("buffer_position");
AddSetting<float>("buffer_zone");
AddSetting<CStrW>("caption");
AddSetting<i32>("cell_id");
AddSetting<CStrW>("font");
AddSetting<CStrW>("mask_char");
AddSetting<bool>("mask");
AddSetting<i32>("max_length");
AddSetting<bool>("multiline");
AddSetting<bool>("readonly");
AddSetting<bool>("scrollbar");
AddSetting<CStr>("scrollbar_style");
AddSetting<CGUISpriteInstance>("sprite");
AddSetting<CGUISpriteInstance>("sprite_selectarea");
AddSetting<CGUIColor>("textcolor");
AddSetting<CGUIColor>("textcolor_selected");
AddSetting<CStrW>("tooltip");
AddSetting<CStr>("tooltip_style");
CFG_GET_VAL("gui.cursorblinkrate", m_CursorBlinkRate);

View File

@ -32,27 +32,27 @@ CList::CList(CGUI* pGUI)
m_Modified(false), m_PrevSelectedItem(-1), m_LastItemClickTime(0)
{
// Add sprite_disabled! TODO
AddSetting(GUIST_float, "buffer_zone");
AddSetting(GUIST_CStrW, "font");
AddSetting(GUIST_bool, "scrollbar");
AddSetting(GUIST_CStr, "scrollbar_style");
AddSetting(GUIST_CStrW, "sound_disabled");
AddSetting(GUIST_CStrW, "sound_selected");
AddSetting(GUIST_CGUISpriteInstance, "sprite");
AddSetting(GUIST_CGUISpriteInstance, "sprite_selectarea");
AddSetting(GUIST_int, "cell_id");
AddSetting(GUIST_EAlign, "text_align");
AddSetting(GUIST_CGUIColor, "textcolor");
AddSetting(GUIST_CGUIColor, "textcolor_selected");
AddSetting(GUIST_int, "selected"); // Index selected. -1 is none.
AddSetting(GUIST_bool, "auto_scroll");
AddSetting(GUIST_int, "hovered");
AddSetting(GUIST_CStrW, "tooltip");
AddSetting(GUIST_CStr, "tooltip_style");
AddSetting<float>("buffer_zone");
AddSetting<CStrW>("font");
AddSetting<bool>("scrollbar");
AddSetting<CStr>("scrollbar_style");
AddSetting<CStrW>("sound_disabled");
AddSetting<CStrW>("sound_selected");
AddSetting<CGUISpriteInstance>("sprite");
AddSetting<CGUISpriteInstance>("sprite_selectarea");
AddSetting<int>( "cell_id");
AddSetting<EAlign>("text_align");
AddSetting<CGUIColor>("textcolor");
AddSetting<CGUIColor>("textcolor_selected");
AddSetting<int>( "selected"); // Index selected. -1 is none.
AddSetting<bool>("auto_scroll");
AddSetting<int>( "hovered");
AddSetting<CStrW>("tooltip");
AddSetting<CStr>("tooltip_style");
// Each list item has both a name (in 'list') and an associated data string (in 'list_data')
AddSetting(GUIST_CGUIList, "list");
AddSetting(GUIST_CGUIList, "list_data"); // TODO: this should be a list of raw strings, not of CGUIStrings
AddSetting<CGUIList>("list");
AddSetting<CGUIList>("list_data");
GUI<bool>::SetSetting(this, "scrollbar", false);
GUI<int>::SetSetting(this, "selected", -1);

View File

@ -30,13 +30,13 @@ const CPos COLUMN_SHIFT = CPos(0, 4);
COList::COList(CGUI* pGUI)
: CList(pGUI), IGUIObject(pGUI)
{
AddSetting(GUIST_CGUISpriteInstance, "sprite_heading");
AddSetting(GUIST_bool, "sortable"); // The actual sorting is done in JS for more versatility
AddSetting(GUIST_CStr, "selected_column");
AddSetting(GUIST_int, "selected_column_order");
AddSetting(GUIST_CGUISpriteInstance, "sprite_asc"); // Show the order of sorting
AddSetting(GUIST_CGUISpriteInstance, "sprite_desc");
AddSetting(GUIST_CGUISpriteInstance, "sprite_not_sorted");
AddSetting<CGUISpriteInstance>("sprite_heading");
AddSetting<bool>("sortable"); // The actual sorting is done in JS for more versatility
AddSetting<CStr>("selected_column");
AddSetting<int>("selected_column_order");
AddSetting<CGUISpriteInstance>("sprite_asc"); // Show the order of sorting
AddSetting<CGUISpriteInstance>("sprite_desc");
AddSetting<CGUISpriteInstance>("sprite_not_sorted");
}
void COList::SetupText()
@ -299,8 +299,8 @@ bool COList::HandleAdditionalChildren(const XMBElement& child, CXeromyces* pFile
m_Columns.push_back(column);
AddSetting(GUIST_CGUIList, "list_" + column.m_Id);
AddSetting(GUIST_bool, "hidden_" + column.m_Id);
AddSetting<CGUIList>("list_" + column.m_Id);
AddSetting<bool>("hidden_" + column.m_Id);
GUI<bool>::SetSetting(this, "hidden_" + column.m_Id, hidden);
SetupText();

View File

@ -25,11 +25,11 @@
CProgressBar::CProgressBar(CGUI* pGUI)
: IGUIObject(pGUI)
{
AddSetting(GUIST_CGUISpriteInstance, "sprite_background");
AddSetting(GUIST_CGUISpriteInstance, "sprite_bar");
AddSetting(GUIST_float, "caption"); // aka value from 0 to 100
AddSetting(GUIST_CStrW, "tooltip");
AddSetting(GUIST_CStr, "tooltip_style");
AddSetting<CGUISpriteInstance>("sprite_background");
AddSetting<CGUISpriteInstance>("sprite_bar");
AddSetting<float>("caption"); // aka value from 0 to 100
AddSetting<CStrW>("tooltip");
AddSetting<CStr>("tooltip_style");
}
CProgressBar::~CProgressBar()

View File

@ -21,17 +21,16 @@
#include "lib/ogl.h"
#include "ps/CLogger.h"
CSlider::CSlider(CGUI* pGUI)
: IGUIObject(pGUI), m_IsPressed(false), m_ButtonSide(0)
{
AddSetting(GUIST_float, "value");
AddSetting(GUIST_float, "min_value");
AddSetting(GUIST_float, "max_value");
AddSetting(GUIST_int, "cell_id");
AddSetting(GUIST_CGUISpriteInstance, "sprite");
AddSetting(GUIST_CGUISpriteInstance, "sprite_bar");
AddSetting(GUIST_float, "button_width");
AddSetting<float>("value");
AddSetting<float>("min_value");
AddSetting<float>("max_value");
AddSetting<int>("cell_id");
AddSetting<CGUISpriteInstance>("sprite");
AddSetting<CGUISpriteInstance>("sprite_bar");
AddSetting<float>("button_width");
GUI<float>::GetSetting(this, "value", m_Value);
GUI<float>::GetSetting(this, "min_value", m_MinValue);

View File

@ -26,26 +26,26 @@
CText::CText(CGUI* pGUI)
: IGUIObject(pGUI), IGUIScrollBarOwner(pGUI), IGUITextOwner(pGUI)
{
AddSetting(GUIST_float, "buffer_zone");
AddSetting(GUIST_CGUIString, "caption");
AddSetting(GUIST_int, "cell_id");
AddSetting(GUIST_bool, "clip");
AddSetting(GUIST_CStrW, "font");
AddSetting(GUIST_bool, "scrollbar");
AddSetting(GUIST_CStr, "scrollbar_style");
AddSetting(GUIST_bool, "scroll_bottom");
AddSetting(GUIST_bool, "scroll_top");
AddSetting(GUIST_CGUISpriteInstance, "sprite");
AddSetting(GUIST_EAlign, "text_align");
AddSetting(GUIST_EVAlign, "text_valign");
AddSetting(GUIST_CGUIColor, "textcolor");
AddSetting(GUIST_CGUIColor, "textcolor_disabled");
AddSetting(GUIST_CStrW, "tooltip");
AddSetting(GUIST_CStr, "tooltip_style");
AddSetting<float>("buffer_zone");
AddSetting<CGUIString>("caption");
AddSetting<int>("cell_id");
AddSetting<bool>("clip");
AddSetting<CStrW>("font");
AddSetting<bool>("scrollbar");
AddSetting<CStr>("scrollbar_style");
AddSetting<bool>("scroll_bottom");
AddSetting<bool>("scroll_top");
AddSetting<CGUISpriteInstance>("sprite");
AddSetting<EAlign>("text_align");
AddSetting<EVAlign>("text_valign");
AddSetting<CGUIColor>("textcolor");
AddSetting<CGUIColor>("textcolor_disabled");
AddSetting<CStrW>("tooltip");
AddSetting<CStr>("tooltip_style");
// Private settings
AddSetting(GUIST_CStrW, "_icon_tooltip");
AddSetting(GUIST_CStr, "_icon_tooltip_style");
AddSetting<CStrW>("_icon_tooltip");
AddSetting<CStr>("_icon_tooltip_style");
//GUI<bool>::SetSetting(this, "ghost", true);
GUI<bool>::SetSetting(this, "scrollbar", false);

View File

@ -26,26 +26,26 @@ CTooltip::CTooltip(CGUI* pGUI)
: IGUIObject(pGUI), IGUITextOwner(pGUI)
{
// If the tooltip is an object by itself:
AddSetting(GUIST_float, "buffer_zone");
AddSetting(GUIST_CGUIString, "caption");
AddSetting(GUIST_CStrW, "font");
AddSetting(GUIST_CGUISpriteInstance, "sprite");
AddSetting(GUIST_int, "delay");
AddSetting(GUIST_CGUIColor, "textcolor");
AddSetting(GUIST_float, "maxwidth");
AddSetting(GUIST_CPos, "offset");
AddSetting(GUIST_EVAlign, "anchor");
AddSetting(GUIST_EAlign, "text_align");
AddSetting<float>("buffer_zone");
AddSetting<CGUIString>("caption");
AddSetting<CStrW>("font");
AddSetting<CGUISpriteInstance>("sprite");
AddSetting<int>("delay");
AddSetting<CGUIColor>("textcolor");
AddSetting<float>("maxwidth");
AddSetting<CPos>("offset");
AddSetting<EVAlign>("anchor");
AddSetting<EAlign>("text_align");
// This is used for tooltips that are hidden/revealed manually by scripts, rather than through the standard tooltip display mechanism
AddSetting(GUIST_bool, "independent");
AddSetting<bool>("independent");
// If the tooltip is just a reference to another object:
AddSetting(GUIST_CStr, "use_object");
AddSetting(GUIST_bool, "hide_object");
AddSetting<CStr>("use_object");
AddSetting<bool>("hide_object");
// Private settings:
// This is set by GUITooltip
AddSetting(GUIST_CPos, "_mousepos");
AddSetting<CPos>("_mousepos");
// Defaults
GUI<int>::SetSetting(this, "delay", 500);

View File

@ -26,8 +26,8 @@ to handle every possible type.
*/
TYPE(bool)
TYPE(int)
TYPE(uint)
TYPE(i32)
TYPE(u32)
TYPE(float)
TYPE(CGUIColor)
TYPE(CClientArea)

View File

@ -27,6 +27,41 @@
extern int g_xres, g_yres;
template<typename T>
CGUISetting<T>::CGUISetting(IGUIObject& pObject, const CStr& Name)
: m_pSetting(T()), m_Name(Name), m_pObject(pObject)
{
}
template<typename T>
bool CGUISetting<T>::FromString(const CStrW& Value, const bool& SkipMessage)
{
T settingValue;
if (!GUI<T>::ParseString(Value, settingValue))
return false;
GUI<T>::SetSetting(&m_pObject, m_Name, settingValue, SkipMessage);
return true;
};
template<typename T>
bool CGUISetting<T>::FromJSVal(JSContext* cx, JS::HandleValue Value)
{
T settingValue;
if (!ScriptInterface::FromJSVal<T>(cx, Value, settingValue))
return false;
GUI<T>::SetSetting(&m_pObject, m_Name, settingValue);
return true;
};
template<typename T>
void CGUISetting<T>::ToJSVal(JSContext* cx, JS::MutableHandleValue Value)
{
ScriptInterface::ToJSVal<T>(cx, Value, m_pSetting);
};
template <>
bool __ParseString<bool>(const CStrW& Value, bool& Output)
{
@ -272,28 +307,12 @@ CMatrix3D GetDefaultGuiMatrix()
return m;
}
#ifndef NDEBUG
#define TYPE(T) \
template<> void CheckType<T>(const IGUIObject* obj, const CStr& setting) { \
std::map<CStr, SGUISetting>::const_iterator it = obj->m_Settings.find(setting); \
if (it == obj->m_Settings.end() || it->second.m_Type != GUIST_##T) \
{ \
/* Abort now, to avoid corrupting everything by invalidly \
casting pointers */ \
DEBUG_DISPLAY_ERROR(L"FATAL ERROR: Inconsistent types in GUI"); \
} \
}
#include "GUItypes.h"
#undef TYPE
#endif
template <typename T>
PSRETURN GUI<T>::GetSettingPointer(const IGUIObject* pObject, const CStr& Setting, T*& Value)
{
ENSURE(pObject != NULL);
std::map<CStr, SGUISetting>::const_iterator it = pObject->m_Settings.find(Setting);
std::map<CStr, IGUISetting*>::const_iterator it = pObject->m_Settings.find(Setting);
if (it == pObject->m_Settings.end())
{
LOGWARNING("setting %s was not found on object %s",
@ -302,15 +321,11 @@ PSRETURN GUI<T>::GetSettingPointer(const IGUIObject* pObject, const CStr& Settin
return PSRETURN_GUI_InvalidSetting;
}
if (it->second.m_pSetting == NULL)
if (it->second == nullptr)
return PSRETURN_GUI_InvalidSetting;
#ifndef NDEBUG
CheckType<T>(pObject, Setting);
#endif
// Get value
Value = (T*)(it->second.m_pSetting);
Value = &(static_cast<CGUISetting<T>* >(it->second)->m_pSetting);
return PSRETURN_OK;
}
@ -330,7 +345,7 @@ PSRETURN GUI<T>::SetSetting(IGUIObject* pObject, const CStr& Setting, T& Value,
{
return SetSettingWrap(pObject, Setting, Value, SkipMessage,
[&pObject, &Setting, &Value]() {
*static_cast<T*>(pObject->m_Settings[Setting].m_pSetting) = std::move(Value);
static_cast<CGUISetting<T>* >(pObject->m_Settings[Setting])->m_pSetting = std::move(Value);
});
}
@ -339,7 +354,7 @@ PSRETURN GUI<T>::SetSetting(IGUIObject* pObject, const CStr& Setting, const T& V
{
return SetSettingWrap(pObject, Setting, Value, SkipMessage,
[&pObject, &Setting, &Value]() {
*static_cast<T*>(pObject->m_Settings[Setting].m_pSetting) = Value;
static_cast<CGUISetting<T>* >(pObject->m_Settings[Setting])->m_pSetting = Value;
});
}
@ -368,10 +383,6 @@ PSRETURN GUI<T>::SetSettingWrap(IGUIObject* pObject, const CStr& Setting, const
return PSRETURN_GUI_InvalidSetting;
}
#ifndef NDEBUG
CheckType<T>(pObject, Setting);
#endif
valueSet();
// Some settings needs special attention at change
@ -402,7 +413,9 @@ PSRETURN GUI<T>::SetSettingWrap(IGUIObject* pObject, const CStr& Setting, const
template PSRETURN GUI<T>::GetSettingPointer(const IGUIObject* pObject, const CStr& Setting, T*& Value); \
template PSRETURN GUI<T>::GetSetting(const IGUIObject* pObject, const CStr& Setting, T& Value); \
template PSRETURN GUI<T>::SetSetting(IGUIObject* pObject, const CStr& Setting, T& Value, const bool& SkipMessage); \
template PSRETURN GUI<T>::SetSetting(IGUIObject* pObject, const CStr& Setting, const T& Value, const bool& SkipMessage);
template PSRETURN GUI<T>::SetSetting(IGUIObject* pObject, const CStr& Setting, const T& Value, const bool& SkipMessage); \
template class CGUISetting<T>; \
#define GUITYPE_IGNORE_CGUISpriteInstance
#include "GUItypes.h"
#undef GUITYPE_IGNORE_CGUISpriteInstance
@ -414,3 +427,4 @@ PSRETURN GUI<T>::SetSettingWrap(IGUIObject* pObject, const CStr& Setting, const
// instead. (This is mainly useful to stop me accidentally using the wrong function.)
template PSRETURN GUI<CGUISpriteInstance>::GetSettingPointer(const IGUIObject* pObject, const CStr& Setting, CGUISpriteInstance*& Value);
template PSRETURN GUI<CGUISpriteInstance>::SetSetting(IGUIObject* pObject, const CStr& Setting, CGUISpriteInstance& Value, const bool& SkipMessage);
template class CGUISetting<CGUISpriteInstance>;

View File

@ -42,6 +42,69 @@ GUI util
class CClientArea;
class CGUIString;
class CMatrix3D;
template<typename T> class GUI;
class IGUISetting
{
public:
virtual ~IGUISetting() {};
/**
* Parses the given string and assigns to the setting value. Used for parsing XML attributes.
*/
virtual bool FromString(const CStrW& Value, const bool& SkipMessage) = 0;
/**
* Parses the given JS::Value using ScriptInterface::FromJSVal and assigns it to the setting data.
*/
virtual bool FromJSVal(JSContext* cx, JS::HandleValue Value) = 0;
/**
* Converts the setting data to a JS::Value using ScriptInterface::ToJSVal.
*/
virtual void ToJSVal(JSContext* cx, JS::MutableHandleValue Value) = 0;
};
template<typename T>
class CGUISetting : public IGUISetting
{
friend class GUI<T>;
public:
CGUISetting(IGUIObject& pObject, const CStr& Name);
/**
* Parses the given string and assigns to the setting value. Used for parsing XML attributes.
*/
bool FromString(const CStrW& Value, const bool& SkipMessage) override;
/**
* Parses the given JS::Value using ScriptInterface::FromJSVal and assigns it to the setting data.
*/
bool FromJSVal(JSContext* cx, JS::HandleValue Value) override;
/**
* Converts the setting data to a JS::Value using ScriptInterface::ToJSVal.
*/
void ToJSVal(JSContext* cx, JS::MutableHandleValue Value) override;
private:
/**
* The object that stores this setting.
*/
IGUIObject& m_pObject;
/**
* Property name identifying the setting.
*/
const CStr m_Name;
/**
* Holds the value of the setting..
*/
T m_pSetting;
};
template <typename T>
bool __ParseString(const CStrW& Value, T& tOutput);
@ -51,12 +114,6 @@ CMatrix3D GetDefaultGuiMatrix();
struct SGUIMessage;
#ifndef NDEBUG
// Used to ensure type-safety, sort of
template<typename T> void CheckType(const IGUIObject* obj, const CStr& setting);
#endif
/**
* Includes static functions that needs one template
* argument.

View File

@ -27,39 +27,20 @@
#include "ps/Profile.h"
#include "scriptinterface/ScriptInterface.h"
template<typename T>
void SGUISetting::Init(IGUIObject& pObject, const CStr& Name)
{
m_pSetting = new T();
m_FromJSVal = [Name, &pObject](JSContext* cx, JS::HandleValue v) {
T value;
if (!ScriptInterface::FromJSVal<T>(cx, v, value))
return false;
GUI<T>::SetSetting(&pObject, Name, value);
return true;
};
m_ToJSVal = [Name, this](JSContext* cx, JS::MutableHandleValue v) {
ScriptInterface::ToJSVal<T>(cx, v, *static_cast<T*>(m_pSetting));
};
}
IGUIObject::IGUIObject(CGUI* pGUI)
: m_pGUI(pGUI), m_pParent(NULL), m_MouseHovering(false), m_LastClickTime()
{
AddSetting(GUIST_bool, "enabled");
AddSetting(GUIST_bool, "hidden");
AddSetting(GUIST_CClientArea, "size");
AddSetting(GUIST_CStr, "style");
AddSetting(GUIST_CStr, "hotkey");
AddSetting(GUIST_float, "z");
AddSetting(GUIST_bool, "absolute");
AddSetting(GUIST_bool, "ghost");
AddSetting(GUIST_float, "aspectratio");
AddSetting(GUIST_CStrW, "tooltip");
AddSetting(GUIST_CStr, "tooltip_style");
AddSetting<bool>("enabled");
AddSetting<bool>("hidden");
AddSetting<CClientArea>("size");
AddSetting<CStr>("style");
AddSetting<CStr>("hotkey");
AddSetting<float>("z");
AddSetting<bool>("absolute");
AddSetting<bool>("ghost");
AddSetting<float>("aspectratio");
AddSetting<CStrW>("tooltip");
AddSetting<CStr>("tooltip_style");
// Setup important defaults
GUI<bool>::SetSetting(this, "hidden", false);
@ -70,16 +51,8 @@ IGUIObject::IGUIObject(CGUI* pGUI)
IGUIObject::~IGUIObject()
{
for (const std::pair<CStr, SGUISetting>& p : m_Settings)
switch (p.second.m_Type)
{
// delete() needs to know the type of the variable - never delete a void*
#define TYPE(t) case GUIST_##t: delete (t*)p.second.m_pSetting; break;
#include "GUItypes.h"
#undef TYPE
default:
debug_warn(L"Invalid setting type");
}
for (const std::pair<CStr, IGUISetting*>& p : m_Settings)
delete p.second;
if (!m_ScriptHandlers.empty())
JS_RemoveExtraGCRootsTracer(m_pGUI->GetScriptInterface()->GetJSRuntime(), Trace, this);
@ -150,34 +123,16 @@ void IGUIObject::Destroy()
// Is there anything besides the children to destroy?
}
void IGUIObject::AddSetting(const EGUISettingType& Type, const CStr& Name)
template<typename T>
void IGUIObject::AddSetting(const CStr& Name)
{
// Is name already taken?
if (m_Settings.count(Name) >= 1)
// This can happen due to inheritance
if (SettingExists(Name))
return;
// Construct, and set type
m_Settings[Name].m_Type = Type;
switch (Type)
{
#define TYPE(type) \
case GUIST_##type: \
m_Settings[Name].Init<type>(*this, Name);\
break;
// Construct the setting.
#include "GUItypes.h"
#undef TYPE
default:
debug_warn(L"IGUIObject::AddSetting failed, type not recognized!");
break;
}
m_Settings[Name] = new CGUISetting<T>(*this, Name);
}
bool IGUIObject::MouseOver()
{
if (!GetGUI())
@ -222,12 +177,7 @@ void IGUIObject::UpdateMouseOver(IGUIObject* const& pMouseOver)
bool IGUIObject::SettingExists(const CStr& Setting) const
{
// Because GetOffsets will direct dynamically defined
// classes with polymorphism to respective ms_SettingsInfo
// we need to make no further updates on this function
// in derived classes.
//return (GetSettingsInfo().count(Setting) >= 1);
return (m_Settings.count(Setting) >= 1);
return m_Settings.count(Setting) == 1;
}
PSRETURN IGUIObject::SetSetting(const CStr& Setting, const CStrW& Value, const bool& SkipMessage)
@ -235,46 +185,12 @@ PSRETURN IGUIObject::SetSetting(const CStr& Setting, const CStrW& Value, const b
if (!SettingExists(Setting))
return PSRETURN_GUI_InvalidSetting;
SGUISetting set = m_Settings[Setting];
#define TYPE(type) \
else if (set.m_Type == GUIST_##type) \
{ \
type _Value; \
if (!GUI<type>::ParseString(Value, _Value)) \
return PSRETURN_GUI_UnableToParse; \
GUI<type>::SetSetting(this, Setting, _Value, SkipMessage); \
}
if (0)
;
#include "GUItypes.h"
#undef TYPE
else
{
// Why does it always fail?
//return PS_FAIL;
return LogInvalidSettings(Setting);
}
return PSRETURN_OK;
}
PSRETURN IGUIObject::GetSettingType(const CStr& Setting, EGUISettingType& Type) const
{
if (!SettingExists(Setting))
return LogInvalidSettings(Setting);
if (m_Settings.find(Setting) == m_Settings.end())
return LogInvalidSettings(Setting);
Type = m_Settings.find(Setting)->second.m_Type;
if (!m_Settings[Setting]->FromString(Value, SkipMessage))
return PSRETURN_GUI_UnableToParse;
return PSRETURN_OK;
}
void IGUIObject::ChooseMouseOverAndClosest(IGUIObject*& pObject)
{
if (!MouseOver())
@ -570,8 +486,7 @@ void IGUIObject::TraceMember(JSTracer* trc)
JS_CallObjectTracer(trc, &handler.second, "IGUIObject::m_ScriptHandlers");
}
PSRETURN IGUIObject::LogInvalidSettings(const CStr8& Setting) const
{
LOGWARNING("IGUIObject: setting %s was not found on an object", Setting.c_str());
return PSRETURN_GUI_InvalidSetting;
}
// Instantiate templated functions:
#define TYPE(T) template void IGUIObject::AddSetting<T>(const CStr& Name);
#include "GUItypes.h"
#undef TYPE

View File

@ -36,60 +36,14 @@
#include <string>
#include <vector>
struct SGUISetting;
struct SGUIStyle;
class CGUI;
class JSObject;
class IGUISetting;
ERROR_TYPE(GUI, UnableToParse);
/**
* Setting Type
* @see SGUISetting
*
* For use of later macros, all names should be GUIST_ followed
* by the code name (case sensitive!).
*/
#define TYPE(T) GUIST_##T,
enum EGUISettingType
{
#include "GUItypes.h"
};
#undef TYPE
/**
* A GUI Setting is anything that can be inputted from XML as
* \<object\>-attributes (with exceptions). For instance:
* \<object style="null"\>
*
* "style" will be a SGUISetting.
*/
struct SGUISetting
{
SGUISetting() : m_pSetting(NULL) {}
/**
* Stores the instance of the setting type holding the setting data. Can be set from XML and JS.
*/
void *m_pSetting;
EGUISettingType m_Type;
template<typename T>
void Init(IGUIObject& pObject, const CStr& Name);
/**
* Parses the given JS::Value using ScriptInterface::FromJSVal and assigns it to the setting data.
*/
std::function<bool(JSContext* cx, JS::HandleValue v)> m_FromJSVal;
/**
* Converts the setting data to a JS::Value using ScriptInterface::ToJSVal.
*/
std::function<void(JSContext* cx, JS::MutableHandleValue v)> m_ToJSVal;
};
/**
* GUI object such as a button or an input-box.
* Abstract data type !
@ -190,9 +144,7 @@ public:
//@{
/**
* Checks if settings exists, only available for derived
* classes that has this set up, that's why the base
* class just returns false
* Returns whether there is a setting with the given name registered.
*
* @param Setting setting name
* @return True if settings exist.
@ -224,15 +176,6 @@ public:
*/
PSRETURN SetSetting(const CStr& Setting, const CStrW& Value, const bool& SkipMessage = false);
/**
* Retrieves the type of a named setting.
*
* @param Setting Setting by name
* @param Type Stores an EGUISettingType
* @return PSRETURN (PSRETURN_OK if successful)
*/
PSRETURN GetSettingType(const CStr& Setting, EGUISettingType& Type) const;
/**
* Set the script handler for a particular object-specific action
*
@ -273,7 +216,7 @@ protected:
* @param Type Setting type
* @param Name Setting reference name
*/
void AddSetting(const EGUISettingType& Type, const CStr& Name);
template<typename T> void AddSetting(const CStr& Name);
/**
* Calls Destroy on all children, and deallocates all memory.
@ -464,13 +407,6 @@ private:
// as parent.
bool IsRootObject() const;
/**
* Logs an invalid setting search and returns the correct return result
*
* @return the error result
*/
PSRETURN LogInvalidSettings(const CStr8& Setting) const;
static void Trace(JSTracer* trc, void* data)
{
reinterpret_cast<IGUIObject*>(data)->TraceMember(trc);
@ -520,7 +456,7 @@ protected:
* @see SetupSettings()
*/
public:
std::map<CStr, SGUISetting> m_Settings;
std::map<CStr, IGUISetting*> m_Settings;
protected:
// An object can't function stand alone

View File

@ -68,8 +68,8 @@ CMiniMap::CMiniMap(CGUI* pGUI) :
m_EntitiesDrawn(0), m_IndexArray(GL_STATIC_DRAW), m_VertexArray(GL_DYNAMIC_DRAW),
m_NextBlinkTime(0.0), m_PingDuration(25.0), m_BlinkState(false), m_WaterHeight(0.0)
{
AddSetting(GUIST_CStrW, "tooltip");
AddSetting(GUIST_CStr, "tooltip_style");
AddSetting<CStrW>("tooltip");
AddSetting<CStr>("tooltip_style");
m_Clicking = false;
m_MouseHovering = false;

View File

@ -116,7 +116,7 @@ bool JSI_IGUIObject::getProperty(JSContext* cx, JS::HandleObject obj, JS::Handle
}
else if (e->SettingExists(propName))
{
e->m_Settings[propName].m_ToJSVal(cx, vp);
e->m_Settings[propName]->ToJSVal(cx, vp);
return true;
}
@ -168,7 +168,7 @@ bool JSI_IGUIObject::setProperty(JSContext* cx, JS::HandleObject obj, JS::Handle
}
if (e->SettingExists(propName))
return e->m_Settings[propName].m_FromJSVal(cx, vp);
return e->m_Settings[propName]->FromJSVal(cx, vp);
JS_ReportError(cx, "Property '%s' does not exist!", propName.c_str());
return false;