/***************************************************************************************** * * * OpenSpace * * * * Copyright (c) 2014-2019 * * * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * * software and associated documentation files (the "Software"), to deal in the Software * * without restriction, including without limitation the rights to use, copy, modify, * * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * * permit persons to whom the Software is furnished to do so, subject to the following * * conditions: * * * * The above copyright notice and this permission notice shall be included in all copies * * or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ #include namespace openspace::properties { #define REGISTER_NUMERICALPROPERTY_HEADER(CLASS_NAME, TYPE) \ using CLASS_NAME = NumericalProperty; \ \ 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>::defaultSteppingValue(); \ \ 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, \ const TYPE& value); \ template <> \ template <> \ bool PropertyDelegate>::toLuaValue(lua_State* state, \ const TYPE& value); \ template <> \ int PropertyDelegate>::typeLua(); \ template <> \ int PropertyDelegate>::typeLua(); \ \ template <> \ template <> \ TYPE PropertyDelegate>::fromString(const std::string& value, \ bool& success); \ \ template <> \ template <> \ TYPE PropertyDelegate>::fromString(const std::string& value, \ bool& success); \ \ template <> \ template <> \ bool PropertyDelegate>::toString(std::string& outValue, \ const TYPE& inValue); \ \ template <> \ template <> \ bool PropertyDelegate>::toString(std::string& outValue, \ const TYPE& inValue); #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, \ FROM_STRING_LAMBDA_EXPRESSION, \ TO_STRING_LAMBDA_EXPRESSION, LUA_TYPE) \ 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>::defaultSteppingValue() \ { \ return DEFAULT_STEPPING; \ } \ \ 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, \ const TYPE& value) \ { \ return TO_LUA_LAMBDA_EXPRESSION(state, value); \ } \ \ template <> \ template <> \ bool PropertyDelegate>::toLuaValue(lua_State* state, \ const TYPE& value) \ { \ return PropertyDelegate>::toLuaValue(state, value); \ } \ \ template <> \ int PropertyDelegate>::typeLua() \ { \ return LUA_TYPE; \ } \ \ template <> \ int PropertyDelegate>::typeLua() \ { \ return PropertyDelegate>::typeLua(); \ } \ \ template <> \ template <> \ TYPE PropertyDelegate>::fromString(const std::string& value, \ bool& success) \ { \ return FROM_STRING_LAMBDA_EXPRESSION(value, success); \ } \ \ template <> \ template <> \ TYPE PropertyDelegate>::fromString(const std::string& value, \ bool& success) \ { \ return PropertyDelegate>::fromString( \ value, \ success \ ); \ } \ \ template <> \ template <> \ bool PropertyDelegate>::toString(std::string& outValue, \ const TYPE& inValue) \ { \ return TO_STRING_LAMBDA_EXPRESSION(outValue, inValue); \ } \ \ template <> \ template <> \ bool PropertyDelegate>::toString(std::string& outValue, \ const TYPE& inValue) \ { \ return PropertyDelegate>::toString(outValue, inValue); \ } template const std::string NumericalProperty::MinimumValueKey = "MinimumValue"; template const std::string NumericalProperty::MaximumValueKey = "MaximumValue"; template const std::string NumericalProperty::SteppingValueKey = "SteppingValue"; template const std::string NumericalProperty::ExponentValueKey = "Exponent"; // Delegating constructors are necessary; automatic template deduction cannot // deduce template argument for 'U' if 'default' methods are used as default values in // a single constructor template NumericalProperty::NumericalProperty(Property::PropertyInfo info) : NumericalProperty( std::move(info), PropertyDelegate>::template defaultValue(), PropertyDelegate>::template defaultMinimumValue(), PropertyDelegate>::template defaultMaximumValue(), PropertyDelegate>::template defaultSteppingValue(), 1.f ) {} template NumericalProperty::NumericalProperty(Property::PropertyInfo info, T value) : NumericalProperty( std::move(info), std::move(value), PropertyDelegate>::template defaultMinimumValue(), PropertyDelegate>::template defaultMaximumValue(), PropertyDelegate>::template defaultSteppingValue(), 1.f ) {} template NumericalProperty::NumericalProperty(Property::PropertyInfo info, T value, T minimumValue, T maximumValue) : NumericalProperty( std::move(info), std::move(value), std::move(minimumValue), std::move(maximumValue), PropertyDelegate>::template defaultSteppingValue(), 1.f ) {} template NumericalProperty::NumericalProperty(Property::PropertyInfo info, T value, T minimumValue, T maximumValue, T steppingValue) : NumericalProperty( std::move(info), std::move(value), std::move(minimumValue), std::move(maximumValue), std::move(steppingValue), 1.f ) {} template NumericalProperty::NumericalProperty(Property::PropertyInfo info, T value, T minimumValue, T maximumValue, T steppingValue, float exponent) : TemplateProperty(std::move(info), std::move(value)) , _minimumValue(std::move(minimumValue)) , _maximumValue(std::move(maximumValue)) , _stepping(std::move(steppingValue)) , _exponent(exponent) {} template std::string NumericalProperty::className() const { return PropertyDelegate>::className(); } template bool NumericalProperty::setLuaValue(lua_State* state) { bool success = false; T value = PropertyDelegate>::template fromLuaValue( state, success ); if (success) { TemplateProperty::setValue(std::move(value)); } return success; } template bool NumericalProperty::getLuaValue(lua_State* state) const { bool success = PropertyDelegate>::template toLuaValue( state, TemplateProperty::_value ); return success; } template int NumericalProperty::typeLua() const { return PropertyDelegate>::typeLua(); } template bool NumericalProperty::getStringValue(std::string& value) const { bool success = PropertyDelegate>::template toString( value, TemplateProperty::_value ); return success; } template bool NumericalProperty::setStringValue(std::string value) { bool success = false; T thisValue = PropertyDelegate>::template fromString( value, success ); if (success) { TemplateProperty::set(ghoul::any(std::move(thisValue))); } return success; } template T NumericalProperty::minValue() const { return _minimumValue; } template void NumericalProperty::setMinValue(T value) { _minimumValue = std::move(value); } template T NumericalProperty::maxValue() const { return _maximumValue; } template void NumericalProperty::setMaxValue(T value) { _maximumValue = std::move(value); } template T NumericalProperty::steppingValue() const { return _stepping; } template void NumericalProperty::setSteppingValue(T value) { _stepping = std::move(value); } template float NumericalProperty::exponent() const { return _exponent; } template void NumericalProperty::setExponent(float exponent) { _exponent = exponent; } template std::string NumericalProperty::generateAdditionalJsonDescription() const { std::string result = "{ "; result += "\"" + MinimumValueKey + "\": " + luaToJson(ghoul::to_string(_minimumValue)) + ","; result += "\"" + MaximumValueKey + "\": " + luaToJson(ghoul::to_string(_maximumValue)) + ","; result += "\"" + SteppingValueKey + "\": " + luaToJson(ghoul::to_string(_stepping)) + ","; result += "\"" + ExponentValueKey + "\": " + luaToJson(ghoul::to_string(_exponent)); result += " }"; return result; } template std::string NumericalProperty::luaToJson(std::string luaValue) const { if (luaValue[0] == '{') { luaValue.replace(0, 1, "["); } if (luaValue[luaValue.size() - 1] == '}') { luaValue.replace(luaValue.size() - 1, 1, "]"); } return luaValue; } template std::string NumericalProperty::jsonValue() const { std::string value; getStringValue(value); return luaToJson(value); } template void NumericalProperty::setInterpolationTarget(ghoul::any value) { T v = ghoul::any_cast(std::move(value)); _interpolationStart = TemplateProperty::_value; _interpolationEnd = std::move(v); } template void NumericalProperty::setLuaInterpolationTarget(lua_State* state) { bool success = false; T thisValue = PropertyDelegate>::template fromLuaValue( state, success ); if (success) { _interpolationStart = TemplateProperty::_value; _interpolationEnd = std::move(thisValue); } } template void NumericalProperty::setStringInterpolationTarget(std::string value) { bool success = false; T thisValue = PropertyDelegate>::template fromString( value, success ); if (success) { _interpolationStart = TemplateProperty::_value; _interpolationEnd = std::move(thisValue); } } template void NumericalProperty::interpolateValue(float t, ghoul::EasingFunc easingFunction) { if (easingFunction) { t = easingFunction(t); } TemplateProperty::setValue(static_cast( glm::mix(_interpolationStart, _interpolationEnd, t) )); } } // namespace openspace::properties