Line data Source code
1 : /**
2 : Copyright (c) 2022 Roman Katuntsev <sbkarr@stappler.org>
3 : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
4 :
5 : Permission is hereby granted, free of charge, to any person obtaining a copy
6 : of this software and associated documentation files (the "Software"), to deal
7 : in the Software without restriction, including without limitation the rights
8 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 : copies of the Software, and to permit persons to whom the Software is
10 : furnished to do so, subject to the following conditions:
11 :
12 : The above copyright notice and this permission notice shall be included in
13 : all copies or substantial portions of the Software.
14 :
15 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 : THE SOFTWARE.
22 : **/
23 :
24 : #ifndef XENOLITH_SCENE_ACTIONS_XLACTION_H_
25 : #define XENOLITH_SCENE_ACTIONS_XLACTION_H_
26 :
27 : #include "XLCommon.h"
28 : #include "SPRefContainer.h"
29 :
30 : namespace STAPPLER_VERSIONIZED stappler::xenolith {
31 :
32 : class Node;
33 :
34 : class Action : public Ref {
35 : public:
36 : /** Default tag used for all the actions. */
37 : static const uint32_t INVALID_TAG = std::numeric_limits<uint32_t>::max();
38 :
39 : virtual ~Action();
40 :
41 : Action();
42 :
43 : /** Return true if the action has finished */
44 : virtual bool isDone() const;
45 :
46 : /**
47 : * Called after the action has finished. It will set the 'target' to nil.
48 : * IMPORTANT: You should never call "Action::stop()" manually. Instead, use: "target->stopAction(action);".
49 : */
50 : virtual void invalidate();
51 : virtual void stop();
52 :
53 : /** Called every frame with it's delta time, dt in seconds. DON'T override unless you know what you are doing */
54 : virtual void step(float dt);
55 :
56 : /**
57 : * Called once per frame. time a value between 0 and 1.
58 :
59 : * For example:
60 : * - 0 Means that the action just started.
61 : * - 0.5 Means that the action is in the middle.
62 : * - 1 Means that the action is over.
63 : *
64 : * @param time A value between 0 and 1.
65 : */
66 : virtual void update(float time);
67 :
68 4 : Node* getContainer() const { return _container; }
69 50694 : Node* getTarget() const { return _target; }
70 :
71 2666 : uint32_t getTag() const { return _tag; }
72 1867 : void setTag(uint32_t tag) { _tag = tag; }
73 :
74 13881 : float getDuration() const { return _duration; }
75 21 : virtual void setDuration(float duration) { _duration = duration; }
76 :
77 : /** Called before the action start. It will also set the target */
78 : virtual void startWithTarget(Node *target);
79 :
80 : protected:
81 : friend class ActionManager;
82 :
83 : void setContainer(Node *container);
84 : void setTarget(Node *target);
85 :
86 : Node *_container = nullptr;
87 : /**
88 : * The "target".
89 : * The target will be set with the 'startWithTarget' method.
90 : * When the 'stop' method is called, target will be set to nil.
91 : * The target is 'assigned', it is not 'retained'.
92 : */
93 : Rc<Node> _target;
94 : /** The action tag. An identifier of the action. */
95 : uint32_t _tag = INVALID_TAG;
96 :
97 : // duration in seconds or NaN
98 : float _duration = std::numeric_limits<float>::quiet_NaN();
99 : };
100 :
101 : class ActionInstant : public Action {
102 : public:
103 : virtual ~ActionInstant();
104 :
105 : virtual bool init(bool runOnce = false);
106 : virtual void step(float dt) override;
107 :
108 : protected:
109 : bool _runOnce = false;
110 : bool _performed = false;
111 : };
112 :
113 : class Show : public ActionInstant {
114 : public:
115 : virtual ~Show();
116 :
117 : virtual void update(float time) override;
118 : };
119 :
120 : class Hide : public ActionInstant {
121 : public:
122 : virtual ~Hide();
123 :
124 : virtual void update(float time) override;
125 : };
126 :
127 : class ToggleVisibility : public ActionInstant {
128 : public:
129 : virtual ~ToggleVisibility();
130 :
131 : virtual void update(float time) override;
132 : };
133 :
134 : class RemoveSelf : public ActionInstant {
135 : public:
136 : virtual ~RemoveSelf();
137 :
138 : virtual bool init(bool isNeedCleanUp, bool runOnce = false);
139 : virtual void update(float time) override;
140 :
141 : protected:
142 : using ActionInstant::init;
143 :
144 : bool _isNeedCleanUp;
145 : };
146 :
147 : class Place : public ActionInstant {
148 : public:
149 : virtual ~Place();
150 :
151 : virtual bool init(const Vec2 &pos, bool runOnce = false);
152 : virtual void update(float time) override;
153 :
154 : protected:
155 : using ActionInstant::init;
156 :
157 : Vec2 _position;
158 : };
159 :
160 : class CallFunc : public ActionInstant {
161 : public:
162 : virtual ~CallFunc();
163 :
164 : virtual bool init(Function<void()> &&func, bool runOnce = false);
165 : virtual void update(float time) override;
166 :
167 : protected:
168 : using ActionInstant::init;
169 :
170 : Function<void()> _callback;
171 : };
172 :
173 : class ActionInterval : public Action {
174 : public:
175 : virtual ~ActionInterval();
176 :
177 : bool init(float duration);
178 :
179 52 : float getElapsed() { return _elapsed; }
180 :
181 : virtual void stop() override;
182 : virtual bool isDone(void) const override;
183 : virtual void step(float dt) override;
184 : virtual void setDuration(float duration) override;
185 : virtual void startWithTarget(Node *target) override;
186 :
187 : protected:
188 : float _elapsed = 0.0f;
189 : bool _firstTick = true;
190 : };
191 :
192 : /** @class Speed
193 : * @brief Changes the speed of an action, making it take longer (speed>1)
194 : * or less (speed<1) time.
195 : * Useful to simulate 'slow motion' or 'fast forward' effect.
196 : * @warning This action can't be Sequenceable because it is not an IntervalAction.
197 : */
198 : class Speed : public Action {
199 : public:
200 : virtual ~Speed();
201 :
202 : Speed();
203 :
204 : bool init(Rc<ActionInterval> &&action, float speed);
205 :
206 : float getSpeed(void) const { return _speed; }
207 : void setSpeed(float speed) { _speed = speed; }
208 :
209 : ActionInterval* getInnerAction() const { return _innerAction; }
210 : void setInnerAction(Rc<ActionInterval> &&action);
211 :
212 : virtual void stop() override;
213 : virtual void step(float dt) override;
214 : virtual bool isDone() const override;
215 :
216 : virtual void startWithTarget(Node *target) override;
217 :
218 : protected:
219 : float _speed = 1.0f;
220 : Rc<ActionInterval> _innerAction;
221 : };
222 :
223 : class Sequence : public ActionInterval {
224 : public:
225 : virtual ~Sequence();
226 :
227 : template <typename ... Args>
228 744 : bool init(Args && ... args) {
229 744 : _duration = 0.0f;
230 744 : reserve(sizeof...(Args));
231 744 : return initWithActions(std::forward<Args>(args)...);
232 : }
233 :
234 : virtual void stop(void) override;
235 : virtual void update(float t) override;
236 : virtual void startWithTarget(Node *target) override;
237 :
238 : protected:
239 : bool reserve(size_t);
240 : bool addAction(Function<void()> &&); // add callback action
241 : bool addAction(float); // add timeout action
242 : bool addAction(TimeInterval); // add timeout action
243 :
244 : template <typename T>
245 626 : bool addAction(const Rc<T> &t) {
246 626 : return addAction(t.get());
247 : }
248 :
249 : bool addAction(Action *);
250 :
251 : template <typename T, typename ... Args>
252 914 : bool initWithActions(T &&t, Args && ... args) {
253 914 : if (!addAction(std::forward<T>(t))) {
254 0 : return false;
255 : }
256 914 : return initWithActions(std::forward<Args>(args)...);
257 : }
258 :
259 : template <typename T>
260 744 : bool initWithActions(T &&t) {
261 744 : if (addAction(std::forward<T>(t))) {
262 744 : return ActionInterval::init(_duration);
263 : }
264 0 : return false;
265 : }
266 :
267 : struct ActionData {
268 : Rc<Action> action;
269 : float minThreshold = 0.0f;
270 : float maxThreshold = 0.0f;
271 : float threshold = 0.0f;
272 : };
273 :
274 : Vector<ActionData> _actions;
275 : float _prevTime = 0.0f;
276 : uint32_t _currentIdx = 0;
277 : };
278 :
279 : class Spawn : public ActionInterval {
280 : public:
281 : virtual ~Spawn();
282 :
283 : template <typename ... Args>
284 10 : bool init(Args && ... args) {
285 10 : _duration = 0.0f;
286 10 : reserve(sizeof...(Args));
287 10 : return initWithActions(std::forward<Args>(args)...);
288 : }
289 :
290 : virtual void stop(void) override;
291 : virtual void update(float t) override;
292 : virtual void startWithTarget(Node *target) override;
293 :
294 : protected:
295 : bool reserve(size_t);
296 : bool addAction(Function<void()> &&); // add callback action
297 : bool addAction(float); // add timeout action
298 :
299 : template <typename T>
300 30 : bool addAction(const Rc<T> &t) {
301 30 : return addAction(t.get());
302 : }
303 :
304 : bool addAction(Action *);
305 :
306 : template <typename T, typename ... Args>
307 24 : bool initWithActions(T &&t, Args && ... args) {
308 24 : if (!addAction(std::forward<T>(t))) {
309 0 : return false;
310 : }
311 24 : return initWithActions(std::forward<Args>(args)...);
312 : }
313 :
314 : template <typename T>
315 10 : bool initWithActions(T &&t) {
316 10 : if (addAction(std::forward<T>(t))) {
317 10 : return ActionInterval::init(_duration);
318 : }
319 0 : return false;
320 : }
321 :
322 : struct ActionData {
323 : Rc<Action> action;
324 : float threshold = 0.0f;
325 : };
326 :
327 : Vector<ActionData> _actions;
328 : float _prevTime = 0.0f;
329 : uint32_t _currentIdx = 0;
330 : };
331 :
332 : class Repeat: public ActionInterval {
333 : public:
334 : virtual ~Repeat();
335 :
336 : virtual bool init(Rc<ActionInterval> &&, uint32_t times);
337 :
338 : void setInnerAction(Rc<ActionInterval> &&);
339 :
340 : ActionInterval* getInnerAction() const {
341 : return _innerAction;
342 : }
343 :
344 : virtual void stop() override;
345 : virtual void update(float dt) override;
346 : virtual void startWithTarget(Node *target) override;
347 : virtual bool isDone(void) const override;
348 :
349 : protected:
350 : uint32_t _times = 0;
351 : uint32_t _total = 0;
352 : float _nextDt = 0.0f;
353 : bool _actionInstant = false;
354 : Rc<ActionInterval> _innerAction;
355 : };
356 :
357 : class RepeatForever : public ActionInterval {
358 : public:
359 : virtual ~RepeatForever();
360 :
361 : virtual bool init(ActionInterval *);
362 :
363 : void setInnerAction(ActionInterval *action) {
364 : if (_innerAction != action) {
365 : _innerAction = action;
366 : }
367 : }
368 :
369 : ActionInterval* getInnerAction() const {
370 : return _innerAction;
371 : }
372 :
373 : virtual void step(float dt) override;
374 : virtual void startWithTarget(Node *target) override;
375 : virtual bool isDone(void) const override;
376 :
377 : protected:
378 : Rc<ActionInterval> _innerAction;
379 : };
380 :
381 :
382 : /** @class DelayTime
383 : * @brief Delays the action a certain amount of seconds.
384 : */
385 : class DelayTime : public ActionInterval {
386 : public:
387 : virtual ~DelayTime();
388 :
389 : virtual void update(float time) override;
390 : };
391 :
392 : class TintTo : public ActionInterval {
393 : public:
394 : virtual ~TintTo();
395 :
396 : bool init(float duration, const Color4F &, ColorMask = ColorMask::Color);
397 :
398 : virtual void update(float time) override;
399 :
400 : protected:
401 : virtual void startWithTarget(Node *target) override;
402 :
403 : ColorMask _mask = ColorMask::None;
404 : Color4F _to;
405 : Color4F _from;
406 : };
407 :
408 : class ActionProgress : public ActionInterval {
409 : public:
410 : using StartCallback = Function<void()>;
411 : using UpdateCallback = Function<void(float progress)>;
412 : using StopCallback = Function<void()>;
413 :
414 3348 : virtual ~ActionProgress() { }
415 :
416 : virtual bool init(float duration,
417 : UpdateCallback &&update, StartCallback &&start = nullptr, StopCallback &&stop = nullptr);
418 :
419 : virtual bool init(float duration, float targetProgress,
420 : UpdateCallback &&update, StartCallback &&start = nullptr, StopCallback &&stop = nullptr);
421 :
422 : virtual bool init(float duration, float sourceProgress, float targetProgress,
423 : UpdateCallback &&update, StartCallback &&start = nullptr, StopCallback &&stop = nullptr);
424 :
425 : virtual void startWithTarget(Node *t) override;
426 : virtual void update(float time) override;
427 : virtual void stop() override;
428 :
429 749 : void setSourceProgress(float progress) { _sourceProgress = progress; }
430 2 : float getSourceProgress() const { return _sourceProgress; }
431 :
432 : void setTargetProgress(float progress) { _targetProgress = progress; }
433 : float getTargetProgress() const { return _targetProgress; }
434 :
435 : void setStartCallback(StartCallback &&cb) { _onStart = move(cb); }
436 : void setUpdateCallback(UpdateCallback &&cb) { _onUpdate = move(cb); }
437 : void setStopCallback(StopCallback &&cb) { _onStop = move(cb); }
438 :
439 : protected:
440 : bool _stopped = true;
441 : float _sourceProgress = 0.0f;
442 : float _targetProgress = 1.0f;
443 :
444 : StartCallback _onStart;
445 : UpdateCallback _onUpdate;
446 : StopCallback _onStop;
447 : };
448 :
449 : class MoveTo : public ActionInterval {
450 : public:
451 1654 : virtual ~MoveTo() { }
452 :
453 : virtual bool init(float duration, const Vec2 &position);
454 : virtual bool init(float duration, const Vec3 &position);
455 : virtual void startWithTarget(Node *target) override;
456 : virtual void update(float time) override;
457 :
458 : protected:
459 : Vec3 _startPosition;
460 : Vec3 _endPosition;
461 : };
462 :
463 : class ScaleTo : public ActionInterval {
464 : public:
465 84 : virtual ~ScaleTo() { }
466 :
467 : virtual bool init(float duration, float scale);
468 : virtual bool init(float duration, const Vec3 &scale);
469 : virtual void startWithTarget(Node *target) override;
470 : virtual void update(float time) override;
471 :
472 : protected:
473 : Vec3 _startScale;
474 : Vec3 _endScale;
475 : };
476 :
477 : class ResizeTo : public ActionInterval {
478 : public:
479 16 : virtual ~ResizeTo() { }
480 :
481 : virtual bool init(float duration, const Size2 &position);
482 : virtual void startWithTarget(Node *target) override;
483 : virtual void update(float time) override;
484 :
485 : protected:
486 : Size2 _startSize;
487 : Size2 _endSize;
488 : };
489 :
490 : class FadeTo : public ActionInterval {
491 : public:
492 2554 : virtual ~FadeTo() { }
493 :
494 : virtual bool init(float duration, float target);
495 : virtual void startWithTarget(Node *target) override;
496 : virtual void update(float time) override;
497 :
498 : protected:
499 : float _startOpacity = 0.0f;
500 : float _endOpacity = 1.0f;
501 : };
502 :
503 : class RenderContinuously : public ActionInterval {
504 : public:
505 126 : virtual ~RenderContinuously() { }
506 :
507 : virtual bool init();
508 : virtual bool init(float duration);
509 :
510 : virtual void step(float dt) override;
511 : virtual void update(float time) override;
512 : virtual void startWithTarget(Node *target) override;
513 : virtual bool isDone(void) const override;
514 : virtual void stop() override;
515 :
516 : protected:
517 : Rc<ActionInterval> _innerAction;
518 : };
519 :
520 : }
521 :
522 : #endif /* XENOLITH_SCENE_ACTIONS_XLACTION_H_ */
|