diff --git a/include/openspace/properties/numericalproperty.inl b/include/openspace/properties/numericalproperty.inl index 8d16ca33e9..34f73111fd 100644 --- a/include/openspace/properties/numericalproperty.inl +++ b/include/openspace/properties/numericalproperty.inl @@ -27,58 +27,120 @@ namespace openspace { namespace properties { -#define REGISTER_NUMERICALPROPERTY_HEADER(CLASS_NAME, TYPE) \ - typedef NumericalProperty CLASS_NAME; \ - template <> std::string PropertyDelegate>::className(); \ - template <> std::string PropertyDelegate>::className(); \ - template <> template <> \ - TYPE PropertyDelegate>::defaultValue(); \ - template <> template <> \ - TYPE PropertyDelegate>::defaultMinimumValue(); \ - template <> template <> \ - TYPE PropertyDelegate>::defaultMaximumValue(); \ - template <> template <> \ - TYPE PropertyDelegate>::fromLuaValue( \ - lua_State* state, bool& success); \ - template <> template <> \ - bool PropertyDelegate>::toLuaValue( \ - lua_State* state, TYPE value); +#define REGISTER_NUMERICALPROPERTY_HEADER(CLASS_NAME, TYPE) \ + typedef NumericalProperty CLASS_NAME; \ + template <> \ + std::string PropertyDelegate>::className(); \ + template <> \ + std::string PropertyDelegate>::className(); \ + template <> \ + template <> \ + TYPE PropertyDelegate>::defaultValue(); \ + template <> \ + template <> \ + TYPE PropertyDelegate>::defaultMinimumValue(); \ + template <> \ + template <> \ + TYPE PropertyDelegate>::defaultMaximumValue(); \ + template <> \ + template <> \ + TYPE PropertyDelegate>::fromLuaValue(lua_State* state, \ + bool& success); \ + template <> \ + template <> \ + TYPE PropertyDelegate>::fromLuaValue(lua_State* state, \ + bool& success); \ + template <> \ + template <> \ + bool PropertyDelegate>::toLuaValue(lua_State* state, \ + TYPE value); \ + template <> \ + template <> \ + bool PropertyDelegate>::toLuaValue(lua_State* state, \ + TYPE value); \ + template <> \ + int PropertyDelegate>::typeLua(); \ + template <> \ + int PropertyDelegate>::typeLua(); - -#define REGISTER_NUMERICALPROPERTY_SOURCE(CLASS_NAME, TYPE, \ - DEFAULT_VALUE, DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, DEFAULT_STEPPING, \ - FROM_LUA_LAMBDA_EXPRESSION, TO_LUA_LAMBDA_EXPRESSION) \ - template <> \ - std::string PropertyDelegate>::className() { \ - return #CLASS_NAME; \ -} \ - template <> \ - std::string PropertyDelegate>::className() { \ - return #CLASS_NAME; \ -} \ - template <> template <> \ - TYPE PropertyDelegate>::defaultValue() { \ - return DEFAULT_VALUE; \ -} \ - template <> template <> \ - TYPE PropertyDelegate>::defaultMinimumValue() { \ - return DEFAULT_MIN_VALUE; \ -} \ - template <> template <> \ - TYPE PropertyDelegate>::defaultMaximumValue() { \ - return DEFAULT_MAX_VALUE; \ -} \ - template <> template <> \ - TYPE PropertyDelegate>::fromLuaValue( \ - lua_State* state, bool& success) { \ - return FROM_LUA_LAMBDA_EXPRESSION(state, success); \ -} \ - template <> template <> \ - bool PropertyDelegate>::toLuaValue( \ - lua_State* state, TYPE value) { \ - return TO_LUA_LAMBDA_EXPRESSION(state, value); \ -} - +#define REGISTER_NUMERICALPROPERTY_SOURCE(CLASS_NAME, TYPE, DEFAULT_VALUE, \ + DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, \ + DEFAULT_STEPPING, FROM_LUA_LAMBDA_EXPRESSION, \ + TO_LUA_LAMBDA_EXPRESSION) \ + template <> \ + std::string PropertyDelegate>::className() \ + { \ + return #CLASS_NAME; \ + \ +} \ + template <> \ + std::string PropertyDelegate>::className() \ + { \ + return PropertyDelegate>::className(); \ + \ +} \ + template <> \ + template <> \ + TYPE PropertyDelegate>::defaultValue() \ + { \ + return DEFAULT_VALUE; \ + \ +} \ + template <> \ + template <> \ + TYPE PropertyDelegate>::defaultMinimumValue() \ + { \ + return DEFAULT_MIN_VALUE; \ + \ +} \ + template <> \ + template <> \ + TYPE PropertyDelegate>::defaultMaximumValue() \ + { \ + return DEFAULT_MAX_VALUE; \ + \ +} \ + template <> \ + template <> \ + TYPE PropertyDelegate>::fromLuaValue(lua_State * state, \ + bool& success) \ + { \ + return FROM_LUA_LAMBDA_EXPRESSION(state, success); \ + \ +} \ + template <> \ + template <> \ + TYPE PropertyDelegate>::fromLuaValue( \ + lua_State * state, bool& success) \ + { \ + return PropertyDelegate>::fromLuaValue(state, \ + success); \ + \ +} \ + template <> \ + template <> \ + bool PropertyDelegate>::toLuaValue(lua_State * state, \ + TYPE value) \ + { \ + return TO_LUA_LAMBDA_EXPRESSION(state, value); \ + } \ + template <> \ + template <> \ + bool PropertyDelegate>::toLuaValue(lua_State * state, \ + TYPE value) \ + { \ + return PropertyDelegate>::toLuaValue(state, value); \ + } \ + template <> \ + int PropertyDelegate>::typeLua() \ + { \ + return LUA_TNUMBER; \ + } \ + template <> \ + int PropertyDelegate>::typeLua() \ + { \ + return PropertyDelegate>::typeLua(); \ + } // Delegating constructors are necessary; automatic template deduction cannot // deduce template argument for 'U' if 'default' methods are used as default values in @@ -133,8 +195,8 @@ bool NumericalProperty::getLua(lua_State* state) const } template -int openspace::properties::NumericalProperty::typeLua() const { - return LUA_TNUMBER; +int NumericalProperty::typeLua() const { + return PropertyDelegate>::typeLua(); } diff --git a/include/openspace/properties/propertydelegate.h b/include/openspace/properties/propertydelegate.h index feeb411c05..a97ae67cf0 100644 --- a/include/openspace/properties/propertydelegate.h +++ b/include/openspace/properties/propertydelegate.h @@ -51,6 +51,8 @@ public: template static bool toLuaValue(lua_State* state, U value); + + static int typeLua(); }; } // namespace properties diff --git a/include/openspace/properties/propertydelegate.inl b/include/openspace/properties/propertydelegate.inl index 8088fb4b4b..7f0f57e344 100644 --- a/include/openspace/properties/propertydelegate.inl +++ b/include/openspace/properties/propertydelegate.inl @@ -71,5 +71,11 @@ bool PropertyDelegate::toLuaValue(lua_State* state, U value) { "Unimplemented PropertyDelegate::toLuaValue specialization"); } +template +int PropertyDelegate::typeLua() { + static_assert(sizeof(T) == 0, + "Unimplemented PropertyDelegate::luaType specialization"); +} + } // namespace properties } // namespace openspace diff --git a/include/openspace/properties/stringproperty.h b/include/openspace/properties/stringproperty.h index c1dc995c86..7fa08b1753 100644 --- a/include/openspace/properties/stringproperty.h +++ b/include/openspace/properties/stringproperty.h @@ -45,7 +45,19 @@ template <> template <> std::string PropertyDelegate>::defaultValue(); -//REGISTER_TEMPLATEPROPERTY_HEADER(StringProperty, std::string); +template <> +template <> +std::string PropertyDelegate>::fromLuaValue( + lua_State* state, bool& success); + +template <> +template <> +bool PropertyDelegate>::toLuaValue( + lua_State* state, std::string value); + +template <> +int PropertyDelegate>::typeLua(); + } // namespace properties diff --git a/include/openspace/properties/templateproperty.h b/include/openspace/properties/templateproperty.h index d38e0cc660..1906a4299f 100644 --- a/include/openspace/properties/templateproperty.h +++ b/include/openspace/properties/templateproperty.h @@ -41,6 +41,11 @@ public: virtual void set(boost::any value) override; virtual const std::type_info& type() const override; + bool getLua(lua_State* state) const override; + bool setLua(lua_State* state) override; + int typeLua() const override; + + operator T(); TemplateProperty& operator=(T val); diff --git a/include/openspace/properties/templateproperty.inl b/include/openspace/properties/templateproperty.inl index 25648695d9..2db1902329 100644 --- a/include/openspace/properties/templateproperty.inl +++ b/include/openspace/properties/templateproperty.inl @@ -31,20 +31,52 @@ namespace properties { std::string PropertyDelegate>::className(); \ template <> \ template <> \ - TYPE PropertyDelegate>::defaultValue(); - -#define REGISTER_TEMPLATEPROPERTY_SOURCE(CLASS_NAME, TYPE, DEFAULT_VALUE) \ + TYPE PropertyDelegate>::defaultValue(); \ template <> \ - std::string PropertyDelegate>::className() { \ + template <> \ + TYPE PropertyDelegate>::fromLuaValue(lua_State* state, \ + bool& success); \ + template <> \ + template <> \ + bool PropertyDelegate>::toLuaValue(lua_State* state, \ + TYPE value); \ + template <> \ + int PropertyDelegate>::typeLua(); + +#define REGISTER_TEMPLATEPROPERTY_SOURCE(CLASS_NAME, TYPE, DEFAULT_VALUE, \ + FROM_LUA_LAMBDA_EXPRESSION, \ + TO_LUA_LAMBDA_EXPRESSION, LUA_TYPE) \ + template <> \ + std::string PropertyDelegate>::className() \ + { \ return #CLASS_NAME; \ \ } \ template <> \ template <> \ - TYPE PropertyDelegate>::defaultValue() { \ + TYPE PropertyDelegate>::defaultValue() \ + { \ return DEFAULT_VALUE; \ - \ -} + } \ + template <> \ + template <> \ + TYPE PropertyDelegate>::fromLuaValue(lua_State * state, \ + bool& success) \ + { \ + return FROM_LUA_LAMBDA_EXPRESSION(state, success); \ + } \ + template <> \ + template <> \ + bool PropertyDelegate>::toLuaValue(lua_State * state, \ + TYPE value) \ + { \ + return TO_LUA_LAMBDA_EXPRESSION(state, value); \ + } \ + template <> \ + int PropertyDelegate>::typeLua() \ + { \ + return LUA_TYPE; \ + } // Delegating constructors are necessary; automatic template deduction cannot // deduce template argument for 'U' if 'default' methods are used as default values in @@ -114,5 +146,27 @@ const std::type_info& TemplateProperty::type() const { return typeid(T); } +template +bool TemplateProperty::setLua(lua_State* state) +{ + bool success; + T value = PropertyDelegate>::fromLuaValue(state, success); + if (success) + set(value); + return success; +} + +template +bool TemplateProperty::getLua(lua_State* state) const +{ + bool success = PropertyDelegate>::toLuaValue(state, _value); + return success; +} + +template +int TemplateProperty::typeLua() const { + return PropertyDelegate>::typeLua(); +} + } // namespace properties } // namespace openspace diff --git a/src/properties/scalarproperty.cpp b/src/properties/scalarproperty.cpp index b3562ac2e1..01ba23820f 100644 --- a/src/properties/scalarproperty.cpp +++ b/src/properties/scalarproperty.cpp @@ -51,7 +51,20 @@ namespace properties { // char16_t and char32_t are not supported on Visual Studio 2013 and are defined to // be equal to unsigned short and unsigned int which causes a compile error -REGISTER_TEMPLATEPROPERTY_SOURCE(BoolProperty, bool, false); +REGISTER_TEMPLATEPROPERTY_SOURCE(BoolProperty, bool, false, + [](lua_State* state, bool& success) -> bool { + success = (lua_isboolean(state, -1) == 1); + if (success) + return lua_toboolean(state, -1) == 1; + else + return false; + }, + [](lua_State* state, bool value) -> bool { + lua_pushboolean(state, value); + return true; + }, + LUA_TBOOLEAN + ); REGISTER_NUMERICALPROPERTY_SOURCE(CharProperty, char, char(0), numeric_limits::lowest(), numeric_limits::max(), char(1), diff --git a/src/properties/stringproperty.cpp b/src/properties/stringproperty.cpp index a60115cd29..1389f2c200 100644 --- a/src/properties/stringproperty.cpp +++ b/src/properties/stringproperty.cpp @@ -24,6 +24,8 @@ #include +#include + namespace openspace { namespace properties { @@ -50,12 +52,31 @@ std::string PropertyDelegate>::defaultValue +template <> +std::string PropertyDelegate>::fromLuaValue( + lua_State* state, bool& success) +{ + success = lua_isstring(state, -1) == 1; + if (success) + return lua_tostring(state, -1); + else + return ""; +} -//REGISTER_TEMPLATEPROPERTY_SOURCE(StringProperty, std::string, ""); -// -//std::string openspace::properties::StringProperty::className() const { -// return "StringProperty"; -//} +template <> +template <> +bool PropertyDelegate>::toLuaValue( + lua_State* state, std::string value) +{ + lua_pushstring(state, value.c_str()); + return true; +} + +template <> +int PropertyDelegate>::typeLua() { + return LUA_TSTRING; +} } // namespace properties } // namespace openspace diff --git a/src/properties/vectorproperty.cpp b/src/properties/vectorproperty.cpp index ff9193347d..ecd2f01f16 100644 --- a/src/properties/vectorproperty.cpp +++ b/src/properties/vectorproperty.cpp @@ -102,14 +102,71 @@ namespace properties { \ } -REGISTER_TEMPLATEPROPERTY_SOURCE(BVec2Property, glm::bvec2, glm::bvec2(false)); -REGISTER_TEMPLATEPROPERTY_SOURCE(BVec3Property, glm::bvec3, glm::bvec3(false)); -REGISTER_TEMPLATEPROPERTY_SOURCE(BVec4Property, glm::bvec4, glm::bvec4(false)); +REGISTER_TEMPLATEPROPERTY_SOURCE(BVec2Property, glm::bvec2, glm::bvec2(false), + [](lua_State* state, bool& success) -> glm::bvec2 { + success = (lua_isboolean(state, -1) == 1) && (lua_isboolean(state, -2) == 1); + if (success) + return glm::bvec2(lua_toboolean(state, -1), lua_toboolean(state, -2)); + else + return glm::bvec2(false); + }, + [](lua_State* state, glm::bvec2 value) -> bool { + lua_pushboolean(state, value.x); + lua_pushboolean(state, value.y); + return true; + }, + LUA_TTABLE + ); + +REGISTER_TEMPLATEPROPERTY_SOURCE(BVec3Property, glm::bvec3, glm::bvec3(false), + [](lua_State* state, bool& success) -> glm::bvec3 { + success = (lua_isboolean(state, -1) == 1) && + (lua_isboolean(state, -2) == 1) && + (lua_isboolean(state, -3) == 1); + if (success) + return glm::bvec3(lua_toboolean(state, -1), + lua_toboolean(state, -2), + lua_toboolean(state, -3)); + else + return glm::bvec3(false); + }, + [](lua_State* state, glm::bvec3 value) -> bool { + lua_pushboolean(state, value.x); + lua_pushboolean(state, value.y); + lua_pushboolean(state, value.z); + return true; + }, + LUA_TTABLE + ); + +REGISTER_TEMPLATEPROPERTY_SOURCE(BVec4Property, glm::bvec4, glm::bvec4(false), + [](lua_State* state, bool& success) -> glm::bvec4 { + success = (lua_isboolean(state, -1) == 1) && + (lua_isboolean(state, -2) == 1) && + (lua_isboolean(state, -3) == 1) && + (lua_isboolean(state, -4) == 1); + if (success) + return glm::bvec4(lua_toboolean(state, -1), + lua_toboolean(state, -2), + lua_toboolean(state, -3), + lua_toboolean(state, -4)); + else + return glm::bvec4(false); + }, + [](lua_State* state, glm::bvec4 value) -> bool { + lua_pushboolean(state, value.x); + lua_pushboolean(state, value.y); + lua_pushboolean(state, value.z); + lua_pushboolean(state, value.w); + return true; + }, + LUA_TTABLE + ); REGISTER_NUMERICALPROPERTY_SOURCE(Vec2Property, glm::vec2, glm::vec2(0), glm::vec2(numeric_limits::lowest()), glm::vec2(numeric_limits::max()), glm::vec2(0.01f), DEFAULT_FROM_LUA_LAMBDA_2(glm::vec2, glm::vec2(0)), - DEFAULT_TO_LUA_LAMBDA_2(glm::vec2)); + DEFAULT_TO_LUA_LAMBDA_2(glm::vec2)); // , LUA_TTABLE REGISTER_NUMERICALPROPERTY_SOURCE(Vec3Property, glm::vec3, glm::vec3(0), glm::vec3(numeric_limits::lowest()), glm::vec3(numeric_limits::max()),