diff --git a/Tween.h b/Tween.h index e058ac3..3a45111 100644 --- a/Tween.h +++ b/Tween.h @@ -46,11 +46,16 @@ class Tween { private: static inline Tween* head = nullptr; static inline Tween* last = nullptr; - Tween* next; + Tween* next = nullptr; TweenListener* listener = nullptr; public: + Tween(const Tween&) = delete; + Tween& operator=(const Tween&) = delete; + Tween(Tween&& other) noexcept; + Tween& operator=(Tween&& other) noexcept; + Tween(uint16_t fps = 30) { setFps(fps); frameRateTimer = millis(); @@ -78,6 +83,20 @@ public: /////// private: + void unlinkFromList() { + if (Tween::head == nullptr) return; + if (this == Tween::head) { + Tween::head = this->next; + if (this == Tween::last) Tween::last = nullptr; + } else { + Tween* prev = Tween::head; + while (prev && prev->next != this) prev = prev->next; + if (prev) prev->next = this->next; + if (this == Tween::last) Tween::last = prev; + } + this->next = nullptr; + } + uint16_t frameTime; float dt; uint32_t oldMillis; @@ -300,21 +319,83 @@ public: static float lerp(float a, float b, float t) { return a + (b - a) * t; } - -private: - // int clamp(int value, int a, int b) { - // if (a > b) { - // a ^= b; - // b ^= a; - // a ^= b; - // } - // if (value < a) return a; - // else if (value > b) return b; - // else return value; - // } }; +//---------------------------------------------------------------------- +// TWEEN MOVE SEMANTICS +//---------------------------------------------------------------------- +inline Tween::Tween(Tween&& other) noexcept { + unlinkFromList(); + next = other.next; + listener = other.listener; + frameTime = other.frameTime; + dt = other.dt; + oldMillis = other.oldMillis; + frameRateTimer = other.frameRateTimer; + from = other.from; + to = other.to; + duration = other.duration; + easing = other.easing; + easingFunc = std::move(other.easingFunc); + progress = other.progress; + isPlayingF = other.isPlayingF; + triggerLastTick = other.triggerLastTick; + current = other.current; + + other.next = nullptr; + other.listener = nullptr; + other.easing = nullptr; + other.easingFunc = nullptr; + other.isPlayingF = false; + other.triggerLastTick = false; + + if (Tween::head == &other) Tween::head = this; + else { + Tween* prev = Tween::head; + while (prev && prev->next != &other) prev = prev->next; + if (prev) prev->next = this; + } + if (Tween::last == &other) Tween::last = this; +} + +inline Tween& Tween::operator=(Tween&& other) noexcept { + if (this != &other) { + unlinkFromList(); + + next = other.next; + listener = other.listener; + frameTime = other.frameTime; + dt = other.dt; + oldMillis = other.oldMillis; + frameRateTimer = other.frameRateTimer; + from = other.from; + to = other.to; + duration = other.duration; + easing = other.easing; + easingFunc = std::move(other.easingFunc); + progress = other.progress; + isPlayingF = other.isPlayingF; + triggerLastTick = other.triggerLastTick; + current = other.current; + + other.next = nullptr; + other.listener = nullptr; + other.easing = nullptr; + other.easingFunc = nullptr; + other.isPlayingF = false; + other.triggerLastTick = false; + + if (Tween::head == &other) Tween::head = this; + else { + Tween* prev = Tween::head; + while (prev && prev->next != &other) prev = prev->next; + if (prev) prev->next = this; + } + if (Tween::last == &other) Tween::last = this; + } + return *this; +} //---------------------------------------------------------------------- // ANIMATION CHAIN