chore: process listeners in specified order (#11487) 3253c0beae
* chore: process listeners in specified order

* resolve sorting on export

Co-authored-by: hernan <hernan@rive.app>
diff --git a/.rive_head b/.rive_head
index 5404d80..a1a4e90 100644
--- a/.rive_head
+++ b/.rive_head
@@ -1 +1 @@
-c83919a2477577deac9afdc2f22b83b9093e4b93
+3253c0beae3bdc2d68db7cf52eb4490e17276c58
diff --git a/tests/unit_tests/assets/sorted_listeners.riv b/tests/unit_tests/assets/sorted_listeners.riv
new file mode 100644
index 0000000..2e78487
--- /dev/null
+++ b/tests/unit_tests/assets/sorted_listeners.riv
Binary files differ
diff --git a/tests/unit_tests/runtime/state_machine_test.cpp b/tests/unit_tests/runtime/state_machine_test.cpp
index 0357a8a..3a4d3d4 100644
--- a/tests/unit_tests/runtime/state_machine_test.cpp
+++ b/tests/unit_tests/runtime/state_machine_test.cpp
@@ -527,4 +527,67 @@
     artboard->draw(renderer.get());
 
     CHECK(silver.matches("transition_index_condition"));
+}
+
+TEST_CASE("Listeners are sorted in the right order", "[silver]")
+{
+    SerializingFactory silver;
+    auto file = ReadRiveFile("assets/sorted_listeners.riv", &silver);
+
+    auto artboard = file->artboardDefault();
+    silver.frameSize(artboard->width(), artboard->height());
+
+    auto stateMachine = artboard->stateMachineAt(0);
+
+    auto vmi = file->createViewModelInstance(artboard.get());
+
+    stateMachine->bindViewModelInstance(vmi);
+    stateMachine->advanceAndApply(0.0f);
+    auto renderer = silver.makeRenderer();
+    artboard->draw(renderer.get());
+
+    // Down (Move + Down happen on the same frame, but down happens after move)
+    silver.addFrame();
+    stateMachine->pointerDown(Vec2D(250.0f, 250.0f), 0);
+    stateMachine->advanceAndApply(0.016f);
+    artboard->draw(renderer.get());
+
+    // Click (Up + Click on same frame, but click happens after up)
+    silver.addFrame();
+    stateMachine->pointerUp(Vec2D(250.0f, 250.0f), 0);
+    stateMachine->advanceAndApply(0.016f);
+    artboard->draw(renderer.get());
+
+    // Exit
+    silver.addFrame();
+    stateMachine->pointerMove(Vec2D(0.0f, 0.0f), 0, 0);
+    stateMachine->advanceAndApply(0.016f);
+    artboard->draw(renderer.get());
+
+    // Drag gesture
+    silver.addFrame();
+    stateMachine->pointerDown(Vec2D(250.0f, 250.0f), 0);
+    stateMachine->pointerMove(Vec2D(251.0f, 251.0f), 0);
+    stateMachine->advanceAndApply(0.016f);
+    artboard->draw(renderer.get());
+
+    // Up
+    silver.addFrame();
+    stateMachine->pointerUp(Vec2D(251.0f, 251.0f), 0);
+    stateMachine->advanceAndApply(0.016f);
+    artboard->draw(renderer.get());
+
+    // Exit
+    silver.addFrame();
+    stateMachine->pointerMove(Vec2D(0.0f, 0.0f), 0);
+    stateMachine->advanceAndApply(0.016f);
+    artboard->draw(renderer.get());
+
+    // (Move): Enter + Move, but move happens after enter
+    silver.addFrame();
+    stateMachine->pointerMove(Vec2D(251.0f, 251.0f), 0);
+    stateMachine->advanceAndApply(0.016f);
+    artboard->draw(renderer.get());
+
+    CHECK(silver.matches("sorted_listeners"));
 }
\ No newline at end of file
diff --git a/tests/unit_tests/silvers/sorted_listeners.sriv b/tests/unit_tests/silvers/sorted_listeners.sriv
new file mode 100644
index 0000000..b418248
--- /dev/null
+++ b/tests/unit_tests/silvers/sorted_listeners.sriv
Binary files differ