1
0
forked from 0ad/0ad

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

View File

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

View File

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

View File

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

View File

@ -26,10 +26,10 @@
CImage::CImage(CGUI* pGUI) CImage::CImage(CGUI* pGUI)
: IGUIObject(pGUI) : IGUIObject(pGUI)
{ {
AddSetting(GUIST_CGUISpriteInstance, "sprite"); AddSetting<CGUISpriteInstance>("sprite");
AddSetting(GUIST_int, "cell_id"); AddSetting<int>("cell_id");
AddSetting(GUIST_CStrW, "tooltip"); AddSetting<CStrW>("tooltip");
AddSetting(GUIST_CStr, "tooltip_style"); AddSetting<CStr>("tooltip_style");
} }
CImage::~CImage() 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_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) m_iComposedLength(0), m_iComposedPos(0), m_iInsertPos(0), m_Readonly(false)
{ {
AddSetting(GUIST_int, "buffer_position"); AddSetting<i32>("buffer_position");
AddSetting(GUIST_float, "buffer_zone"); AddSetting<float>("buffer_zone");
AddSetting(GUIST_CStrW, "caption"); AddSetting<CStrW>("caption");
AddSetting(GUIST_int, "cell_id"); AddSetting<i32>("cell_id");
AddSetting(GUIST_CStrW, "font"); AddSetting<CStrW>("font");
AddSetting(GUIST_CStrW, "mask_char"); AddSetting<CStrW>("mask_char");
AddSetting(GUIST_bool, "mask"); AddSetting<bool>("mask");
AddSetting(GUIST_int, "max_length"); AddSetting<i32>("max_length");
AddSetting(GUIST_bool, "multiline"); AddSetting<bool>("multiline");
AddSetting(GUIST_bool, "readonly"); AddSetting<bool>("readonly");
AddSetting(GUIST_bool, "scrollbar"); AddSetting<bool>("scrollbar");
AddSetting(GUIST_CStr, "scrollbar_style"); AddSetting<CStr>("scrollbar_style");
AddSetting(GUIST_CGUISpriteInstance, "sprite"); AddSetting<CGUISpriteInstance>("sprite");
AddSetting(GUIST_CGUISpriteInstance, "sprite_selectarea"); AddSetting<CGUISpriteInstance>("sprite_selectarea");
AddSetting(GUIST_CGUIColor, "textcolor"); AddSetting<CGUIColor>("textcolor");
AddSetting(GUIST_CGUIColor, "textcolor_selected"); AddSetting<CGUIColor>("textcolor_selected");
AddSetting(GUIST_CStrW, "tooltip"); AddSetting<CStrW>("tooltip");
AddSetting(GUIST_CStr, "tooltip_style"); AddSetting<CStr>("tooltip_style");
CFG_GET_VAL("gui.cursorblinkrate", m_CursorBlinkRate); 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) m_Modified(false), m_PrevSelectedItem(-1), m_LastItemClickTime(0)
{ {
// Add sprite_disabled! TODO // Add sprite_disabled! TODO
AddSetting(GUIST_float, "buffer_zone"); AddSetting<float>("buffer_zone");
AddSetting(GUIST_CStrW, "font"); AddSetting<CStrW>("font");
AddSetting(GUIST_bool, "scrollbar"); AddSetting<bool>("scrollbar");
AddSetting(GUIST_CStr, "scrollbar_style"); AddSetting<CStr>("scrollbar_style");
AddSetting(GUIST_CStrW, "sound_disabled"); AddSetting<CStrW>("sound_disabled");
AddSetting(GUIST_CStrW, "sound_selected"); AddSetting<CStrW>("sound_selected");
AddSetting(GUIST_CGUISpriteInstance, "sprite"); AddSetting<CGUISpriteInstance>("sprite");
AddSetting(GUIST_CGUISpriteInstance, "sprite_selectarea"); AddSetting<CGUISpriteInstance>("sprite_selectarea");
AddSetting(GUIST_int, "cell_id"); AddSetting<int>( "cell_id");
AddSetting(GUIST_EAlign, "text_align"); AddSetting<EAlign>("text_align");
AddSetting(GUIST_CGUIColor, "textcolor"); AddSetting<CGUIColor>("textcolor");
AddSetting(GUIST_CGUIColor, "textcolor_selected"); AddSetting<CGUIColor>("textcolor_selected");
AddSetting(GUIST_int, "selected"); // Index selected. -1 is none. AddSetting<int>( "selected"); // Index selected. -1 is none.
AddSetting(GUIST_bool, "auto_scroll"); AddSetting<bool>("auto_scroll");
AddSetting(GUIST_int, "hovered"); AddSetting<int>( "hovered");
AddSetting(GUIST_CStrW, "tooltip"); AddSetting<CStrW>("tooltip");
AddSetting(GUIST_CStr, "tooltip_style"); AddSetting<CStr>("tooltip_style");
// Each list item has both a name (in 'list') and an associated data string (in 'list_data') // Each list item has both a name (in 'list') and an associated data string (in 'list_data')
AddSetting(GUIST_CGUIList, "list"); AddSetting<CGUIList>("list");
AddSetting(GUIST_CGUIList, "list_data"); // TODO: this should be a list of raw strings, not of CGUIStrings AddSetting<CGUIList>("list_data");
GUI<bool>::SetSetting(this, "scrollbar", false); GUI<bool>::SetSetting(this, "scrollbar", false);
GUI<int>::SetSetting(this, "selected", -1); GUI<int>::SetSetting(this, "selected", -1);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -27,6 +27,41 @@
extern int g_xres, g_yres; 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 <> template <>
bool __ParseString<bool>(const CStrW& Value, bool& Output) bool __ParseString<bool>(const CStrW& Value, bool& Output)
{ {
@ -272,28 +307,12 @@ CMatrix3D GetDefaultGuiMatrix()
return m; 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> template <typename T>
PSRETURN GUI<T>::GetSettingPointer(const IGUIObject* pObject, const CStr& Setting, T*& Value) PSRETURN GUI<T>::GetSettingPointer(const IGUIObject* pObject, const CStr& Setting, T*& Value)
{ {
ENSURE(pObject != NULL); 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()) if (it == pObject->m_Settings.end())
{ {
LOGWARNING("setting %s was not found on object %s", 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; return PSRETURN_GUI_InvalidSetting;
} }
if (it->second.m_pSetting == NULL) if (it->second == nullptr)
return PSRETURN_GUI_InvalidSetting; return PSRETURN_GUI_InvalidSetting;
#ifndef NDEBUG
CheckType<T>(pObject, Setting);
#endif
// Get value // Get value
Value = (T*)(it->second.m_pSetting); Value = &(static_cast<CGUISetting<T>* >(it->second)->m_pSetting);
return PSRETURN_OK; return PSRETURN_OK;
} }
@ -330,7 +345,7 @@ PSRETURN GUI<T>::SetSetting(IGUIObject* pObject, const CStr& Setting, T& Value,
{ {
return SetSettingWrap(pObject, Setting, Value, SkipMessage, return SetSettingWrap(pObject, Setting, Value, SkipMessage,
[&pObject, &Setting, &Value]() { [&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, return SetSettingWrap(pObject, Setting, Value, SkipMessage,
[&pObject, &Setting, &Value]() { [&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; return PSRETURN_GUI_InvalidSetting;
} }
#ifndef NDEBUG
CheckType<T>(pObject, Setting);
#endif
valueSet(); valueSet();
// Some settings needs special attention at change // 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>::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>::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, 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 #define GUITYPE_IGNORE_CGUISpriteInstance
#include "GUItypes.h" #include "GUItypes.h"
#undef GUITYPE_IGNORE_CGUISpriteInstance #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.) // 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>::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 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 CClientArea;
class CGUIString; class CGUIString;
class CMatrix3D; 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> template <typename T>
bool __ParseString(const CStrW& Value, T& tOutput); bool __ParseString(const CStrW& Value, T& tOutput);
@ -51,12 +114,6 @@ CMatrix3D GetDefaultGuiMatrix();
struct SGUIMessage; 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 * Includes static functions that needs one template
* argument. * argument.

View File

@ -27,39 +27,20 @@
#include "ps/Profile.h" #include "ps/Profile.h"
#include "scriptinterface/ScriptInterface.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) IGUIObject::IGUIObject(CGUI* pGUI)
: m_pGUI(pGUI), m_pParent(NULL), m_MouseHovering(false), m_LastClickTime() : m_pGUI(pGUI), m_pParent(NULL), m_MouseHovering(false), m_LastClickTime()
{ {
AddSetting(GUIST_bool, "enabled"); AddSetting<bool>("enabled");
AddSetting(GUIST_bool, "hidden"); AddSetting<bool>("hidden");
AddSetting(GUIST_CClientArea, "size"); AddSetting<CClientArea>("size");
AddSetting(GUIST_CStr, "style"); AddSetting<CStr>("style");
AddSetting(GUIST_CStr, "hotkey"); AddSetting<CStr>("hotkey");
AddSetting(GUIST_float, "z"); AddSetting<float>("z");
AddSetting(GUIST_bool, "absolute"); AddSetting<bool>("absolute");
AddSetting(GUIST_bool, "ghost"); AddSetting<bool>("ghost");
AddSetting(GUIST_float, "aspectratio"); AddSetting<float>("aspectratio");
AddSetting(GUIST_CStrW, "tooltip"); AddSetting<CStrW>("tooltip");
AddSetting(GUIST_CStr, "tooltip_style"); AddSetting<CStr>("tooltip_style");
// Setup important defaults // Setup important defaults
GUI<bool>::SetSetting(this, "hidden", false); GUI<bool>::SetSetting(this, "hidden", false);
@ -70,16 +51,8 @@ IGUIObject::IGUIObject(CGUI* pGUI)
IGUIObject::~IGUIObject() IGUIObject::~IGUIObject()
{ {
for (const std::pair<CStr, SGUISetting>& p : m_Settings) for (const std::pair<CStr, IGUISetting*>& p : m_Settings)
switch (p.second.m_Type) delete p.second;
{
// 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");
}
if (!m_ScriptHandlers.empty()) if (!m_ScriptHandlers.empty())
JS_RemoveExtraGCRootsTracer(m_pGUI->GetScriptInterface()->GetJSRuntime(), Trace, this); JS_RemoveExtraGCRootsTracer(m_pGUI->GetScriptInterface()->GetJSRuntime(), Trace, this);
@ -150,34 +123,16 @@ void IGUIObject::Destroy()
// Is there anything besides the children to 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? // This can happen due to inheritance
if (m_Settings.count(Name) >= 1) if (SettingExists(Name))
return; return;
// Construct, and set type m_Settings[Name] = new CGUISetting<T>(*this, Name);
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;
}
} }
bool IGUIObject::MouseOver() bool IGUIObject::MouseOver()
{ {
if (!GetGUI()) if (!GetGUI())
@ -222,12 +177,7 @@ void IGUIObject::UpdateMouseOver(IGUIObject* const& pMouseOver)
bool IGUIObject::SettingExists(const CStr& Setting) const bool IGUIObject::SettingExists(const CStr& Setting) const
{ {
// Because GetOffsets will direct dynamically defined return m_Settings.count(Setting) == 1;
// 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);
} }
PSRETURN IGUIObject::SetSetting(const CStr& Setting, const CStrW& Value, const bool& SkipMessage) 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)) if (!SettingExists(Setting))
return PSRETURN_GUI_InvalidSetting; return PSRETURN_GUI_InvalidSetting;
SGUISetting set = m_Settings[Setting]; if (!m_Settings[Setting]->FromString(Value, SkipMessage))
return PSRETURN_GUI_UnableToParse;
#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;
return PSRETURN_OK; return PSRETURN_OK;
} }
void IGUIObject::ChooseMouseOverAndClosest(IGUIObject*& pObject) void IGUIObject::ChooseMouseOverAndClosest(IGUIObject*& pObject)
{ {
if (!MouseOver()) if (!MouseOver())
@ -570,8 +486,7 @@ void IGUIObject::TraceMember(JSTracer* trc)
JS_CallObjectTracer(trc, &handler.second, "IGUIObject::m_ScriptHandlers"); JS_CallObjectTracer(trc, &handler.second, "IGUIObject::m_ScriptHandlers");
} }
PSRETURN IGUIObject::LogInvalidSettings(const CStr8& Setting) const // Instantiate templated functions:
{ #define TYPE(T) template void IGUIObject::AddSetting<T>(const CStr& Name);
LOGWARNING("IGUIObject: setting %s was not found on an object", Setting.c_str()); #include "GUItypes.h"
return PSRETURN_GUI_InvalidSetting; #undef TYPE
}

View File

@ -36,60 +36,14 @@
#include <string> #include <string>
#include <vector> #include <vector>
struct SGUISetting;
struct SGUIStyle; struct SGUIStyle;
class CGUI; class CGUI;
class JSObject; class JSObject;
class IGUISetting;
ERROR_TYPE(GUI, UnableToParse); 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. * GUI object such as a button or an input-box.
* Abstract data type ! * Abstract data type !
@ -190,9 +144,7 @@ public:
//@{ //@{
/** /**
* Checks if settings exists, only available for derived * Returns whether there is a setting with the given name registered.
* classes that has this set up, that's why the base
* class just returns false
* *
* @param Setting setting name * @param Setting setting name
* @return True if settings exist. * @return True if settings exist.
@ -224,15 +176,6 @@ public:
*/ */
PSRETURN SetSetting(const CStr& Setting, const CStrW& Value, const bool& SkipMessage = false); 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 * Set the script handler for a particular object-specific action
* *
@ -273,7 +216,7 @@ protected:
* @param Type Setting type * @param Type Setting type
* @param Name Setting reference name * @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. * Calls Destroy on all children, and deallocates all memory.
@ -464,13 +407,6 @@ private:
// as parent. // as parent.
bool IsRootObject() const; 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) static void Trace(JSTracer* trc, void* data)
{ {
reinterpret_cast<IGUIObject*>(data)->TraceMember(trc); reinterpret_cast<IGUIObject*>(data)->TraceMember(trc);
@ -520,7 +456,7 @@ protected:
* @see SetupSettings() * @see SetupSettings()
*/ */
public: public:
std::map<CStr, SGUISetting> m_Settings; std::map<CStr, IGUISetting*> m_Settings;
protected: protected:
// An object can't function stand alone // 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_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) m_NextBlinkTime(0.0), m_PingDuration(25.0), m_BlinkState(false), m_WaterHeight(0.0)
{ {
AddSetting(GUIST_CStrW, "tooltip"); AddSetting<CStrW>("tooltip");
AddSetting(GUIST_CStr, "tooltip_style"); AddSetting<CStr>("tooltip_style");
m_Clicking = false; m_Clicking = false;
m_MouseHovering = 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)) else if (e->SettingExists(propName))
{ {
e->m_Settings[propName].m_ToJSVal(cx, vp); e->m_Settings[propName]->ToJSVal(cx, vp);
return true; return true;
} }
@ -168,7 +168,7 @@ bool JSI_IGUIObject::setProperty(JSContext* cx, JS::HandleObject obj, JS::Handle
} }
if (e->SettingExists(propName)) 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()); JS_ReportError(cx, "Property '%s' does not exist!", propName.c_str());
return false; return false;