Heya!
I’ve been recently attempting to make a system to queue up the execution of functions, but I can’t get it to work right.
My goal is that I can add a function to a table and the code will execute the functions one by one after the previous function has finished (indicated by a “return true”). It must not prevent other out-of-queue functions from running by being in the way.
The module responsible for making the queues looks like this:
function module.AddToQueue(ID : number, name : string, func)
local enemy = module.Running[ID]
if not enemy then warn("wha-") return end
local queue = enemy[name].Queue
local index = nil
if queue[1] then
index = #queue + 1
else
index = 1
end
queue[index] = func
module.RunFromQueue(queue, index)
end
function module.RunFromQueue(queue, index : number)
local previous = queue[index-1]
if previous then
repeat task.wait()
until previous == true
queue[index]()
queue[index] = nil
else
queue[index]()
queue[index] = nil
end
end
It’s quite self explanatory what every function does.
The other module where I insert functions into the queue looks like this:
local function becomeRandomColor()
print("started")
--- code stuff here lololol
task.wait(3)
warn("done")
return true
end
local function printSomething()
warn("printed")
task.wait(5)
return true
end
abilityHandler.AddToQueue(enemy.ID, script.Name, becomeRandomColor)
abilityHandler.AddToQueue(enemy.ID, script.Name, printSomething)
warn("INTERCEPTOR")
My goal is that even though I added the stuff to the queue it should instantly warn “INTERCEPTOR”.
+
The queued functions should still delay each other as shown:
print: “started”
-wait3-
print: “done”
print: printed
But currently it does the opposite of what it should, it delays functions outside the queue. (so It only warns “INTERCEPTOR” after the 5 second delay from the “printSomething” function has ended)
seems a few features that I might implement differently, i will suggest it as pseudocode below:
you seem to want push some functions that you like the ‘enemy’ to execute one by one (unless one of the function returns non-true value)
-- init
enemy.Queue = {}
-- add to enemy queue
table.insert(enemy.Queue, func)
-- enemy run from queue
local result = true
while result == true do
if #enemy.Queue == 0 then
task.wait()
continue
end
local func = table.remove(enemy.Queue, 1)
result = func()
end
notice we are mainly working with an array of functions,
so using table.insert and table.remove, we don’t need to manage the index ourselves.
also we rely on func() be blocking
local module = {}
local queue = {}
function module.AddToQueue(func)
table.insert(queue, func)
end
function module.RunFromQueue()
local result = true
while result == true do
if #queue == 0 then
task.wait()
continue
end
local func = table.remove(queue, 1)
print("Before execute a function")
result = func()
print("After execute a function", result)
end
end
return module
AddToQueue (Server script)
local FunctionQueue = require(game:GetService("ServerScriptService").FunctionQueue)
local function becomeRandomColor(funcId)
print("becomeRandomColor started", funcId)
task.wait(3)
print("becomeRandomColor ended", funcId)
return true
end
local funcId = 1
while true do
local waitTime = math.random(1, 5)
print("wait", waitTime)
task.wait(waitTime)
print("add to queue", funcId)
local id = funcId
funcId += 1
FunctionQueue.AddToQueue(function()
return becomeRandomColor(id)
end)
end
ExecuteQueue (Server script)
local FunctionQueue = require(game:GetService("ServerScriptService").FunctionQueue)
FunctionQueue.RunFromQueue()
the ExecuteQueue script calls to my RunFromQueue, which itself is a while loop which do task.wait() until something is added.
so technically, it is at most a frame delayed after add to queue
is that okay?
local module = {}
local queue = {}
local func = nil
local function RunFromQueue()
if func then return end
local result = true
while result == true and #queue > 0 do
func = table.remove(queue, 1)
print("Before execute a function")
result = func()
print("After execute a function", result)
func = nil
end
end
function module.AddToQueue(func)
table.insert(queue, func)
RunFromQueue()
end
return module
AddToQueue (Server script)
local FunctionQueue = require(game:GetService("ServerScriptService").FunctionQueue)
local function becomeRandomColor(funcId)
print("becomeRandomColor started", funcId)
task.wait(3)
print("becomeRandomColor ended", funcId)
return true
end
local funcId = 1
while true do
local waitTime = math.random(1, 5)
print("wait", waitTime)
task.wait(waitTime)
print("add to queue", funcId)
local id = funcId
funcId += 1
FunctionQueue.AddToQueue(function()
return becomeRandomColor(id)
end)
end
yes the code i made is for a single queue to demonstrate it should work in your desired way. you will have to pair each queue with a processing func variable