qxLib
easing_sequence.inl
Go to the documentation of this file.
1 /**
2 
3  @file easing_sequence.inl
4  @author Khrapov
5  @date 4.05.2021
6  @copyright © Nick Khrapov, 2021. All right reserved.
7 
8 **/
9 
10 namespace qx
11 {
12 
13 template<class T>
15 {
16  m_ElementsSequence.push_back(std::move(element));
17  update_total_time();
18 }
19 
20 template<class T>
21 template<class... args_t>
22 inline void base_easing_sequence<T>::emplace_back(args_t&&... args) noexcept
23 {
24  m_ElementsSequence.emplace_back(std::forward<args_t>(args)...);
25  update_total_time();
26 }
27 
28 template<class T>
29 inline void base_easing_sequence<T>::clear() noexcept
30 {
31  m_ElementsSequence.clear();
32  m_nCurrentElement = 0;
33  m_fCurrentTime = T(0.f);
34 }
35 
36 template<class T>
37 inline void base_easing_sequence<T>::start() noexcept
38 {
39  reset();
40  if (auto pCurrentElement = get_current_element())
41  pCurrentElement->start();
42 }
43 
44 template<class T>
45 inline void base_easing_sequence<T>::pause() noexcept
46 {
47  if (auto pCurrentElement = get_current_element())
48  pCurrentElement->pause();
49 }
50 
51 template<class T>
52 inline void base_easing_sequence<T>::resume() noexcept
53 {
54  if (auto pCurrentElement = get_current_element())
55  pCurrentElement->resume();
56 }
57 
58 template<class T>
59 inline void base_easing_sequence<T>::skip() noexcept
60 {
61  if (auto pCurrentElement = get_current_element())
62  {
63  pCurrentElement->finish();
64  update(T(0.f));
65  }
66 }
67 
68 template<class T>
69 inline void base_easing_sequence<T>::reset() noexcept
70 {
71  m_nCurrentElement = 0;
72  m_fCurrentTime = T(0.f);
73  for (auto& element : m_ElementsSequence)
74  element.reset();
75 }
76 
77 template<class T>
78 inline void base_easing_sequence<T>::update(T fDeltaTime) noexcept
79 {
80  if (auto pCurrentElement = get_current_element())
81  {
82  T fNotUsedTime = pCurrentElement->update(fDeltaTime * m_fSpeed) / m_fSpeed;
83 
84  if (pCurrentElement->is_finished())
85  {
86  ++m_nCurrentElement;
87  m_fCurrentTime += T(1.f) / pCurrentElement->get_speed();
88  if (m_nCurrentElement >= m_ElementsSequence.size() && m_bLoop)
89  {
90  m_nCurrentElement = 0;
91  m_fCurrentTime = T(0.f);
92  }
93 
94  if (auto pNewElement = get_current_element())
95  {
96  pNewElement->start();
97  update(fNotUsedTime);
98  }
99  }
100  }
101 }
102 
103 template<class T>
104 inline void base_easing_sequence<T>::set_looped(bool bLooped) noexcept
105 {
106  m_bLoop = bLooped;
107 }
108 
109 template<class T>
110 inline void base_easing_sequence<T>::set_speed(T fSpeed) noexcept
111 {
112  m_fSpeed = fSpeed;
113 }
114 
115 template<class T>
116 inline T base_easing_sequence<T>::get() const noexcept
117 {
118  if (auto pCurrentElement = get_current_element())
119  {
120  return pCurrentElement->get();
121  }
122  else if (!m_ElementsSequence.empty() && m_nCurrentElement >= m_ElementsSequence.size())
123  {
124  return m_ElementsSequence.back().get();
125  }
126  else
127  {
128  return T(0.f);
129  }
130 }
131 
132 template<class T>
133 inline T base_easing_sequence<T>::get_fraction() const noexcept
134 {
135  if (auto pCurrentElement = get_current_element())
136  {
137  return (m_fCurrentTime + pCurrentElement->get_fraction() / pCurrentElement->get_speed()) / m_fTotalTime;
138  }
139  else if (m_fTotalTime > T(0.f))
140  {
141  return m_fCurrentTime / m_fTotalTime;
142  }
143  else
144  {
145  return T(0.f);
146  }
147 }
148 
149 template<class T>
150 inline T base_easing_sequence<T>::get_speed() const noexcept
151 {
152  return m_fSpeed;
153 }
154 
155 template<class T>
156 inline bool base_easing_sequence<T>::is_not_started() const noexcept
157 {
158  if (auto pCurrentElement = get_current_element())
159  {
160  return pCurrentElement->is_not_started();
161  }
162  else if (!m_ElementsSequence.empty() && m_nCurrentElement >= m_ElementsSequence.size())
163  {
164  return m_ElementsSequence.back().is_not_started();
165  }
166  else
167  {
168  return true;
169  }
170 }
171 
172 template<class T>
173 inline bool base_easing_sequence<T>::is_started() const noexcept
174 {
175  if (auto pCurrentElement = get_current_element())
176  {
177  return pCurrentElement->is_started();
178  }
179  else if (!m_ElementsSequence.empty() && m_nCurrentElement >= m_ElementsSequence.size())
180  {
181  return m_ElementsSequence.back().is_started();
182  }
183  else
184  {
185  return false;
186  }
187 }
188 
189 template<class T>
190 inline bool base_easing_sequence<T>::is_paused() const noexcept
191 {
192  if (auto pCurrentElement = get_current_element())
193  return pCurrentElement->is_paused();
194  else
195  return false;
196 }
197 
198 template<class T>
199 inline bool base_easing_sequence<T>::is_finished() const noexcept
200 {
201  if (auto pCurrentElement = get_current_element())
202  {
203  return pCurrentElement->is_finished();
204  }
205  else if (!m_ElementsSequence.empty() && m_nCurrentElement >= m_ElementsSequence.size())
206  {
207  return m_ElementsSequence.back().is_finished();
208  }
209  else
210  {
211  return false;
212  }
213 }
214 
215 template<class T>
216 inline bool base_easing_sequence<T>::is_looped() const noexcept
217 {
218  return m_bLoop;
219 }
220 
221 template<class T>
223 {
224  return m_nCurrentElement < m_ElementsSequence.size() ? &m_ElementsSequence[m_nCurrentElement] : nullptr;
225 }
226 
227 template<class T>
228 inline const typename base_easing_sequence<T>::easing_element_type* base_easing_sequence<T>::get_current_element()
229  const noexcept
230 {
231  return QX_CONST_CAST_THIS()->get_current_element();
232 }
233 
234 template<class T>
235 inline void base_easing_sequence<T>::update_total_time() noexcept
236 {
237  m_fTotalTime += T(1.f) / m_ElementsSequence.back().get_speed();
238 }
239 
240 } // namespace qx
An updatable element representing the value of the easing function at a given time.
T get_speed() const noexcept
Get speed value.
qx::base_easing_element queue
bool is_started() const noexcept
Is sequence started.
T get_speed() const noexcept
Get updating speed value.
void update(T fDeltaTime) noexcept
Update easing element sequence.
void start() noexcept
Start easing element sequence playing.
void clear() noexcept
Clear elements queue.
void pause() noexcept
Pause easing element sequence playing.
void skip() noexcept
Skip current element.
bool is_paused() const noexcept
Is sequence paused.
bool is_finished() const noexcept
Is sequence finished.
T get_fraction() const noexcept
Get a fraction indicating how much of the sequence has played.
void resume() noexcept
Resume easing element sequence playing.
void emplace_back(args_t &&... args) noexcept
Add easing element to queue by constructing in-place.
T get() const noexcept
Get value of current sequence element.
void set_looped(bool bLooped) noexcept
Set loop state.
void reset() noexcept
Reset sequence.
bool is_not_started() const noexcept
Is sequence not started.
void set_speed(T fSpeed) noexcept
Set updating speed value.
bool is_looped() const noexcept
Is sequence looped.
void push_back(easing_element_type element) noexcept
Add easing element to queue.