Fix bad assumptions about state machine animation instances.
diff --git a/include/rive/animation/animation_state.hpp b/include/rive/animation/animation_state.hpp
index 5cb0282..2a2c580 100644
--- a/include/rive/animation/animation_state.hpp
+++ b/include/rive/animation/animation_state.hpp
@@ -15,6 +15,7 @@
public:
const LinearAnimation* animation() const { return m_Animation; }
+ const LinearAnimation* animationOrEmpty() const;
std::unique_ptr<StateInstance> makeInstance(ArtboardInstance*) const override;
};
} // namespace rive
diff --git a/src/animation/animation_state.cpp b/src/animation/animation_state.cpp
index 3d25d42..cc1d37c 100644
--- a/src/animation/animation_state.cpp
+++ b/src/animation/animation_state.cpp
@@ -1,16 +1,17 @@
#include "rive/animation/animation_state.hpp"
#include "rive/animation/linear_animation.hpp"
#include "rive/animation/animation_state_instance.hpp"
-#include "rive/animation/system_state_instance.hpp"
#include "rive/core_context.hpp"
#include "rive/artboard.hpp"
using namespace rive;
std::unique_ptr<StateInstance> AnimationState::makeInstance(ArtboardInstance* instance) const {
- if (animation() == nullptr) {
- // Failed to load at runtime/some new type we don't understand.
- return std::make_unique<SystemStateInstance>(this, instance);
- }
return std::make_unique<AnimationStateInstance>(this, instance);
+}
+
+static LinearAnimation emptyAnimation;
+
+const LinearAnimation* AnimationState::animationOrEmpty() const {
+ return m_Animation == nullptr ? &emptyAnimation : m_Animation;
}
\ No newline at end of file
diff --git a/src/animation/animation_state_instance.cpp b/src/animation/animation_state_instance.cpp
index 3cd7b15..7efd51d 100644
--- a/src/animation/animation_state_instance.cpp
+++ b/src/animation/animation_state_instance.cpp
@@ -6,16 +6,20 @@
AnimationStateInstance::AnimationStateInstance(const AnimationState* state,
ArtboardInstance* instance) :
StateInstance(state),
- m_AnimationInstance(state->animation(), instance),
- m_KeepGoing(true)
-{}
+ // We're careful to always instance a valid animation here as the
+ // StateMachine makes assumptions about AnimationState's producing valid
+ // AnimationStateInstances with backing animations. This was discovered when
+ // using Clang address sanitizer. We previously returned a
+ // SystemStateInstance (basically a no-op StateMachine state) which would
+ // cause bad casts in parts of the code where we assumed AnimationStates
+ // would have create AnimationStateInstances.
+ m_AnimationInstance(state->animationOrEmpty(), instance),
+ m_KeepGoing(true) {}
void AnimationStateInstance::advance(float seconds, Span<SMIInput*>) {
m_KeepGoing = m_AnimationInstance.advance(seconds);
}
-void AnimationStateInstance::apply(float mix) {
- m_AnimationInstance.apply(mix);
-}
+void AnimationStateInstance::apply(float mix) { m_AnimationInstance.apply(mix); }
bool AnimationStateInstance::keepGoing() const { return m_KeepGoing; }
\ No newline at end of file