mirror of
https://github.com/hyprwm/hyprutils.git
synced 2025-05-12 21:30:36 +01:00
animation: use smart pointers
This commit is contained in:
parent
4984b5ab12
commit
2e21448de5
5 changed files with 146 additions and 90 deletions
|
@ -1,5 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "../memory/WeakPtr.hpp"
|
||||
#include "hyprutils/memory/SharedPtr.hpp"
|
||||
|
||||
#include <functional>
|
||||
#include <chrono>
|
||||
|
||||
|
@ -12,27 +15,27 @@ namespace Hyprutils {
|
|||
Config properties need to have a static lifetime to allow for config reload.
|
||||
*/
|
||||
struct SAnimationPropertyConfig {
|
||||
bool overridden = true;
|
||||
bool overridden = true;
|
||||
|
||||
std::string internalBezier = "";
|
||||
std::string internalStyle = "";
|
||||
float internalSpeed = 0.f;
|
||||
int internalEnabled = -1;
|
||||
std::string internalBezier = "";
|
||||
std::string internalStyle = "";
|
||||
float internalSpeed = 0.f;
|
||||
int internalEnabled = -1;
|
||||
|
||||
SAnimationPropertyConfig* pValues = nullptr;
|
||||
SAnimationPropertyConfig* pParentAnimation = nullptr;
|
||||
Memory::CWeakPointer<SAnimationPropertyConfig> pValues;
|
||||
Memory::CWeakPointer<SAnimationPropertyConfig> pParentAnimation;
|
||||
};
|
||||
|
||||
/* A base class for animated variables. */
|
||||
class CBaseAnimatedVariable {
|
||||
public:
|
||||
using CallbackFun = std::function<void(CBaseAnimatedVariable* thisptr)>;
|
||||
using CallbackFun = std::function<void(Memory::CWeakPointer<CBaseAnimatedVariable> thisptr)>;
|
||||
|
||||
CBaseAnimatedVariable() {
|
||||
; // m_bDummy = true;
|
||||
};
|
||||
|
||||
void create(CAnimationManager* p, int typeInfo);
|
||||
void create(CAnimationManager*, int, Memory::CSharedPointer<CBaseAnimatedVariable>);
|
||||
void connectToActive();
|
||||
void disconnectFromActive();
|
||||
|
||||
|
@ -48,11 +51,11 @@ namespace Hyprutils {
|
|||
CBaseAnimatedVariable& operator=(const CBaseAnimatedVariable&) = delete;
|
||||
CBaseAnimatedVariable& operator=(CBaseAnimatedVariable&&) = delete;
|
||||
|
||||
void setConfig(SAnimationPropertyConfig* pConfig) {
|
||||
void setConfig(Memory::CSharedPointer<SAnimationPropertyConfig> pConfig) {
|
||||
m_pConfig = pConfig;
|
||||
}
|
||||
|
||||
SAnimationPropertyConfig* getConfig() const {
|
||||
Memory::CWeakPointer<SAnimationPropertyConfig> getConfig() const {
|
||||
return m_pConfig;
|
||||
}
|
||||
|
||||
|
@ -100,23 +103,25 @@ namespace Hyprutils {
|
|||
protected:
|
||||
friend class CAnimationManager;
|
||||
|
||||
bool m_bIsConnectedToActive = false;
|
||||
bool m_bIsBeingAnimated = false;
|
||||
bool m_bIsConnectedToActive = false;
|
||||
bool m_bIsBeingAnimated = false;
|
||||
|
||||
Memory::CWeakPointer<CBaseAnimatedVariable> m_pSelf;
|
||||
|
||||
private:
|
||||
SAnimationPropertyConfig* m_pConfig;
|
||||
Memory::CWeakPointer<SAnimationPropertyConfig> m_pConfig;
|
||||
|
||||
std::chrono::steady_clock::time_point animationBegin;
|
||||
std::chrono::steady_clock::time_point animationBegin;
|
||||
|
||||
bool m_bDummy = true;
|
||||
bool m_bDummy = true;
|
||||
|
||||
CAnimationManager* m_pAnimationManager;
|
||||
bool m_bRemoveEndAfterRan = true;
|
||||
bool m_bRemoveBeginAfterRan = true;
|
||||
CAnimationManager* m_pAnimationManager;
|
||||
bool m_bRemoveEndAfterRan = true;
|
||||
bool m_bRemoveBeginAfterRan = true;
|
||||
|
||||
CallbackFun m_fEndCallback;
|
||||
CallbackFun m_fBeginCallback;
|
||||
CallbackFun m_fUpdateCallback;
|
||||
CallbackFun m_fEndCallback;
|
||||
CallbackFun m_fBeginCallback;
|
||||
CallbackFun m_fUpdateCallback;
|
||||
};
|
||||
|
||||
/* This concept represents the minimum requirement for a type to be used with CGenericAnimatedVariable */
|
||||
|
@ -138,12 +143,13 @@ namespace Hyprutils {
|
|||
public:
|
||||
CGenericAnimatedVariable() = default;
|
||||
|
||||
void create(const int typeInfo, const VarType& initialValue, CAnimationManager* pAnimationManager) {
|
||||
void create(const int typeInfo, CAnimationManager* pAnimationManager, Memory::CSharedPointer<CGenericAnimatedVariable<VarType, AnimationContext>> pSelf,
|
||||
const VarType& initialValue) {
|
||||
m_Begun = initialValue;
|
||||
m_Value = initialValue;
|
||||
m_Goal = initialValue;
|
||||
|
||||
CBaseAnimatedVariable::create(pAnimationManager, typeInfo);
|
||||
CBaseAnimatedVariable::create(pAnimationManager, typeInfo, pSelf);
|
||||
}
|
||||
|
||||
CGenericAnimatedVariable(const CGenericAnimatedVariable&) = delete;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "./BezierCurve.hpp"
|
||||
#include "./AnimatedVariable.hpp"
|
||||
#include "../math/Vector2D.hpp"
|
||||
#include "../memory/SharedPtr.hpp"
|
||||
#include "../memory/WeakPtr.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
@ -13,7 +13,6 @@ using namespace Hyprutils::Math;
|
|||
|
||||
namespace Hyprutils {
|
||||
namespace Animation {
|
||||
|
||||
/* A class for managing bezier curves and variables that are being animated. */
|
||||
class CAnimationManager {
|
||||
public:
|
||||
|
@ -33,7 +32,7 @@ namespace Hyprutils {
|
|||
|
||||
std::unordered_map<std::string, CSharedPointer<CBezierCurve>> getAllBeziers();
|
||||
|
||||
std::vector<CBaseAnimatedVariable*> m_vActiveAnimatedVariables;
|
||||
std::vector<CWeakPointer<CBaseAnimatedVariable>> m_vActiveAnimatedVariables;
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, CSharedPointer<CBezierCurve>> m_mBezierCurves;
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
#include <hyprutils/animation/AnimatedVariable.hpp>
|
||||
#include <hyprutils/animation/AnimationManager.hpp>
|
||||
#include <hyprutils/memory/WeakPtr.hpp>
|
||||
|
||||
using namespace Hyprutils::Animation;
|
||||
using namespace Hyprutils::Memory;
|
||||
|
||||
void CBaseAnimatedVariable::create(Hyprutils::Animation::CAnimationManager* pAnimationManager, int typeInfo) {
|
||||
#define SP CSharedPointer
|
||||
#define WP CWeakPointer
|
||||
|
||||
void CBaseAnimatedVariable::create(Hyprutils::Animation::CAnimationManager* pAnimationManager, int typeInfo, SP<CBaseAnimatedVariable> pSelf) {
|
||||
m_pAnimationManager = pAnimationManager;
|
||||
m_Type = typeInfo;
|
||||
m_pSelf = pSelf;
|
||||
|
||||
m_bDummy = false;
|
||||
}
|
||||
|
@ -16,7 +22,7 @@ void CBaseAnimatedVariable::connectToActive() {
|
|||
|
||||
m_pAnimationManager->scheduleTick(); // otherwise the animation manager will never pick this up
|
||||
if (!m_bIsConnectedToActive)
|
||||
m_pAnimationManager->m_vActiveAnimatedVariables.push_back(this);
|
||||
m_pAnimationManager->m_vActiveAnimatedVariables.push_back(m_pSelf);
|
||||
m_bIsConnectedToActive = true;
|
||||
}
|
||||
|
||||
|
@ -24,22 +30,39 @@ void CBaseAnimatedVariable::disconnectFromActive() {
|
|||
if (!m_pAnimationManager)
|
||||
return;
|
||||
|
||||
std::erase_if(m_pAnimationManager->m_vActiveAnimatedVariables, [&](const auto& other) { return other == this; });
|
||||
std::erase_if(m_pAnimationManager->m_vActiveAnimatedVariables, [&](const auto& other) { return other == m_pSelf; });
|
||||
m_bIsConnectedToActive = false;
|
||||
}
|
||||
|
||||
bool Hyprutils::Animation::CBaseAnimatedVariable::enabled() const {
|
||||
return m_pConfig ? m_pConfig->pValues->internalEnabled : false;
|
||||
if (const auto PCONFIG = m_pConfig.lock()) {
|
||||
const auto PVALUES = PCONFIG->pValues.lock();
|
||||
return PVALUES ? PVALUES->internalEnabled : false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string& CBaseAnimatedVariable::getBezierName() const {
|
||||
static constexpr const std::string DEFAULTBEZIERNAME = "default";
|
||||
return m_pConfig ? m_pConfig->pValues->internalBezier : DEFAULTBEZIERNAME;
|
||||
|
||||
if (const auto PCONFIG = m_pConfig.lock()) {
|
||||
const auto PVALUES = PCONFIG->pValues.lock();
|
||||
return PVALUES ? PVALUES->internalBezier : DEFAULTBEZIERNAME;
|
||||
}
|
||||
|
||||
return DEFAULTBEZIERNAME;
|
||||
}
|
||||
|
||||
const std::string& CBaseAnimatedVariable::getStyle() const {
|
||||
static constexpr const std::string DEFAULTSTYLE = "";
|
||||
return m_pConfig ? m_pConfig->pValues->internalStyle : DEFAULTSTYLE;
|
||||
|
||||
if (const auto PCONFIG = m_pConfig.lock()) {
|
||||
const auto PVALUES = PCONFIG->pValues.lock();
|
||||
return PVALUES ? PVALUES->internalStyle : DEFAULTSTYLE;
|
||||
}
|
||||
|
||||
return DEFAULTSTYLE;
|
||||
}
|
||||
|
||||
float CBaseAnimatedVariable::getPercent() const {
|
||||
|
@ -51,12 +74,22 @@ float CBaseAnimatedVariable::getCurveValue() const {
|
|||
if (!m_bIsBeingAnimated || !m_pAnimationManager)
|
||||
return 1.f;
|
||||
|
||||
const auto SPENT = getPercent();
|
||||
std::string bezierName = "";
|
||||
if (const auto PCONFIG = m_pConfig.lock()) {
|
||||
const auto PVALUES = PCONFIG->pValues.lock();
|
||||
if (PVALUES)
|
||||
bezierName = PVALUES->internalBezier;
|
||||
}
|
||||
|
||||
const auto BEZIER = m_pAnimationManager->getBezier(bezierName);
|
||||
if (!BEZIER)
|
||||
return 1.f;
|
||||
|
||||
const auto SPENT = getPercent();
|
||||
if (SPENT >= 1.f)
|
||||
return 1.f;
|
||||
|
||||
return m_pAnimationManager->getBezier(m_pConfig->pValues->internalBezier)->getYForPoint(SPENT);
|
||||
return BEZIER->getYForPoint(SPENT);
|
||||
}
|
||||
|
||||
bool CBaseAnimatedVariable::ok() const {
|
||||
|
@ -65,7 +98,7 @@ bool CBaseAnimatedVariable::ok() const {
|
|||
|
||||
void CBaseAnimatedVariable::onUpdate() {
|
||||
if (m_fUpdateCallback)
|
||||
m_fUpdateCallback(this);
|
||||
m_fUpdateCallback(m_pSelf);
|
||||
}
|
||||
|
||||
void CBaseAnimatedVariable::setCallbackOnEnd(CallbackFun func, bool remove) {
|
||||
|
@ -100,7 +133,7 @@ void CBaseAnimatedVariable::onAnimationEnd() {
|
|||
if (m_fEndCallback) {
|
||||
/* loading m_bRemoveEndAfterRan before calling the callback allows the callback to delete this animation safely if it is false. */
|
||||
auto removeEndCallback = m_bRemoveEndAfterRan;
|
||||
m_fEndCallback(this);
|
||||
m_fEndCallback(m_pSelf);
|
||||
if (removeEndCallback)
|
||||
m_fEndCallback = nullptr; // reset
|
||||
}
|
||||
|
@ -112,7 +145,7 @@ void CBaseAnimatedVariable::onAnimationBegin() {
|
|||
connectToActive();
|
||||
|
||||
if (m_fBeginCallback) {
|
||||
m_fBeginCallback(this);
|
||||
m_fBeginCallback(m_pSelf);
|
||||
if (m_bRemoveBeginAfterRan)
|
||||
m_fBeginCallback = nullptr; // reset
|
||||
}
|
||||
|
|
|
@ -37,14 +37,18 @@ bool CAnimationManager::shouldTickForNext() {
|
|||
}
|
||||
|
||||
void CAnimationManager::tickDone() {
|
||||
std::vector<CBaseAnimatedVariable*> active;
|
||||
std::vector<CWeakPointer<CBaseAnimatedVariable>> active;
|
||||
// avoid reallocations
|
||||
active.reserve(m_vActiveAnimatedVariables.size());
|
||||
for (auto const& av : m_vActiveAnimatedVariables) {
|
||||
if (av->ok() && av->isBeingAnimated())
|
||||
const auto PAV = av.lock();
|
||||
if (!PAV)
|
||||
continue;
|
||||
|
||||
if (PAV->ok() && PAV->isBeingAnimated())
|
||||
active.push_back(av);
|
||||
else
|
||||
av->m_bIsConnectedToActive = false;
|
||||
PAV->m_bIsConnectedToActive = false;
|
||||
}
|
||||
|
||||
m_vActiveAnimatedVariables = std::move(active);
|
||||
|
|
|
@ -1,15 +1,26 @@
|
|||
#include <hyprutils/animation/AnimationManager.hpp>
|
||||
#include <hyprutils/animation/AnimatedVariable.hpp>
|
||||
#include <hyprutils/memory/WeakPtr.hpp>
|
||||
#include "shared.hpp"
|
||||
|
||||
#define SP CSharedPointer
|
||||
#define WP CWeakPointer
|
||||
|
||||
using namespace Hyprutils::Animation;
|
||||
using namespace Hyprutils::Math;
|
||||
using namespace Hyprutils::Memory;
|
||||
|
||||
class EmtpyContext {};
|
||||
|
||||
template <typename VarType>
|
||||
using CAnimatedVariable = CGenericAnimatedVariable<VarType, EmtpyContext>;
|
||||
|
||||
template <typename VarType>
|
||||
using PANIMVAR = SP<CAnimatedVariable<VarType>>;
|
||||
|
||||
template <typename VarType>
|
||||
using PANIMVARREF = WP<CAnimatedVariable<VarType>>;
|
||||
|
||||
enum eAVTypes {
|
||||
INT = 1,
|
||||
TEST,
|
||||
|
@ -26,30 +37,31 @@ struct SomeTestType {
|
|||
}
|
||||
};
|
||||
|
||||
#define INITANIMCFG(name) animationConfig[name] = {}
|
||||
#define CREATEANIMCFG(name, parent) animationConfig[name] = {false, "", "", 0.f, -1, &animationConfig["global"], &animationConfig[parent]}
|
||||
#define INITANIMCFG(name) animationConfig[name] = makeShared<SAnimationPropertyConfig>();
|
||||
#define CREATEANIMCFG(name, parent) *animationConfig[name] = {false, "", "", 0.f, -1, animationConfig["global"], animationConfig[parent]}
|
||||
|
||||
std::unordered_map<std::string, SAnimationPropertyConfig> animationConfig;
|
||||
std::unordered_map<std::string, SP<SAnimationPropertyConfig>> animationConfig;
|
||||
|
||||
class CMyAnimationManager : public CAnimationManager {
|
||||
public:
|
||||
void tick() {
|
||||
for (auto const& av : m_vActiveAnimatedVariables) {
|
||||
if (!av->ok())
|
||||
const auto PAV = av.lock();
|
||||
if (!PAV || !PAV->ok())
|
||||
continue;
|
||||
|
||||
const auto SPENT = av->getPercent();
|
||||
const auto PBEZIER = getBezier(av->getBezierName());
|
||||
const auto SPENT = PAV->getPercent();
|
||||
const auto PBEZIER = getBezier(PAV->getBezierName());
|
||||
const auto POINTY = PBEZIER->getYForPoint(SPENT);
|
||||
|
||||
if (POINTY >= 1.f || !av->enabled()) {
|
||||
av->warp();
|
||||
if (POINTY >= 1.f || !PAV->enabled()) {
|
||||
PAV->warp();
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (av->m_Type) {
|
||||
switch (PAV->m_Type) {
|
||||
case eAVTypes::INT: {
|
||||
auto* avInt = dynamic_cast<CAnimatedVariable<int>*>(av);
|
||||
auto avInt = dynamic_cast<CAnimatedVariable<int>*>(PAV.get());
|
||||
if (!avInt)
|
||||
std::cout << Colors::RED << "Dynamic cast upcast failed" << Colors::RESET;
|
||||
|
||||
|
@ -57,7 +69,7 @@ class CMyAnimationManager : public CAnimationManager {
|
|||
avInt->value() = avInt->begun() + (DELTA * POINTY);
|
||||
} break;
|
||||
case eAVTypes::TEST: {
|
||||
auto* avCustom = dynamic_cast<CAnimatedVariable<SomeTestType>*>(av);
|
||||
auto avCustom = dynamic_cast<CAnimatedVariable<SomeTestType>*>(PAV.get());
|
||||
if (!avCustom)
|
||||
std::cout << Colors::RED << "Dynamic cast upcast failed" << Colors::RESET;
|
||||
|
||||
|
@ -75,11 +87,14 @@ class CMyAnimationManager : public CAnimationManager {
|
|||
tickDone();
|
||||
}
|
||||
|
||||
template <typename AnimType>
|
||||
void addAnimation(const AnimType& v, CAnimatedVariable<AnimType>& av, const std::string& animationConfigName) {
|
||||
constexpr const eAVTypes EAVTYPE = std::is_same_v<AnimType, int> ? eAVTypes::INT : eAVTypes::TEST;
|
||||
av.create(EAVTYPE, v, static_cast<CAnimationManager*>(this));
|
||||
av.setConfig(&animationConfig[animationConfigName]);
|
||||
template <typename VarType>
|
||||
void createAnimation(const VarType& v, PANIMVAR<VarType>& av, const std::string& animationConfigName) {
|
||||
constexpr const eAVTypes EAVTYPE = std::is_same_v<VarType, int> ? eAVTypes::INT : eAVTypes::TEST;
|
||||
const auto PAV = makeShared<CGenericAnimatedVariable<VarType, EmtpyContext>>();
|
||||
|
||||
PAV->create(EAVTYPE, static_cast<CAnimationManager*>(this), PAV, v);
|
||||
PAV->setConfig(animationConfig[animationConfigName]);
|
||||
av = std::move(PAV);
|
||||
}
|
||||
|
||||
virtual void scheduleTick() {
|
||||
|
@ -96,64 +111,63 @@ CMyAnimationManager gAnimationManager;
|
|||
class Subject {
|
||||
public:
|
||||
Subject(const int& a, const int& b) {
|
||||
gAnimationManager.addAnimation(a, m_iA, "default");
|
||||
gAnimationManager.addAnimation(b, m_iB, "default");
|
||||
gAnimationManager.addAnimation({}, m_iC, "default");
|
||||
gAnimationManager.createAnimation(a, m_iA, "default");
|
||||
gAnimationManager.createAnimation(b, m_iB, "default");
|
||||
gAnimationManager.createAnimation({}, m_iC, "default");
|
||||
}
|
||||
CAnimatedVariable<int> m_iA;
|
||||
CAnimatedVariable<int> m_iB;
|
||||
CAnimatedVariable<SomeTestType> m_iC;
|
||||
PANIMVAR<int> m_iA;
|
||||
PANIMVAR<int> m_iB;
|
||||
PANIMVAR<SomeTestType> m_iC;
|
||||
};
|
||||
|
||||
int main(int argc, char** argv, char** envp) {
|
||||
INITANIMCFG("global");
|
||||
CREATEANIMCFG("default", "global");
|
||||
animationConfig["default"].internalBezier = "default";
|
||||
animationConfig["default"].internalSpeed = 1.0;
|
||||
animationConfig["default"].internalEnabled = 1;
|
||||
animationConfig["default"].pValues = &animationConfig["default"];
|
||||
animationConfig["default"] = makeShared<SAnimationPropertyConfig>();
|
||||
animationConfig["default"]->internalBezier = "default";
|
||||
animationConfig["default"]->internalSpeed = 1.0;
|
||||
animationConfig["default"]->internalEnabled = 1;
|
||||
animationConfig["default"]->pValues = animationConfig["default"];
|
||||
|
||||
int ret = 0;
|
||||
Subject s(0, 0);
|
||||
|
||||
EXPECT(s.m_iA.value(), 0);
|
||||
EXPECT(s.m_iB.value(), 0);
|
||||
EXPECT(s.m_iA->value(), 0);
|
||||
EXPECT(s.m_iB->value(), 0);
|
||||
|
||||
// Test destruction of a CAnimatedVariable
|
||||
{
|
||||
Subject s2(10, 10);
|
||||
// Adds them to active
|
||||
s2.m_iA = 1;
|
||||
s2.m_iB = 2;
|
||||
*s2.m_iA = 1;
|
||||
*s2.m_iB = 2;
|
||||
// We deliberately do not tick here, to make sure the destructor removes active animated variables
|
||||
}
|
||||
|
||||
EXPECT(gAnimationManager.shouldTickForNext(), false);
|
||||
EXPECT(s.m_iC.value().done, false);
|
||||
EXPECT(s.m_iC->value().done, false);
|
||||
|
||||
s.m_iA = 10;
|
||||
s.m_iB = 100;
|
||||
s.m_iC = SomeTestType(true);
|
||||
*s.m_iA = 10;
|
||||
*s.m_iB = 100;
|
||||
*s.m_iC = SomeTestType(true);
|
||||
|
||||
EXPECT(s.m_iC.value().done, false);
|
||||
EXPECT(s.m_iC->value().done, false);
|
||||
|
||||
while (gAnimationManager.shouldTickForNext()) {
|
||||
gAnimationManager.tick();
|
||||
}
|
||||
|
||||
EXPECT(s.m_iA.value(), 10);
|
||||
EXPECT(s.m_iB.value(), 100);
|
||||
EXPECT(s.m_iC.value().done, true);
|
||||
EXPECT(s.m_iA->value(), 10);
|
||||
EXPECT(s.m_iB->value(), 100);
|
||||
EXPECT(s.m_iC->value().done, true);
|
||||
|
||||
s.m_iA.setValue(0);
|
||||
s.m_iB.setValue(0);
|
||||
s.m_iA->setValue(0);
|
||||
s.m_iB->setValue(0);
|
||||
|
||||
while (gAnimationManager.shouldTickForNext()) {
|
||||
gAnimationManager.tick();
|
||||
}
|
||||
|
||||
EXPECT(s.m_iA.value(), 10);
|
||||
EXPECT(s.m_iB.value(), 100);
|
||||
EXPECT(s.m_iA->value(), 10);
|
||||
EXPECT(s.m_iB->value(), 100);
|
||||
|
||||
//
|
||||
// Test callbacks
|
||||
|
@ -161,11 +175,11 @@ int main(int argc, char** argv, char** envp) {
|
|||
bool beginCallbackRan = false;
|
||||
bool updateCallbackRan = false;
|
||||
bool endCallbackRan = false;
|
||||
s.m_iA.setCallbackOnBegin([&beginCallbackRan](CBaseAnimatedVariable* av) { beginCallbackRan = true; });
|
||||
s.m_iA.setUpdateCallback([&updateCallbackRan](CBaseAnimatedVariable* av) { updateCallbackRan = true; });
|
||||
s.m_iA.setCallbackOnEnd([&endCallbackRan](CBaseAnimatedVariable* av) { endCallbackRan = true; }, false);
|
||||
s.m_iA->setCallbackOnBegin([&beginCallbackRan](WP<CBaseAnimatedVariable> pav) { beginCallbackRan = true; });
|
||||
s.m_iA->setUpdateCallback([&updateCallbackRan](WP<CBaseAnimatedVariable> pav) { updateCallbackRan = true; });
|
||||
s.m_iA->setCallbackOnEnd([&endCallbackRan](WP<CBaseAnimatedVariable> pav) { endCallbackRan = true; }, false);
|
||||
|
||||
s.m_iA.setValueAndWarp(42);
|
||||
s.m_iA->setValueAndWarp(42);
|
||||
|
||||
EXPECT(beginCallbackRan, false);
|
||||
EXPECT(updateCallbackRan, true);
|
||||
|
@ -175,7 +189,7 @@ int main(int argc, char** argv, char** envp) {
|
|||
updateCallbackRan = false;
|
||||
endCallbackRan = false;
|
||||
|
||||
s.m_iA = 1337;
|
||||
*s.m_iA = 1337;
|
||||
while (gAnimationManager.shouldTickForNext()) {
|
||||
gAnimationManager.tick();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue