Fix ping pong hang Fixes issue introduced by #4770 Diffs= 4c5a576ad Fix ping pong hang (#4776)
diff --git a/.rive_head b/.rive_head index ea7d744..4ead8a7 100644 --- a/.rive_head +++ b/.rive_head
@@ -1 +1 @@ -ae1e02afcf18840b4b66d2ba419a26a437057ba5 +4c5a576adaf493b2a152fb69b68021c07aca385f
diff --git a/src/animation/linear_animation_instance.cpp b/src/animation/linear_animation_instance.cpp index e4f16be..702398e 100644 --- a/src/animation/linear_animation_instance.cpp +++ b/src/animation/linear_animation_instance.cpp
@@ -68,7 +68,7 @@ bool didLoop = false; m_SpilledTime = 0.0f; - int direction = speed() * m_Direction < 0 ? -1 : 1; + int direction = speed() < 0 ? -m_Direction : m_Direction; switch (loop()) { case Loop::oneShot: @@ -136,6 +136,7 @@ // where animations are not advanced on regular intervals. break; } + direction = speed() < 0 ? -m_Direction : m_Direction; } break; }
diff --git a/test/draw_order_test.cpp b/test/draw_order_test.cpp index 8567648..c217f36 100644 --- a/test/draw_order_test.cpp +++ b/test/draw_order_test.cpp
@@ -3,6 +3,7 @@ #include <rive/shapes/clipping_shape.hpp> #include <rive/shapes/rectangle.hpp> #include <rive/shapes/shape.hpp> +#include <rive/animation/linear_animation_instance.hpp> #include "utils/no_op_renderer.hpp" #include "rive_file_reader.hpp" #include <catch.hpp> @@ -13,17 +14,26 @@ auto file = ReadRiveFile("../../test/assets/draw_rule_cycle.riv"); // auto file = reader.file(); - // auto node = file->artboard()->node("TopEllipse"); - // REQUIRE(node != nullptr); - // REQUIRE(node->is<rive::Shape>()); - + std::unique_ptr<rive::ArtboardInstance> artboard = file->artboardDefault(); + auto node = artboard->find<rive::Node>("Blue"); + REQUIRE(node != nullptr); + REQUIRE(node->is<rive::Shape>()); // auto shape = node->as<rive::Shape>(); - // REQUIRE(shape->clippingShapes().size() == 2); - // REQUIRE(shape->clippingShapes()[0]->shape()->name() == "ClipRect2"); - // REQUIRE(shape->clippingShapes()[1]->shape()->name() == "BabyEllipse"); - // file->artboard()->updateComponents(); + artboard->updateComponents(); + REQUIRE(artboard->animationCount() == 1); - // rive::NoOpRenderer renderer; - // file->artboard()->draw(&renderer); + // Check that we can advance the ping-pong animation with 1 second duration + // without a hang. + std::unique_ptr<rive::LinearAnimationInstance> animation = artboard->animationAt(0); + // Advance and apply some frames. + int frames = 10; + float frameDuration = 1.0f; + + for (int i = 0; i < frames; i++) + { + animation->advanceAndApply(frameDuration); + rive::NoOpRenderer renderer; + artboard->draw(&renderer); + } }
diff --git a/test/linear_animation_instance_test.cpp b/test/linear_animation_instance_test.cpp index 07f06ad..073cc15 100644 --- a/test/linear_animation_instance_test.cpp +++ b/test/linear_animation_instance_test.cpp
@@ -277,6 +277,29 @@ REQUIRE(linearAnimationInstance->direction() == -1); REQUIRE(linearAnimationInstance->didLoop() == true); REQUIRE(continuePlaying == true); + // pingpong at the start and come back to 6. + continuePlaying = linearAnimationInstance->advance(9.0); + REQUIRE(linearAnimationInstance->time() == 4.0); + REQUIRE(linearAnimationInstance->totalTime() == 16.0); + REQUIRE(linearAnimationInstance->direction() == -1); + REQUIRE(linearAnimationInstance->didLoop() == true); + REQUIRE(continuePlaying == true); + + // pingpong back around to 2 + continuePlaying = linearAnimationInstance->advance(6.0); + REQUIRE(linearAnimationInstance->time() == 2.0); + REQUIRE(linearAnimationInstance->totalTime() == 22.0); + REQUIRE(linearAnimationInstance->direction() == 1); + REQUIRE(linearAnimationInstance->didLoop() == true); + REQUIRE(continuePlaying == true); + + // Loop around twice in a frame. + continuePlaying = linearAnimationInstance->advance(20.0); + REQUIRE(linearAnimationInstance->time() == 2.0); + REQUIRE(linearAnimationInstance->totalTime() == 42.0); + REQUIRE(linearAnimationInstance->direction() == 1); + REQUIRE(linearAnimationInstance->didLoop() == true); + REQUIRE(continuePlaying == true); delete linearAnimationInstance; delete linearAnimation;