Nested linear animations report events up to parent artboards

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>
diff --git a/.rive_head b/.rive_head
index 00cccbb..918acd8 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 316b0c7..d04d596 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 @@
     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 7de512c..6d30727 100644
--- a/include/rive/animation/nested_linear_animation.hpp
+++ b/include/rive/animation/nested_linear_animation.hpp
@@ -15,6 +15,7 @@
     ~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 4618a82..13e3740 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 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 @@
 
     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;
diff --git a/include/rive/event_report.hpp b/include/rive/event_report.hpp
new file mode 100644
index 0000000..fe56315
--- /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 843739e..fc31df6 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 <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:
diff --git a/src/animation/linear_animation_instance.cpp b/src/animation/linear_animation_instance.cpp
index f40f8af..1399912 100644
--- a/src/animation/linear_animation_instance.cpp
+++ b/src/animation/linear_animation_instance.cpp
@@ -245,3 +245,9 @@
 }
 
 float LinearAnimationInstance::durationSeconds() const { return m_animation->durationSeconds(); }
+
+void LinearAnimationInstance::reportEvent(Event* event, float secondsDelay)
+{
+    const std::vector<Event*> 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 dd6bb6e..c747fd2 100644
--- a/src/animation/nested_simple_animation.cpp
+++ b/src/animation/nested_simple_animation.cpp
@@ -10,7 +10,8 @@
     {
         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 1f0b0a2..e70d4f4 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 @@
             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);
             }
         }
     }
@@ -880,6 +884,11 @@
     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)
 {
@@ -920,9 +929,12 @@
             }
         }
         // 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)