From 8710a4f93f4771c37602e1662162878088790773 Mon Sep 17 00:00:00 2001 From: devnguy Date: Thu, 24 Sep 2026 10:25:47 -0500 Subject: [PATCH 1/2] Fix update function so that it properly determines when an animation has finished --- anima/anima.odin | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/anima/anima.odin b/anima/anima.odin index 8cbca6b..c281612 100644 --- a/anima/anima.odin +++ b/anima/anima.odin @@ -165,9 +165,9 @@ new_animation :: proc( anim.oneshot = oneshot anim.flip_h = flip_h anim.flip_v = flip_v + anim.on_finished = on_finished anim.index = 0 anim.time = 0.0 - anim.on_finished = nil return anim } @@ -188,13 +188,14 @@ update :: proc(self: ^Animation, dt: f32) { self.index = (self.index + 1) % u32(len(self.frames)) self.time = 0.0 - on_finished, ok := self.on_finished.(OnFinishedFunc) - if ok { - on_finished(self) - } - - if self.oneshot { - self.playing = false + if self.index == 0 { + on_finished, ok := self.on_finished.(OnFinishedFunc) + if ok { + on_finished(self) + } + if self.oneshot { + self.playing = false + } } } } From 3f3c42e8dacc9c1428aee491120063fe1fe2688e Mon Sep 17 00:00:00 2001 From: Christopher Kaster Date: Tue, 29 Sep 2026 11:10:40 +0200 Subject: [PATCH 2/2] add test for #3 --- anima/anima.odin | 101 ++++++++++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 50 deletions(-) diff --git a/anima/anima.odin b/anima/anima.odin index c281612..8d246b6 100644 --- a/anima/anima.odin +++ b/anima/anima.odin @@ -193,6 +193,7 @@ update :: proc(self: ^Animation, dt: f32) { if ok { on_finished(self) } + if self.oneshot { self.playing = false } @@ -244,53 +245,53 @@ test_update_advances_index :: proc(t: ^testing.T) { testing.expect_value(t, anim.index, u32(2)) } -// @(private) -// test_on_finished_count: int -// -// @(private) -// test_on_finished :: proc(_: ^Animation) { -// test_on_finished_count += 1 -// } -// -// @(test) -// test_on_finished_fires_when_index_loops_to_zero :: proc(t: ^testing.T) { -// test_on_finished_count = 0 -// -// grid := new_grid(16, 16, 64, 16) -// frames := grid_frames( -// &grid, -// "0-3", -// 0, -// allocator = context.temp_allocator, -// temp_allocator = context.temp_allocator, -// ) -// -// anim := new_animation( -// frames, -// 0.1, -// on_finished = test_on_finished, -// allocator = context.temp_allocator, -// ) -// defer destroy_animation(anim, context.temp_allocator) -// -// testing.expect(t, anim.on_finished != nil) -// -// update(anim, 0.1) -// update(anim, 0.1) -// update(anim, 0.1) -// -// testing.expect_value(t, anim.index, u32(3)) -// testing.expect_value(t, test_on_finished_count, 0) -// -// update(anim, 0.1) -// -// testing.expect_value(t, anim.index, u32(0)) -// testing.expect_value(t, test_on_finished_count, 1) -// testing.expect_value(t, anim.playing, true) -// -// for _ in 0 ..< 4 { -// update(anim, 0.1) -// } -// -// testing.expect_value(t, test_on_finished_count, 2) -// } +@(private) +test_on_finished_count: int + +@(private) +test_on_finished :: proc(_: ^Animation) { + test_on_finished_count += 1 +} + +@(test) +test_on_finished_fires_when_index_loops_to_zero :: proc(t: ^testing.T) { + test_on_finished_count = 0 + + grid := new_grid(16, 16, 64, 16) + frames := grid_frames( + &grid, + "0-3", + 0, + allocator = context.temp_allocator, + temp_allocator = context.temp_allocator, + ) + + anim := new_animation( + frames, + 0.1, + on_finished = test_on_finished, + allocator = context.temp_allocator, + ) + defer destroy_animation(anim, context.temp_allocator) + + testing.expect(t, anim.on_finished != nil) + + update(anim, 0.1) + update(anim, 0.1) + update(anim, 0.1) + + testing.expect_value(t, anim.index, u32(3)) + testing.expect_value(t, test_on_finished_count, 0) + + update(anim, 0.1) + + testing.expect_value(t, anim.index, u32(0)) + testing.expect_value(t, test_on_finished_count, 1) + testing.expect_value(t, anim.playing, true) + + for _ in 0 ..< 4 { + update(anim, 0.1) + } + + testing.expect_value(t, test_on_finished_count, 2) +}