blob: 90fa07f48325889dc8162276ddf0a62991231d8c [file] [log] [blame]
#include "rive/animation/state_transition_flags.hpp"
#include "rive/generated/animation/state_transition_base.hpp"
#include <stdio.h>
#include <vector>
namespace rive {
class LayerState;
class StateMachineLayerImporter;
class StateTransitionImporter;
class TransitionCondition;
class StateInstance;
class SMIInput;
class LinearAnimation;
class LinearAnimationInstance;
enum class AllowTransition : unsigned char { no, waitingForExit, yes };
class StateTransition : public StateTransitionBase {
friend class StateMachineLayerImporter;
friend class StateTransitionImporter;
StateTransitionFlags transitionFlags() const {
return static_cast<StateTransitionFlags>(flags());
LayerState* m_StateTo = nullptr;
std::vector<TransitionCondition*> m_Conditions;
void addCondition(TransitionCondition* condition);
const LayerState* stateTo() const { return m_StateTo; }
StatusCode onAddedDirty(CoreContext* context) override;
StatusCode onAddedClean(CoreContext* context) override;
/// Whether the transition is marked disabled (usually done in the
/// editor).
bool isDisabled() const {
return (transitionFlags() & StateTransitionFlags::Disabled) ==
/// Returns AllowTransition::yes when this transition can be taken from
/// stateFrom with the given inputs.
allowed(StateInstance* stateFrom, Span<SMIInput*> inputs, bool ignoreTriggers) const;
/// Whether the animation is held at exit or if it keeps advancing
/// during mixing.
bool pauseOnExit() const {
return (transitionFlags() & StateTransitionFlags::PauseOnExit) ==
/// Whether exit time is enabled. All other conditions still apply, the
/// exit time is effectively an AND with the rest of the conditions.
bool enableExitTime() const {
return (transitionFlags() & StateTransitionFlags::EnableExitTime) ==
StatusCode import(ImportStack& importStack) override;
size_t conditionCount() const { return m_Conditions.size(); }
TransitionCondition* condition(size_t index) const {
if (index < m_Conditions.size()) {
return m_Conditions[index];
return nullptr;
/// The amount of time to mix the outgoing animation onto the incoming
/// one when changing state. Only applies when going out from an
/// AnimationState.
float mixTime(const LayerState* stateFrom) const;
/// Computes the exit time in seconds of the stateFrom. Set absolute to
/// true if you want the returned time to be relative to the entire
/// animation. Set absolute to false if you want it relative to the work
/// area.
float exitTimeSeconds(const LayerState* stateFrom, bool absolute = false) const;
/// Provide the animation instance to use for computing percentage
/// durations for exit time.
virtual const LinearAnimationInstance*
exitTimeAnimationInstance(const StateInstance* from) const;
/// Provide the animation to use for computing percentage durations for
/// exit time.
virtual const LinearAnimation* exitTimeAnimation(const LayerState* from) const;
/// Retruns true when we need to hold the exit time, also applies the
/// correct time to the animation instance in the stateFrom, when
/// applicable (when it's an AnimationState).
bool applyExitCondition(StateInstance* stateFrom) const;
} // namespace rive