-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTweenManager.h
More file actions
167 lines (138 loc) · 4.54 KB
/
Copy pathTweenManager.h
File metadata and controls
167 lines (138 loc) · 4.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#pragma once
#include <vector>
#include <memory>
#include <cstdint>
#include <functional>
#include "Tween.h"
namespace deki {
/**
* @brief Singleton manager for all active tweens
*
* TweenManager holds and updates all tweens created via the static API.
* It is updated automatically when any TweenComponent's Update() is called,
* using frame tracking to ensure it only processes once per frame.
*
* For the static API to work, at least one TweenComponent must exist in
* the scene to drive updates. Alternatively, you can manually call
* TweenManager::Instance().Update() each frame.
*/
class DEKI_TWEEN_API TweenManager
{
public:
/**
* @brief Get singleton instance
*/
static TweenManager& Instance();
/**
* @brief Update all active tweens
* @param deltaTimeSeconds Delta time in seconds
*
* Called by TweenComponent::Update() or manually if no components exist.
*/
void Update(float deltaTimeSeconds);
/**
* @brief Ensure manager is updated for the current frame
*
* Uses DekiTime to track frames and only updates once per frame.
* Called automatically by TweenComponent::Update().
*/
void EnsureUpdatedThisFrame();
/**
* @brief Kill all active tweens
*/
void KillAll();
/**
* @brief Kill tweens targeting a specific pointer
*/
template <typename T>
void KillTweensOf(T* target);
/**
* @brief Get number of active tweens
*/
size_t GetActiveTweenCount() const { return m_Tweens.size(); }
// ========== Static Factory API ==========
/**
* @brief Create a float tween from current value to end value.
* `duration` is float seconds.
*/
static Tween<float>& To(float* target, float endValue, float duration);
/**
* @brief Create a float tween from start value to end value
*/
static Tween<float>& FromTo(float* target, float startValue, float endValue, float duration);
/**
* @brief Create an int32 tween from current value to end value
*/
static Tween<int32_t>& To(int32_t* target, int32_t endValue, float duration);
/**
* @brief Create an int32 tween from start value to end value
*/
static Tween<int32_t>& FromTo(int32_t* target, int32_t startValue, int32_t endValue, float duration);
/**
* @brief Create a DekiVector2 tween from current value to end value
*/
static Tween<DekiVector2>& To(DekiVector2* target, const DekiVector2& endValue, float duration);
/**
* @brief Create a DekiVector2 tween from start value to end value
*/
static Tween<DekiVector2>& FromTo(DekiVector2* target, const DekiVector2& startValue, const DekiVector2& endValue, float duration);
/**
* @brief Create a Color tween from current value to end value
*/
static Tween<Color>& To(Color* target, const Color& endValue, float duration);
/**
* @brief Create a Color tween from start value to end value
*/
static Tween<Color>& FromTo(Color* target, const Color& startValue, const Color& endValue, float duration);
/**
* @brief Create a delayed callback (no value interpolation)
*/
static Tween<float>& DelayedCall(float delay, std::function<void()> callback);
private:
TweenManager();
~TweenManager();
TweenManager(const TweenManager&) = delete;
TweenManager& operator=(const TweenManager&) = delete;
/**
* @brief Add a tween to the manager
* @return Reference to the added tween for chaining
*/
template <typename T>
Tween<T>& AddTween(std::unique_ptr<Tween<T>> tween);
std::vector<std::unique_ptr<ITween>> m_Tweens;
uint32_t m_NextId = 1;
// Temporary storage during Update() to avoid iterator invalidation
std::vector<std::unique_ptr<ITween>> m_TweensToAdd;
bool m_IsUpdating = false;
// Frame tracking for EnsureUpdatedThisFrame()
uint32_t m_LastUpdateTime = 0;
};
// ========== Template Implementation ==========
template <typename T>
void TweenManager::KillTweensOf(T* target)
{
for (auto& tween : m_Tweens)
{
auto* typedTween = dynamic_cast<Tween<T>*>(tween.get());
if (typedTween && typedTween->GetTarget() == target)
{
typedTween->Kill();
}
}
}
template <typename T>
Tween<T>& TweenManager::AddTween(std::unique_ptr<Tween<T>> tween)
{
tween->id = m_NextId++;
Tween<T>& tweenRef = *tween;
if (m_IsUpdating)
{
m_TweensToAdd.push_back(std::move(tween));
}
else
{
m_Tweens.push_back(std::move(tween));
}
return tweenRef;
}
} // namespace deki