mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-12 08:21:02 +02:00
The shrink timeline called finish() every frame once past its end. finish() emits finished and then pops the stack, so a listener that pushes a screen (a warp, a menu) had that screen popped in the speech's place: the speech stayed alive and re-fired the event every frame, repeating the listener's side effects each time. Clear the shrink state before finishing so the timeline cannot run finish() twice. Co-authored-by: johnjohto <johnjohto@users.noreply.github.com>
This commit is contained in:
@@ -549,6 +549,10 @@ function OakSpeech:update(dt)
|
||||
elseif s.frame >= 79 and s.frame <= 102 then
|
||||
self.fadeLevel = math.floor((s.frame - 79) / 8) + 1
|
||||
elseif s.frame > 102 then
|
||||
-- clear before finish(): a finished-listener that pushes a state gets
|
||||
-- ITS state popped in the speech's place, and a live shrink would call
|
||||
-- finish() again next frame, re-firing the event every frame (#308)
|
||||
self.shrink = nil
|
||||
self:finish()
|
||||
end
|
||||
end
|
||||
|
||||
@@ -788,6 +788,27 @@ check(type("intro.oak_speech.started") == "string"
|
||||
"intro.oak_speech lifecycle event names are stable")
|
||||
events:removeOwner("fixture")
|
||||
|
||||
-- issue #308: finish runs once even when a finished-listener pushes a
|
||||
-- screen (the pop in finish() then removes that screen instead of the
|
||||
-- speech, and a live shrink re-fires the event every frame)
|
||||
do
|
||||
local fgame = { data = {}, stack = newStack(), input = newInput(),
|
||||
save = { player = {} } }
|
||||
local fspeech = OakSpeech.new(fgame, nil)
|
||||
fspeech.shrink = { frame = 103 } -- past the shrink timeline's end
|
||||
fgame.stack:push(fspeech)
|
||||
fspeech.picReveal = nil -- skip the intro fade so update reaches shrink
|
||||
local finishes = 0
|
||||
events:on("intro.oak_speech.finished", function()
|
||||
finishes = finishes + 1
|
||||
fgame.stack:push({ pushedByListener = true }) -- the #308 trap
|
||||
end, 0, "t308")
|
||||
for _ = 1, 3 do fspeech:update(1 / 60) end
|
||||
events:removeOwner("t308")
|
||||
check(finishes == 1,
|
||||
"finished fires once when a listener pushes a screen")
|
||||
end
|
||||
|
||||
-- ModUI step helpers
|
||||
local tiny = { { id = "a" }, { id = "c" } }
|
||||
ModUI.insertStepAfter(tiny, "a", { id = "b" })
|
||||
|
||||
Reference in New Issue
Block a user