Game Development Reference
In-Depth Information
typename std::enable_if<std::is_arithmetic<T>::value, void>::type Set(T value) {
m_value = value;
math::Clamp(m_value, m_minValue, m_maxValue);
}
template <typename T>
typename std::enable_if<!std::is_arithmetic<T>::value, void>::type Set(T value) {
m_value = value;
}
What this translates to is, if the type of T is an arithmetic type, mainly integers and floats,
thentheversionofthefunctionthatperformsaclamp onthevaluewithinthelimits willbe
a member of the
runtime_variable_type
class. However, if the type of T is not an arithmet-
ic type, then the function that only does a clean assignment will be a member of the class.
This is not necessary, it's definitely an option to pass the responsibility of applying limits
tothedifferentspecialized types,andinthatcaseasimple virtual Setfunctionmaysuffice.
In some cases, we will want to give variables a default value, a starting value and maybe
after some tweaking, we may find that we're not satisfied with the values we've changed
and would like to restore, or revert a value to its default value. It is for this that the
m_defaultValue
member variable exists, and a Revert function which restores
m_value
to
m_defaultValue
.
virtual void Set(T value) = 0;
The Set function does not need to be called directly, it's useful to wrap it around the oper-
ator =, this gives us the ability to use our runtime variables as regular variables.
runtime_variable_type<T,type>& operator = (const T& value)
{
Set(value);
return *this;
}
Itisalsoconvenienttoprovideatypeoperatorthatwillallowustoaccessourruntimevari-
able's value as its internal type, as well as a getter that gives us a reference to the internal
value, as we may not always want to rely on automatic type conversion or force the user to
cast.
operator T()
{
return m_value;
}
T& Get()
{
return m_value;
}