Gamedev Framework (gf) 1.2.0
A C++17 framework for 2D games
Activities.h
1/*
2 * Gamedev Framework (gf)
3 * Copyright (C) 2016-2022 Julien Bernard
4 *
5 * This software is provided 'as-is', without any express or implied
6 * warranty. In no event will the authors be held liable for any damages
7 * arising from the use of this software.
8 *
9 * Permission is granted to anyone to use this software for any purpose,
10 * including commercial applications, and to alter it and redistribute it
11 * freely, subject to the following restrictions:
12 *
13 * 1. The origin of this software must not be misrepresented; you must not
14 * claim that you wrote the original software. If you use this software
15 * in a product, an acknowledgment in the product documentation would be
16 * appreciated but is not required.
17 * 2. Altered source versions must be plainly marked as such, and must not be
18 * misrepresented as being the original software.
19 * 3. This notice may not be removed or altered from any source distribution.
20 */
21#ifndef GF_ACTIVITIES_H
22#define GF_ACTIVITIES_H
23
24#include <cassert>
25#include <functional>
26#include <vector>
27
28#include "Activity.h"
29#include "CoreApi.h"
30#include "Ref.h"
31#include "Tween.h"
32#include "Vector.h"
33
34namespace gf {
35#ifndef DOXYGEN_SHOULD_SKIP_THIS
36inline namespace v1 {
37#endif
38
45 class GF_CORE_API ValueActivity : public Activity {
46 public:
56 ValueActivity(float origin, float target, float& value, Time duration, Easing easing = Ease::linear);
57
63 void setOrigin(float origin) {
64 m_tween.setOrigin(origin);
65 }
66
72 float getOrigin() const noexcept {
73 return m_tween.getOrigin();
74 }
75
81 void setTarget(float target) {
82 m_tween.setTarget(target);
83 }
84
90 float getTarget() const noexcept {
91 return m_tween.getTarget();
92 }
93
99 void setDuration(Time duration) {
100 m_tween.setDuration(duration);
101 }
102
108 Time getDuration() const noexcept {
109 return m_tween.getDuration();
110 }
111
112 ActivityStatus run(Time time) override;
113 void restart() override;
114
115 private:
116 Tween<float> m_tween;
117 };
118
119
128 class GF_CORE_API RotateToActivity : public Activity {
129 public:
139 RotateToActivity(float origin, float target, float& angle, Time duration, Easing easing = Ease::linear);
140
146 void setOrigin(float origin) {
147 m_tween.setOrigin(origin);
148 normalize();
149 }
150
156 float getOrigin() const noexcept {
157 return m_tween.getOrigin();
158 }
159
165 void setTarget(float target) {
166 m_tween.setTarget(target);
167 normalize();
168 }
169
175 float getTarget() const noexcept {
176 return m_tween.getTarget();
177 }
178
184 void setDuration(Time duration) {
185 m_tween.setDuration(duration);
186 }
187
193 Time getDuration() const noexcept {
194 return m_tween.getDuration();
195 }
196
197 ActivityStatus run(Time time) override;
198 void restart() override;
199
200 private:
201 void normalize();
202
203 private:
204 Tween<float> m_tween;
205 };
206
207
214 class GF_CORE_API MoveToActivity : public Activity {
215 public:
225 MoveToActivity(Vector2f origin, Vector2f target, Vector2f& position, Time duration, Easing easing = Ease::linear);
226
232 void setOrigin(Vector2f origin) {
233 m_tween.setOrigin(origin);
234 }
235
241 Vector2f getOrigin() const noexcept {
242 return m_tween.getOrigin();
243 }
244
250 void setTarget(Vector2f target) {
251 m_tween.setTarget(target);
252 }
253
259 Vector2f getTarget() const noexcept {
260 return m_tween.getTarget();
261 }
262
268 void setDuration(Time duration) {
269 m_tween.setDuration(duration);
270 }
271
277 Time getDuration() const noexcept {
278 return m_tween.getDuration();
279 }
280
281 ActivityStatus run(Time time) override;
282 void restart() override;
283
284 private:
285 Tween<Vector2f> m_tween;
286 };
287
288
295 class GF_CORE_API ColorActivity : public Activity {
296 public:
306 ColorActivity(Color4f origin, Color4f target, Color4f& color, Time duration, Easing easing = Ease::linear);
307
313 void setOrigin(Color4f origin) {
314 m_tween.setOrigin(origin);
315 }
316
322 Color4f getOrigin() const noexcept {
323 return m_tween.getOrigin();
324 }
325
331 void setTarget(Color4f target) {
332 m_tween.setTarget(target);
333 }
334
340 Color4f getTarget() const noexcept {
341 return m_tween.getTarget();
342 }
343
349 void setDuration(Time duration) {
350 m_tween.setDuration(duration);
351 }
352
358 Time getDuration() const noexcept {
359 return m_tween.getDuration();
360 }
361
362 ActivityStatus run(Time time) override;
363 void restart() override;
364
365 private:
366 Tween<Color4f> m_tween;
367 };
368
369
374 class GF_CORE_API CallbackActivity : public Activity {
375 public:
381 CallbackActivity(std::function<void()> callback);
382
383 ActivityStatus run(Time time) override;
384 void restart() override;
385
386 private:
387 std::function<void()> m_callback;
388 bool m_called;
389 };
390
391
396 class GF_CORE_API DelayActivity : public Activity {
397 public:
404
405 ActivityStatus run(Time time) override;
406 void restart() override;
407
408 private:
409 Time m_elapsed;
410 Time m_duration;
411 };
412
413
418 class GF_CORE_API SequenceActivity : public Activity {
419 public:
424
430 void addActivity(Activity& activity);
431
435 void clear();
436
437 ActivityStatus run(Time time) override;
438 void restart() override;
439
440 private:
441 std::size_t m_current;
442 std::vector<Ref<Activity>> m_activities;
443 };
444
445
450 class GF_CORE_API RepeatActivity : public Activity {
451 public:
458 RepeatActivity(Activity& activity, int repeat = 0);
459
460 ActivityStatus run(Time time) override;
461 void restart() override;
462
463 private:
464 Ref<Activity> m_activity;
465 int m_count;
466 int m_repeat;
467 };
468
472 enum class ActivityFinish {
473 Any,
474 All,
475 };
476
481 class GF_CORE_API ParallelActivity : public Activity {
482 public:
483
490
496 void addActivity(Activity& activity);
497
501 void clear();
502
503 ActivityStatus run(Time time) override;
504 void restart() override;
505
506 private:
507 ActivityFinish m_finish;
508 ActivityStatus m_status;
509 std::vector<Ref<Activity>> m_activities;
510 };
511
515 namespace activity {
525 inline
526 ValueActivity value(float origin, float target, float& value, Time duration, Easing easing = Ease::linear) {
527 return ValueActivity(origin, target, value, duration, easing);
528 }
529
539 inline
540 RotateToActivity rotateTo(float origin, float target, float& angle, Time duration, Easing easing = Ease::linear) {
541 return RotateToActivity(origin, target, angle, duration, easing);
542 }
543
553 inline
554 MoveToActivity moveTo(Vector2f origin, Vector2f target, Vector2f& position, Time duration, Easing easing = Ease::linear) {
555 return MoveToActivity(origin, target, position, duration, easing);
556 }
557
567 inline
568 ColorActivity color(Color4f origin, Color4f target, Color4f& color, Time duration, Easing easing = Ease::linear) {
569 return ColorActivity(origin, target, color, duration, easing);
570 }
571
577 inline
578 CallbackActivity call(std::function<void()> callback) {
579 return CallbackActivity(std::move(callback));
580 }
581
587 inline
589 return DelayActivity(duration);
590 }
591
592#ifndef DOXYGEN_SHOULD_SKIP_THIS
593 // inspired by https://accu.org/journals/overload/25/139/williams_2382/
594
595 template<typename Tuple, std::size_t I>
596 Activity& activityTupleGet(Tuple& tuple) {
597 return std::get<I>(tuple);
598 }
599
600 template<typename Tuple, typename Indices = std::make_index_sequence<std::tuple_size_v<Tuple>>>
601 struct ActivityTupleGetters;
602
603 template<typename Tuple, std::size_t ... Indices>
604 struct ActivityTupleGetters<Tuple, std::index_sequence<Indices...>>
605 {
606 using Getter = Activity& (*)(Tuple&);
607 static inline constexpr Getter table[std::tuple_size_v<Tuple>] = { &activityTupleGet<Tuple, Indices>... };
608 };
609
610 template<typename Tuple>
611 Activity& activityTupleGetIth(Tuple& tuple, std::size_t i) {
612 assert(i < std::tuple_size_v<Tuple>);
613 return ActivityTupleGetters<Tuple>::table[i](tuple);
614 }
615
616#endif
617
621 template<typename... Args>
623 public:
629 SequenceActivityEx(Args... activities)
630 : m_current(0)
631 , m_activities(std::forward<Args>(activities)...)
632 {
633 }
634
635 ActivityStatus run(Time time) override {
636 if (m_current == sizeof... (Args)) {
638 }
639
640 Activity& currentActivity = activityTupleGetIth(m_activities, m_current);
641 auto status = currentActivity.run(time);
642
643 if (status == ActivityStatus::Finished) {
644 m_current++;
645 }
646
647 return m_current == sizeof... (Args) ? ActivityStatus::Finished : ActivityStatus::Running;
648 }
649
650 void restart() override {
651 m_current = 0;
652
653 for (std::size_t i = 0; i < sizeof ... (Args); ++i) {
654 activityTupleGetIth(m_activities, i).restart();
655 }
656 }
657
658 private:
659 std::size_t m_current;
660 std::tuple<Args...> m_activities;
661 };
662
668 template<typename... Args>
669 SequenceActivityEx<Args...> sequence(Args... activities) {
670 return SequenceActivityEx<Args...>(std::forward<Args>(activities)...);
671 }
672
676 template<typename Other>
677 class RepeatActivityEx : public Activity {
678 public:
685 RepeatActivityEx(Other activity, int repeat)
686 : m_activity(std::move(activity))
687 , m_count(0)
688 , m_repeat(repeat)
689 {
690 }
691
692 ActivityStatus run(Time time) override {
693 if (m_count > 0 && m_repeat == m_count) {
695 }
696
697 auto status = m_activity.run(time);
698
699 if (status == ActivityStatus::Finished) {
700 m_activity.restart();
701 m_count++;
702 }
703
704 return (m_repeat > 0 && m_repeat == m_count) ? ActivityStatus::Finished : ActivityStatus::Running;
705 }
706
707 void restart() override {
708 m_count = 0;
709 m_activity.restart();
710 }
711
712 private:
713 Other m_activity;
714 int m_count;
715 int m_repeat;
716 };
717
724 template<typename Other>
725 RepeatActivityEx<Other> repeat(Other activity, int repeat = 0) {
726 return RepeatActivityEx<Other>(std::move(activity), repeat);
727 }
728
732 template<typename... Args>
734 public:
741 ParallelActivityEx(ActivityFinish finish, Args... activities)
742 : m_finish(finish)
743 , m_status(ActivityStatus::Running)
744 , m_activities(std::forward<Args>(activities)...)
745 {
746 }
747
748 ActivityStatus run(Time time) override {
749 if (m_status == ActivityStatus::Finished) {
751 }
752
753 std::size_t finished = 0;
754
755 for (std::size_t i = 0; i < sizeof ... (Args); ++i) {
756 auto status = activityTupleGetIth(m_activities, i).run(time);
757
758 if (status == ActivityStatus::Finished) {
759 finished++;
760 }
761 }
762
763 switch (m_finish) {
765 if (finished > 0) {
766 m_status = ActivityStatus::Finished;
767 }
768 break;
769
771 if (finished == sizeof ... (Args)) {
772 m_status = ActivityStatus::Finished;
773 }
774 break;
775 }
776
777 return m_status;
778 }
779
780 void restart() override {
781 m_status = ActivityStatus::Running;
782
783 for (std::size_t i = 0; i < sizeof ... (Args); ++i) {
784 activityTupleGetIth(m_activities, i).restart();
785 }
786 }
787
788
789 private:
790 ActivityFinish m_finish;
791 ActivityStatus m_status;
792 std::tuple<Args...> m_activities;
793 };
794
800 template<typename... Args>
801 ParallelActivityEx<Args...> parallelAny(Args... activities) {
802 return ParallelActivityEx<Args...>(ActivityFinish::Any, std::forward<Args>(activities)...);
803 }
804
810 template<typename... Args>
811 ParallelActivityEx<Args...> parallelAll(Args... activities) {
812 return ParallelActivityEx<Args...>(ActivityFinish::All, std::forward<Args>(activities)...);
813 }
814
818 class AnyActivity : public Activity {
819 public:
825 template<typename Other>
826 explicit AnyActivity(Other other)
827 : m_activity(std::make_unique<Other>(std::move(other)))
828 {
829 }
830
831 ActivityStatus run(Time time) override {
832 return m_activity->run(time);
833 }
834
835 void restart() override {
836 m_activity->restart();
837 }
838
839 private:
840 std::unique_ptr<Activity> m_activity;
841 };
842
843 }
844
845#ifndef DOXYGEN_SHOULD_SKIP_THIS
846}
847#endif
848}
849
850#endif // GF_ACTIVITIES_H
A game activity.
Definition: Activity.h:62
virtual ActivityStatus run(Time time)=0
Run the activity.
An activity for calling a function once.
Definition: Activities.h:374
CallbackActivity(std::function< void()> callback)
Constructor.
ActivityStatus run(Time time) override
Run the activity.
void restart() override
Restart the activity.
An activity for a change of color.
Definition: Activities.h:295
Color4f getOrigin() const noexcept
Get the origin of the activity.
Definition: Activities.h:322
void setDuration(Time duration)
Change the duration of the activity.
Definition: Activities.h:349
ColorActivity(Color4f origin, Color4f target, Color4f &color, Time duration, Easing easing=Ease::linear)
Constructor.
void restart() override
Restart the activity.
void setTarget(Color4f target)
Change the target of the activity.
Definition: Activities.h:331
Time getDuration() const noexcept
Get the duration of the activity.
Definition: Activities.h:358
ActivityStatus run(Time time) override
Run the activity.
void setOrigin(Color4f origin)
Change the origin of the activity.
Definition: Activities.h:313
Color4f getTarget() const noexcept
Get the target of the activity.
Definition: Activities.h:340
An activity to wait for a predefined duration.
Definition: Activities.h:396
ActivityStatus run(Time time) override
Run the activity.
DelayActivity(Time duration)
Constructor.
void restart() override
Restart the activity.
static float linear(float t)
Linear easing.
An activity for a change of position.
Definition: Activities.h:214
Vector2f getTarget() const noexcept
Get the target of the activity.
Definition: Activities.h:259
MoveToActivity(Vector2f origin, Vector2f target, Vector2f &position, Time duration, Easing easing=Ease::linear)
Constructor.
void setDuration(Time duration)
Change the duration of the activity.
Definition: Activities.h:268
void setTarget(Vector2f target)
Change the target of the activity.
Definition: Activities.h:250
void restart() override
Restart the activity.
Time getDuration() const noexcept
Get the duration of the activity.
Definition: Activities.h:277
ActivityStatus run(Time time) override
Run the activity.
Vector2f getOrigin() const noexcept
Get the origin of the activity.
Definition: Activities.h:241
void setOrigin(Vector2f origin)
Change the origin of the activity.
Definition: Activities.h:232
An activity to run several activities in parallel.
Definition: Activities.h:481
void addActivity(Activity &activity)
Add an activity to the set.
void clear()
Remove all the activities.
ActivityStatus run(Time time) override
Run the activity.
ParallelActivity(ActivityFinish finish=ActivityFinish::Any)
Constructor.
void restart() override
Restart the activity.
A reference wrapper.
Definition: Ref.h:39
An activity to run an activity several times.
Definition: Activities.h:450
RepeatActivity(Activity &activity, int repeat=0)
Constructor.
ActivityStatus run(Time time) override
Run the activity.
void restart() override
Restart the activity.
An activity for a change of angle.
Definition: Activities.h:128
float getTarget() const noexcept
Get the target of the activity.
Definition: Activities.h:175
void setOrigin(float origin)
Change the origin of the activity.
Definition: Activities.h:146
RotateToActivity(float origin, float target, float &angle, Time duration, Easing easing=Ease::linear)
Constructor.
float getOrigin() const noexcept
Get the origin of the activity.
Definition: Activities.h:156
void setTarget(float target)
Change the target of the activity.
Definition: Activities.h:165
void restart() override
Restart the activity.
Time getDuration() const noexcept
Get the duration of the activity.
Definition: Activities.h:193
void setDuration(Time duration)
Change the duration of the activity.
Definition: Activities.h:184
ActivityStatus run(Time time) override
Run the activity.
An activity to run several activities sequentially.
Definition: Activities.h:418
SequenceActivity()
Constructor.
void restart() override
Restart the activity.
void addActivity(Activity &activity)
Add an activity to the sequence.
ActivityStatus run(Time time) override
Run the activity.
void clear()
Remove all the activities.
Represents a time value.
Definition: Time.h:65
An activity for a simple float value.
Definition: Activities.h:45
ValueActivity(float origin, float target, float &value, Time duration, Easing easing=Ease::linear)
Constructor.
void setOrigin(float origin)
Change the origin of the activity.
Definition: Activities.h:63
void setDuration(Time duration)
Change the duration of the activity.
Definition: Activities.h:99
float getTarget() const noexcept
Get the target of the activity.
Definition: Activities.h:90
Time getDuration() const noexcept
Get the duration of the activity.
Definition: Activities.h:108
void setTarget(float target)
Change the target of the activity.
Definition: Activities.h:81
float getOrigin() const noexcept
Get the origin of the activity.
Definition: Activities.h:72
void restart() override
Restart the activity.
ActivityStatus run(Time time) override
Run the activity.
An activity that can hold any other activity.
Definition: Activities.h:818
AnyActivity(Other other)
Constructor.
Definition: Activities.h:826
ActivityStatus run(Time time) override
Run the activity.
Definition: Activities.h:831
void restart() override
Restart the activity.
Definition: Activities.h:835
A gf::ParallelActivity that holds its activities.
Definition: Activities.h:733
void restart() override
Restart the activity.
Definition: Activities.h:780
ParallelActivityEx(ActivityFinish finish, Args... activities)
Constructor.
Definition: Activities.h:741
ActivityStatus run(Time time) override
Run the activity.
Definition: Activities.h:748
A gf::RepeatActivity that holds its activity.
Definition: Activities.h:677
ActivityStatus run(Time time) override
Run the activity.
Definition: Activities.h:692
RepeatActivityEx(Other activity, int repeat)
Constructor.
Definition: Activities.h:685
void restart() override
Restart the activity.
Definition: Activities.h:707
A gf::SequenceActivity that holds its activities.
Definition: Activities.h:622
ActivityStatus run(Time time) override
Run the activity.
Definition: Activities.h:635
SequenceActivityEx(Args... activities)
Constructor.
Definition: Activities.h:629
void restart() override
Restart the activity.
Definition: Activities.h:650
float(*)(float) Easing
An easing function.
Definition: Easings.h:48
ActivityStatus
Status of an activity.
Definition: Activity.h:38
@ Running
The activity is still running.
@ Finished
The activity is finished.
GF_CORE_API float angle(Direction direction)
Get an angle from a direction.
constexpr AllType All
Constant to represent "all".
Definition: Types.h:61
constexpr AnyType Any
Constant to represent "any".
Definition: Types.h:77
@ Other
Another unknown button (may happen with touchpads)
ColorActivity color(Color4f origin, Color4f target, Color4f &color, Time duration, Easing easing=Ease::linear)
Create a gf::ColorActivity.
Definition: Activities.h:568
ParallelActivityEx< Args... > parallelAll(Args... activities)
Create a gf::ParallelActivityEx.
Definition: Activities.h:811
RepeatActivityEx< Other > repeat(Other activity, int repeat=0)
Definition: Activities.h:725
MoveToActivity moveTo(Vector2f origin, Vector2f target, Vector2f &position, Time duration, Easing easing=Ease::linear)
Create a gf::MoveToActivity.
Definition: Activities.h:554
RotateToActivity rotateTo(float origin, float target, float &angle, Time duration, Easing easing=Ease::linear)
Create a gf::RotateToActivity.
Definition: Activities.h:540
DelayActivity delay(Time duration)
Create a gf::DelayActivity.
Definition: Activities.h:588
ParallelActivityEx< Args... > parallelAny(Args... activities)
Create a gf::ParallelActivityEx.
Definition: Activities.h:801
SequenceActivityEx< Args... > sequence(Args... activities)
Definition: Activities.h:669
ValueActivity value(float origin, float target, float &value, Time duration, Easing easing=Ease::linear)
Create a gf::ValueActivity.
Definition: Activities.h:526
CallbackActivity call(std::function< void()> callback)
Create a gf::CallbackActivity.
Definition: Activities.h:578
The namespace for gf classes.
ActivityFinish
The type of finish for the activity.
Definition: Activities.h:472
@ All
If all of the activities ends.
@ Any
If any of the activities ends.
A 4D vector.
Definition: Vector.h:852