diff --git a/.rive_head b/.rive_head index 00cccbb2..918acd82 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -34e186b32dbb956a36807635ea16fe039f988333 +097b68f5616951d83b0c5b28345e6bfc9f0b1a5b diff --git a/include/rive/animation/linear_animation_instance.hpp b/include/rive/animation/linear_animation_instance.hpp index 316b0c7c..d04d5964 100644 --- a/include/rive/animation/linear_animation_instance.hpp +++ b/include/rive/animation/linear_animation_instance.hpp @@ -3,13 +3,15 @@ #include "rive/artboard.hpp" #include "rive/core/field_types/core_callback_type.hpp" +#include "rive/nested_animation.hpp" #include "rive/scene.hpp" namespace rive { class LinearAnimation; +class NestedEventNotifier; -class LinearAnimationInstance : public Scene +class LinearAnimationInstance : public Scene, public NestedEventNotifier { public: LinearAnimationInstance(const LinearAnimation*, ArtboardInstance*, float speedMultiplier = 1.0); @@ -97,6 +99,7 @@ class LinearAnimationInstance : public Scene bool advanceAndApply(float seconds) override; std::string name() const override; void reset(float speedMultiplier); + void reportEvent(Event* event, float secondsDelay = 0.0f) override; private: const LinearAnimation* m_animation = nullptr; diff --git a/include/rive/animation/nested_linear_animation.hpp b/include/rive/animation/nested_linear_animation.hpp index 7de512c8..6d307270 100644 --- a/include/rive/animation/nested_linear_animation.hpp +++ b/include/rive/animation/nested_linear_animation.hpp @@ -15,6 +15,7 @@ class NestedLinearAnimation : public NestedLinearAnimationBase ~NestedLinearAnimation() override; void initializeAnimation(ArtboardInstance*) override; + LinearAnimationInstance* animationInstance() { return m_AnimationInstance.get(); } }; } // namespace rive diff --git a/include/rive/animation/state_machine_instance.hpp b/include/rive/animation/state_machine_instance.hpp index 4618a82f..13e37407 100644 --- a/include/rive/animation/state_machine_instance.hpp +++ b/include/rive/animation/state_machine_instance.hpp @@ -10,6 +10,7 @@ #include "rive/core/field_types/core_callback_type.hpp" #include "rive/hit_result.hpp" #include "rive/listener_type.hpp" +#include "rive/nested_animation.hpp" #include "rive/scene.hpp" namespace rive @@ -25,22 +26,13 @@ class Shape; class StateMachineLayerInstance; class HitComponent; class NestedArtboard; +class NestedEventListener; +class NestedEventNotifier; class Event; +class EventReport; class KeyedProperty; -class EventReport -{ -public: - EventReport(Event* event, float secondsDelay) : m_event(event), m_secondsDelay(secondsDelay) {} - Event* event() const { return m_event; } - float secondsDelay() const { return m_secondsDelay; } - -private: - Event* m_event; - float m_secondsDelay; -}; - -class StateMachineInstance : public Scene +class StateMachineInstance : public Scene, public NestedEventNotifier, public NestedEventListener { friend class SMIInput; friend class KeyedProperty; @@ -117,6 +109,7 @@ class StateMachineInstance : public Scene void setParentNestedArtboard(NestedArtboard* artboard) { m_parentNestedArtboard = artboard; } NestedArtboard* parentNestedArtboard() { return m_parentNestedArtboard; } + void notify(const std::vector& events, NestedArtboard* context) override; /// Tracks an event that reported, will be cleared at the end of the next advance. void reportEvent(Event* event, float secondsDelay = 0.0f) override; diff --git a/include/rive/event_report.hpp b/include/rive/event_report.hpp new file mode 100644 index 00000000..fe56315e --- /dev/null +++ b/include/rive/event_report.hpp @@ -0,0 +1,21 @@ +#ifndef _RIVE_EVENT_REPORT_HPP_ +#define _RIVE_EVENT_REPORT_HPP_ + +namespace rive +{ +class Event; + +class EventReport +{ +public: + EventReport(Event* event, float secondsDelay) : m_event(event), m_secondsDelay(secondsDelay) {} + Event* event() const { return m_event; } + float secondsDelay() const { return m_secondsDelay; } + +private: + Event* m_event; + float m_secondsDelay; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/nested_animation.hpp b/include/rive/nested_animation.hpp index 843739e8..fc31df6c 100644 --- a/include/rive/nested_animation.hpp +++ b/include/rive/nested_animation.hpp @@ -1,11 +1,59 @@ #ifndef _RIVE_NESTED_ANIMATION_HPP_ #define _RIVE_NESTED_ANIMATION_HPP_ +#include "rive/event.hpp" +#include "rive/event_report.hpp" #include "rive/generated/nested_animation_base.hpp" +#include "rive/nested_artboard.hpp" #include namespace rive { class ArtboardInstance; +class NestedEventListener +{ +public: + virtual ~NestedEventListener() {} + virtual void notify(const std::vector& events, NestedArtboard* context) = 0; +}; + +class NestedEventNotifier +{ +public: + ~NestedEventNotifier() + { + m_nestedArtboard = nullptr; + m_nestedEventListeners.clear(); + } + void addNestedEventListener(NestedEventListener* listener) + { + m_nestedEventListeners.push_back(listener); + } + std::vector nestedEventListeners() { return m_nestedEventListeners; } + + void setNestedArtboard(NestedArtboard* artboard) { m_nestedArtboard = artboard; } + NestedArtboard* nestedArtboard() { return m_nestedArtboard; } + + void notifyListeners(const std::vector& events) + { + if (m_nestedArtboard != nullptr) + { + std::vector eventReports; + for (auto event : events) + { + eventReports.push_back(EventReport(event, 0)); + } + for (auto listener : m_nestedEventListeners) + { + listener->notify(eventReports, m_nestedArtboard); + } + } + } + +private: + NestedArtboard* m_nestedArtboard; + std::vector m_nestedEventListeners; +}; + class NestedAnimation : public NestedAnimationBase { public: diff --git a/src/animation/linear_animation_instance.cpp b/src/animation/linear_animation_instance.cpp index f40f8afe..1399912c 100644 --- a/src/animation/linear_animation_instance.cpp +++ b/src/animation/linear_animation_instance.cpp @@ -245,3 +245,9 @@ void LinearAnimationInstance::loopValue(int value) } float LinearAnimationInstance::durationSeconds() const { return m_animation->durationSeconds(); } + +void LinearAnimationInstance::reportEvent(Event* event, float secondsDelay) +{ + const std::vector events{event}; + notifyListeners(events); +} \ No newline at end of file diff --git a/src/animation/nested_simple_animation.cpp b/src/animation/nested_simple_animation.cpp index dd6bb6e2..c747fd29 100644 --- a/src/animation/nested_simple_animation.cpp +++ b/src/animation/nested_simple_animation.cpp @@ -10,7 +10,8 @@ bool NestedSimpleAnimation::advance(float elapsedSeconds) { if (isPlaying()) { - keepGoing = m_AnimationInstance->advance(elapsedSeconds * speed()); + keepGoing = + m_AnimationInstance->advance(elapsedSeconds * speed(), m_AnimationInstance.get()); } if (mix() != 0.0f) { diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index 1f0b0a2a..e70d4f40 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -4,6 +4,7 @@ #include "rive/animation/cubic_interpolator.hpp" #include "rive/animation/entry_state.hpp" #include "rive/animation/layer_state_flags.hpp" +#include "rive/animation/nested_linear_animation.hpp" #include "rive/animation/nested_state_machine.hpp" #include "rive/animation/state_instance.hpp" #include "rive/animation/state_machine_bool.hpp" @@ -18,6 +19,7 @@ #include "rive/animation/state_transition.hpp" #include "rive/animation/transition_condition.hpp" #include "rive/animation/state_machine_fire_event.hpp" +#include "rive/event_report.hpp" #include "rive/hit_result.hpp" #include "rive/math/aabb.hpp" #include "rive/math/hit_test.hpp" @@ -669,18 +671,20 @@ StateMachineInstance::StateMachineInstance(const StateMachine* machine, auto hn = rivestd::make_unique(nestedArtboard->as(), this); m_hitComponents.push_back(std::move(hn)); - - for (auto animation : nestedArtboard->nestedAnimations()) + } + for (auto animation : nestedArtboard->nestedAnimations()) + { + if (animation->is()) { - if (animation->is()) - { - animation->as() - ->stateMachineInstance() - ->setParentNestedArtboard(nestedArtboard); - animation->as() - ->stateMachineInstance() - ->setParentStateMachineInstance(this); - } + auto notifier = animation->as()->stateMachineInstance(); + notifier->setNestedArtboard(nestedArtboard); + notifier->addNestedEventListener(this); + } + else if (animation->is()) + { + auto notifier = animation->as()->animationInstance(); + notifier->setNestedArtboard(nestedArtboard); + notifier->addNestedEventListener(this); } } } @@ -880,6 +884,11 @@ const EventReport StateMachineInstance::reportedEventAt(std::size_t index) const return m_reportedEvents[index]; } +void StateMachineInstance::notify(const std::vector& events, NestedArtboard* context) +{ + notifyEventListeners(events, context); +} + void StateMachineInstance::notifyEventListeners(const std::vector& events, NestedArtboard* source) { @@ -920,9 +929,12 @@ void StateMachineInstance::notifyEventListeners(const std::vector& } } // Bubble the event up to parent artboard state machines immediately - if (m_parentStateMachineInstance != nullptr) + if (nestedArtboard() != nullptr) { - m_parentStateMachineInstance->notifyEventListeners(events, m_parentNestedArtboard); + for (auto listener : nestedEventListeners()) + { + listener->notify(events, nestedArtboard()); + } } for (auto report : events)