Skip to content

Commit

Permalink
Nested linear animations report events up to parent artboards
Browse files Browse the repository at this point in the history
Previously, only nested state machines could report events so that listeners in parent artboards could listen for them. This PR adds event reporting for nested simple animations. Had to refactor some stuff to genericize in order for both state machines and linear animations to have similar functionality.

I'm not sure if its possible, or desirable, for nested remap animations to have the same functionality, but that is not included in this PR.

Diffs=
097b68f56 Nested linear animations report events up to parent artboards (#7310)

Co-authored-by: Philip Chung <philterdesign@gmail.com>
  • Loading branch information
philter and philter committed Jun 11, 2024
1 parent 7101954 commit 3bba1c9
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 29 deletions.
2 changes: 1 addition & 1 deletion .rive_head
Original file line number Diff line number Diff line change
@@ -1 +1 @@
34e186b32dbb956a36807635ea16fe039f988333
097b68f5616951d83b0c5b28345e6bfc9f0b1a5b
5 changes: 4 additions & 1 deletion include/rive/animation/linear_animation_instance.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions include/rive/animation/nested_linear_animation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class NestedLinearAnimation : public NestedLinearAnimationBase
~NestedLinearAnimation() override;

void initializeAnimation(ArtboardInstance*) override;
LinearAnimationInstance* animationInstance() { return m_AnimationInstance.get(); }
};
} // namespace rive

Expand Down
19 changes: 6 additions & 13 deletions include/rive/animation/state_machine_instance.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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<EventReport>& 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;
Expand Down
21 changes: 21 additions & 0 deletions include/rive/event_report.hpp
Original file line number Diff line number Diff line change
@@ -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
48 changes: 48 additions & 0 deletions include/rive/nested_animation.hpp
Original file line number Diff line number Diff line change
@@ -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 <stdio.h>
namespace rive
{
class ArtboardInstance;

class NestedEventListener
{
public:
virtual ~NestedEventListener() {}
virtual void notify(const std::vector<EventReport>& 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<NestedEventListener*> nestedEventListeners() { return m_nestedEventListeners; }

void setNestedArtboard(NestedArtboard* artboard) { m_nestedArtboard = artboard; }
NestedArtboard* nestedArtboard() { return m_nestedArtboard; }

void notifyListeners(const std::vector<Event*>& events)
{
if (m_nestedArtboard != nullptr)
{
std::vector<EventReport> 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<NestedEventListener*> m_nestedEventListeners;
};

class NestedAnimation : public NestedAnimationBase
{
public:
Expand Down
6 changes: 6 additions & 0 deletions src/animation/linear_animation_instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Event*> events{event};
notifyListeners(events);
}
3 changes: 2 additions & 1 deletion src/animation/nested_simple_animation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
38 changes: 25 additions & 13 deletions src/animation/state_machine_instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
Expand Down Expand Up @@ -669,18 +671,20 @@ StateMachineInstance::StateMachineInstance(const StateMachine* machine,
auto hn =
rivestd::make_unique<HitNestedArtboard>(nestedArtboard->as<Component>(), this);
m_hitComponents.push_back(std::move(hn));

for (auto animation : nestedArtboard->nestedAnimations())
}
for (auto animation : nestedArtboard->nestedAnimations())
{
if (animation->is<NestedStateMachine>())
{
if (animation->is<NestedStateMachine>())
{
animation->as<NestedStateMachine>()
->stateMachineInstance()
->setParentNestedArtboard(nestedArtboard);
animation->as<NestedStateMachine>()
->stateMachineInstance()
->setParentStateMachineInstance(this);
}
auto notifier = animation->as<NestedStateMachine>()->stateMachineInstance();
notifier->setNestedArtboard(nestedArtboard);
notifier->addNestedEventListener(this);
}
else if (animation->is<NestedLinearAnimation>())
{
auto notifier = animation->as<NestedLinearAnimation>()->animationInstance();
notifier->setNestedArtboard(nestedArtboard);
notifier->addNestedEventListener(this);
}
}
}
Expand Down Expand Up @@ -880,6 +884,11 @@ const EventReport StateMachineInstance::reportedEventAt(std::size_t index) const
return m_reportedEvents[index];
}

void StateMachineInstance::notify(const std::vector<EventReport>& events, NestedArtboard* context)
{
notifyEventListeners(events, context);
}

void StateMachineInstance::notifyEventListeners(const std::vector<EventReport>& events,
NestedArtboard* source)
{
Expand Down Expand Up @@ -920,9 +929,12 @@ void StateMachineInstance::notifyEventListeners(const std::vector<EventReport>&
}
}
// 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)
Expand Down

0 comments on commit 3bba1c9

Please sign in to comment.