Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Timer that can be interrupted immediately (hitting a race condition?)

Asked by 3 years ago

Hello, I've recently came back to developing on Roblox after a few years of time so please be forgiving if it's something simple.

I'm trying to create a timer that counts down, but the catch is that I want it to be stoppable immediately (without finishing the wait).

local __CoroIncrementTimer = coroutine.create(function()
    while true do
        wait(1)
        beLoopControl:Fire(false)
        print("Fired CoroIncrementTimer")
        coroutine.yield()
    end
end)

function StartCountdown(timeFrom)
    timeValue.Value = timeFrom
    for i=60,0,-1 do
        coroutine.resume(__CoroIncrementTimer)
        print("Countdown waiting..")
        local bBreakLoop = beLoopControl.Event:Wait()
        print("Loop continue")
        if bBreakLoop == true then break end -- When the recived event is true that means we needs to exit immediately.
        timeValue.Value = timeValue.Value - 1
    end
end

-- Somewhere in a different coroutine:
beLoopControl:Fire(true) -- End the main loop

beLoopControl is the BindableEvent

How I interpret a single iteration of the loop:

Coroutine is resumed and is ran when the main loop yields waiting for the event.

The coroutine yields for a second, fires the event and yields until next resume.

The loop recieves the event and continues

In theory this approach should let me fire the event with an argument that the loop can then catch and end execution. However in practice the timer just fires once and stops working. The thing is that using the debugger to run the code one by one it works perfectly fine.

I'm assuming there's a race condition happening but I have no idea how to fix it. I imagine that my approach must be fundamentally flawed so I'm open to your propositions on how to fix this problem.

Answer this question