I recently revisited an old project of mine and realized I had never gotten a system finished. - To keep it short, I need to find a way to temporarily yield code at any given point in a function by using a BindableEvent, (might be unreliable but I’m not much of an experienced scripter), and then being able to resume the code by using a different event.
Within a larger function of a ModuleScript I have set up for one of the in-game events, I have this function at the top:
YieldEvent.Event:Connect(function()
print("Event signal received, yielding script.")
repeat wait() until ResEvent.Event
print("Event signal received, resuming script.")
end)
This function’s intended purpose is to stop the larger function when YieldEvent is called, no matter which line of code is being executed next. (Is that a good way to describe it?) And then resume the function when ResEvent is called.
When YieldEvent is called, it doesn’t do its proper function and doesn’t yield the whole script, my only assumption being that it runs as a separate function compared to the rest of the script. How would I make it so that the wait() loop stops the rest of the code momentarily until ResEvent is called? Would I need to code a special wait function for the script, or is there a simpler solution?
tl;dr : trying to figure out how to stop/resume a script midway, tried a couple of things already, need help.
(edited) Actually from what I’ve observed if you’re using bindableEvents your best bet is just to use BindableEvent.Event:Wait();
if you however are customly making your own events then a possible approach could be this
– scripts calling it
module scripts
```local totalWaits = 0
local stopTable = {}
function Wait()
totalWaits += 1
local CurrentIteration = totalWaits
local currentThread = coroutine.running()
stopTable[CurrentIteration] = false
task.spawn(function()
while true do
task.wait()
if stopTable[CurrentIteration] == true then
task.spawn(currentThread)
end
end
end)
return coroutine.yield()
end
function UnWait(SpecificThread)
-- this will be a number, every thread halted using these functions will have a unique number assigned to them
stopTable[SpecificThread] = true
end
The supposed-to-be yield function (highlighted in the image) is part of a larger function that is called by an external script. (in-game event that is inside a ModuleScript for organization purposes)
To yield the main function, you can create a new thread for it which can be yielded from the outside. Here’s an example:
function main()
while task.wait() do
print("I'm running!")
end
end
local thread = coroutine.create(main)
local function pause()
coroutine.yield(thread)
end
local function resume()
coroutine.resume(thread)
end
YieldEvent.Event:Connect(pause)
ResumeEvent.Event:Connect(resume)
resume()
--Promise use case example
module.Start = function()
return Promise.new(function(resolve, _, onCancel)
local cancel = false
if onCancel(function() cancel = true end) return end
function OpenBlastShelters()
end
function LockBlastShelters()
end
while not cancel do
--do whatever game logic
task.wait(1)
end
resolve() --call when finished thread
end)
end)
--and this is how you use it:
local startPromise = module.Start()
YieldEvent.Event:Connect(function() startPromise:cancel() end)
After actually testing my solution, I realized that coroutine.yield is only capable of yielding the current thread, as opposed to a thread the current thread has created. I apologize for providing an incorrect solution.
However, if the main function can be reran from the top upon unpausing you could do something like this:
function loop()
print("Even though I'm not part of the loop, since the function was reran from the top I ran again. Put me outside of this function if you don't want that to happen.")
while task.wait() do
print("I'm running!")
end
end
local thread
local function pause()
coroutine.close(thread)
end
local function resume()
thread = coroutine.create(loop)
coroutine.resume(thread)
end
workspace.Yield.Event:Connect(pause)
workspace.Resume.Event:Connect(resume)
resume()
Hope this works for you, and sorry for both the incorrect response and late reply!
I looked into this a little and I’m still having a hard time understanding it. Only replying again now since I have not gotten a different response in >24hrs.
I haven’t tried this yet but after looking at the Promises page and this code, I have a few questions.
When the YieldEvent is called, it seems that the function is stopped completely. Is there a way to only pause it momentarily until ResEvent is called?
Where do I put the startPromise function? Does it go into the ModuleScript or do I need to put it into a separate script?