mirror of
https://github.com/Refactorio/RedMew.git
synced 2024-12-12 10:04:40 +02:00
93 lines
2.9 KiB
Lua
93 lines
2.9 KiB
Lua
-- Threading simulation module
|
|
-- Task.sleep()
|
|
-- @author Valansch and Grilledham
|
|
-- github: https://github.com/Valansch/RedMew
|
|
-- ======================================================= --
|
|
|
|
local Queue = require 'utils.queue'
|
|
local PriorityQueue = require 'utils.priority_queue'
|
|
local Event = require 'utils.event'
|
|
local Token = require 'utils.token'
|
|
|
|
local Task = {}
|
|
|
|
global.callbacks = global.callbacks or PriorityQueue.new()
|
|
global.next_async_callback_time = -1
|
|
global.task_queue = global.task_queue or Queue.new()
|
|
global.total_task_weight = 0
|
|
global.task_queue_speed = 1
|
|
|
|
local function comp(a, b)
|
|
return a.time < b.time
|
|
end
|
|
|
|
global.tpt = global.task_queue_speed
|
|
local function get_task_per_tick()
|
|
if game.tick % 300 == 0 then
|
|
local size = global.total_task_weight
|
|
global.tpt = math.floor(math.log10(size + 1)) * global.task_queue_speed
|
|
if global.tpt < 1 then
|
|
global.tpt = 1
|
|
end
|
|
end
|
|
return global.tpt
|
|
end
|
|
|
|
local function on_tick()
|
|
local queue = global.task_queue
|
|
for i = 1, get_task_per_tick() do
|
|
local task = Queue.peek(queue)
|
|
if task ~= nil then
|
|
-- result is error if not success else result is a boolean for if the task should stay in the queue.
|
|
local success, result = pcall(Token.get(task.func_token), task.params)
|
|
if not success then
|
|
if _DEBUG then
|
|
error(result)
|
|
else
|
|
log(result)
|
|
end
|
|
Queue.pop(queue)
|
|
global.total_task_weight = global.total_task_weight - task.weight
|
|
elseif not result then
|
|
Queue.pop(queue)
|
|
global.total_task_weight = global.total_task_weight - task.weight
|
|
end
|
|
end
|
|
end
|
|
|
|
local callbacks = global.callbacks
|
|
local callback = PriorityQueue.peek(callbacks)
|
|
while callback ~= nil and game.tick >= callback.time do
|
|
local success, result = pcall(Token.get(callback.func_token), callback.params)
|
|
if not success then
|
|
if _DEBUG then
|
|
error(result)
|
|
else
|
|
log(result)
|
|
end
|
|
end
|
|
PriorityQueue.pop(callbacks, comp)
|
|
callback = PriorityQueue.peek(callbacks)
|
|
end
|
|
end
|
|
|
|
function Task.set_timeout_in_ticks(ticks, func_token, params)
|
|
local time = game.tick + ticks
|
|
local callback = {time = time, func_token = func_token, params = params}
|
|
PriorityQueue.push(global.callbacks, callback, comp)
|
|
end
|
|
|
|
function Task.set_timeout(sec, func_token, params)
|
|
Task.set_timeout_in_ticks(60 * sec, func_token, params)
|
|
end
|
|
|
|
function Task.queue_task(func_token, params, weight)
|
|
weight = weight or 1
|
|
global.total_task_weight = global.total_task_weight + weight
|
|
Queue.push(global.task_queue, {func_token = func_token, params = params, weight = weight})
|
|
end
|
|
|
|
Event.add(defines.events.on_tick, on_tick)
|
|
|
|
return Task
|