85 lines
4.0 KiB
Lua
85 lines
4.0 KiB
Lua
-------------------------------------------------------------------------------
|
|
--[[on-tick queue]] --
|
|
-------------------------------------------------------------------------------
|
|
-- Concept designed and code written by TheStaplergun (staplergun on mod portal)
|
|
-- STDLib and code reviews provided by Nexela
|
|
--[[
|
|
|
|
To add your mod to the queue copy the following code somewhere in your mod at a point where it's been determined that the work needs to be distributed:
|
|
--STDLIB-----------------------------------------------------------------------
|
|
local token = remote.call("PickerAtheneum","queue_add",{mod_name = "YourModName_QueuedTaskAbbreviation"}) --The additional queued task abbreviation allows you to queue multiple things within the same mod
|
|
global.remote_queue_token = token
|
|
Event.register(token, function_to_call_each_turn)
|
|
--NO STD LIB-------------------------------------------------------------------
|
|
local token = remote.call("PickerAtheneum","queue_add",{mod_name = "YourModName_QueuedTaskAbbreviation"}) --The additional queued task abbreviation allows you to queue multiple things within the same mod
|
|
global.remote_queue_token = token
|
|
script.on_event(token, function_to_call_each_turn)
|
|
|
|
|
|
To remove your mod from the queue and de-register the listener, add this code somewhere in your mod once the work is done:
|
|
--STDLIB-----------------------------------------------------------------------
|
|
remote.call("PickerAtheneum","queue_remove",{token = global.remote_queue_token})
|
|
--NO STD LIB-------------------------------------------------------------------
|
|
remote.call("PickerAtheneum","queue_remove",{token = global.remote_queue_token})
|
|
|
|
]]
|
|
local Event = require('__stdlib__/stdlib/event/event')
|
|
local Interface = require('__stdlib__/stdlib/scripts/interface')
|
|
local Queue = require('__stdlib__/stdlib/misc/queue')
|
|
|
|
local options = {
|
|
protected_mode = false,
|
|
skip_valid = true
|
|
}
|
|
|
|
--Cycle through the array stored in global one time per tick and perform remote.call with the mod name and function name provided during "queue_add"
|
|
local function queue_tick()
|
|
local queue = global.remote_queue:pop_and_push()
|
|
if queue then
|
|
if remote.interfaces[queue.interface] and remote.interfaces[queue.interface][queue.func_name] then
|
|
remote.call(queue.interface, queue.func_name)
|
|
else
|
|
Interface.queue_remove(queue.interface, queue.func_name)
|
|
end
|
|
end
|
|
end
|
|
|
|
--Add a mod to the queue. Initializes the queue system if it isn't running. A mod calls remote.call and provides a table with name and f_name parameters, and it is stored in a global array.
|
|
--@tparam name The name of the calling mod
|
|
--@tparam f_name The name of the function assigned to the interface in the remote mod
|
|
Interface['queue_add'] = function(interface, func_name)
|
|
if not global.remote_queue then
|
|
global.remote_queue = Queue()
|
|
Event.register(defines.events.on_tick, queue_tick, nil, nil, options)
|
|
end
|
|
global.remote_queue {interface = interface, func_name = func_name}
|
|
return true
|
|
end
|
|
|
|
--Remove a mod from the queue. Searches for the relevant mod by the provided name from the remote.call and removes the entry from the queue. Also makes sure index stays within bounds. Also unregisters the on_tick handler if the queue is empty.
|
|
--@tparam name The name of the calling mod
|
|
Interface['queue_remove'] = function(interface, func_name)
|
|
if global.remote_queue then
|
|
for k, v in global.remote_queue:pairs() do
|
|
if v.interface == interface and v.func_name == func_name then
|
|
global.remote_queue.objects[k] = nil
|
|
end
|
|
end
|
|
global.remote_queue:sort()
|
|
if #global.remote_queue == 0 then -- Check if queue is empty
|
|
global.remote_queue = nil
|
|
Event.remove(defines.events.on_tick, queue_tick) -- Unregister event handler if empty
|
|
end
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function on_load()
|
|
if global.remote_queue then
|
|
Queue.load(global.remote_queue)
|
|
Event.register(defines.events.on_tick, queue_tick, nil, nil, options)
|
|
end
|
|
end
|
|
Event.on_load(on_load)
|