💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

172 lines
4.2 KiB

  1. /*
  2. * Copyright (C) 2021 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper source code.
  5. *
  6. * Antkeeper source code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper source code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #ifndef ANTKEEPER_TWEEN_HPP
  20. #define ANTKEEPER_TWEEN_HPP
  21. #include <algorithm>
  22. #include <functional>
  23. #include <type_traits>
  24. /**
  25. * Container which stores two states along with an interpolator, for quick and easy tweening.
  26. *
  27. * @tparam T Value type.
  28. */
  29. template <class T>
  30. class tween
  31. {
  32. public:
  33. //typedef typename std::remove_pointer<T>::type value_type;
  34. typedef T value_type;
  35. typedef typename std::decay<std::function<value_type(const T&, const T&, double)>>::type interpolator_type;
  36. /**
  37. * Creates a tween.
  38. *
  39. * @param state0 Initial value of state 0.
  40. * @param state1 Initial value of state 1.
  41. * @param interpolator Function used to interpolate between states 0 and 1.
  42. */
  43. tween(const T& state0, const T& state1, interpolator_type interpolator = nullptr);
  44. /**
  45. * Creates a tween.
  46. *
  47. * @param value Initial value of states 0 and 1.
  48. * @param interpolator Function used to interpolate between states 0 and 1.
  49. */
  50. explicit tween(const T& value, interpolator_type interpolator = nullptr);
  51. /**
  52. * Creates a tween.
  53. *
  54. * @param interpolator Function that will be used to interpolate between states 0 and 1.
  55. */
  56. tween();
  57. /**
  58. * Returns a reference to the specified tween state.
  59. *
  60. * @param state Index of a tween state. Should be either `0` or `1`.
  61. * @return Reference to the specified tween state.
  62. */
  63. const T& operator[](int state) const;
  64. /// @copydoc tween::operator[](int) const
  65. T& operator[](int state);
  66. /**
  67. * Returns an interpolated state between state 0 and state 1. If no interpolator is set, state 1 will be returned.
  68. *
  69. * @param a Interpolation factor on `[0.0, 1.0]`.
  70. * @return Interpolated state, or state 1 if no interpolator is set.
  71. */
  72. value_type interpolate(double a) const;
  73. /**
  74. * Sets the function used to interpolate between states 0 and 1.
  75. *
  76. * @param interpolator Interpolator function.
  77. */
  78. void set_interpolator(const interpolator_type& interpolator);
  79. /**
  80. * Returns the function used to interpolate between states 0 and 1.
  81. */
  82. const interpolator_type& get_interpolator() const;
  83. /**
  84. * Sets state 0 = state 1.
  85. */
  86. void update();
  87. /**
  88. * Swaps state 0 and state 1.
  89. */
  90. void swap();
  91. private:
  92. T state0;
  93. T state1;
  94. interpolator_type interpolator;
  95. };
  96. template <class T>
  97. tween<T>::tween(const T& value, interpolator_type interpolator):
  98. state0(value),
  99. state1(value),
  100. interpolator(interpolator)
  101. {}
  102. template <class T>
  103. tween<T>::tween(const T& state0, const T& state1, interpolator_type interpolator):
  104. state0(state0),
  105. state1(state1),
  106. interpolator(interpolator)
  107. {}
  108. template <class T>
  109. tween<T>::tween():
  110. interpolator(nullptr)
  111. {}
  112. template <class T>
  113. inline const T& tween<T>::operator[](int state) const
  114. {
  115. return (state <= 0) ? state0 : state1;
  116. }
  117. template <class T>
  118. inline T& tween<T>::operator[](int state)
  119. {
  120. return (state <= 0) ? state0 : state1;
  121. }
  122. template <class T>
  123. inline typename tween<T>::value_type tween<T>::interpolate(double a) const
  124. {
  125. return (interpolator) ? interpolator(state0, state1, a) : state1;
  126. }
  127. template <class T>
  128. inline void tween<T>::set_interpolator(const interpolator_type& interpolator)
  129. {
  130. this->interpolator = interpolator;
  131. }
  132. template <class T>
  133. inline const typename tween<T>::interpolator_type& tween<T>::get_interpolator() const
  134. {
  135. return interpolator;
  136. }
  137. template <class T>
  138. inline void tween<T>::update()
  139. {
  140. state0 = state1;
  141. }
  142. template <class T>
  143. inline void tween<T>::swap()
  144. {
  145. std::swap(state0, state1);
  146. }
  147. #endif // ANTKEEPER_TWEEN_HPP