Upload files to "lwcomponents"
This commit is contained in:
parent
68a94d636e
commit
12990637cc
5 changed files with 2230 additions and 0 deletions
196
lwcomponents/long_process.lua
Normal file
196
lwcomponents/long_process.lua
Normal file
|
@ -0,0 +1,196 @@
|
|||
local utils = ...
|
||||
|
||||
|
||||
|
||||
local RUN_INTERVAL = 0.1
|
||||
|
||||
|
||||
|
||||
local processes = { index = 0, current = 0 }
|
||||
local after_job
|
||||
|
||||
|
||||
|
||||
local function run_processes ()
|
||||
if #processes > 0 then
|
||||
processes.index = (processes.index % #processes) + 1
|
||||
|
||||
local process = processes[processes.index]
|
||||
|
||||
processes.current = processes.index
|
||||
process.timer = os.clock ()
|
||||
process.resume ()
|
||||
processes.current = 0
|
||||
end
|
||||
|
||||
if #processes > 0 then
|
||||
after_job = minetest.after (RUN_INTERVAL, run_processes)
|
||||
else
|
||||
processes.index = 0
|
||||
processes.current = 0
|
||||
after_job = nil
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
local long_process = { }
|
||||
|
||||
|
||||
|
||||
function long_process.remove (id)
|
||||
if id then
|
||||
for i = 1, #processes, 1 do
|
||||
if processes[i].id == id then
|
||||
local breaker = ((processes.current == id) and processes[i].breaker)
|
||||
|
||||
if processes.current == i then
|
||||
processes.current = 0
|
||||
elseif processes.current > i then
|
||||
processes.current = processes.current - 1
|
||||
end
|
||||
|
||||
if processes.index >= i then
|
||||
processes.index = processes.index - 1
|
||||
end
|
||||
|
||||
table.remove (processes, i)
|
||||
|
||||
if breaker then
|
||||
breaker ()
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
elseif processes[processes.current] then
|
||||
local breaker = processes[processes.current].breaker
|
||||
|
||||
if processes.index >= processes.current then
|
||||
processes.index = processes.index - 1
|
||||
end
|
||||
|
||||
table.remove (processes, processes.current)
|
||||
processes.current = 0
|
||||
|
||||
if breaker then
|
||||
breaker ()
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
|
||||
function long_process.breaker (id)
|
||||
if id then
|
||||
for i = 1, #processes, 1 do
|
||||
if processes[i].id == id then
|
||||
return processes[i].breaker
|
||||
end
|
||||
end
|
||||
elseif processes[processes.current] then
|
||||
return processes[processes.current].breaker
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
|
||||
function long_process.timer (id)
|
||||
if id then
|
||||
for i = 1, #processes, 1 do
|
||||
if processes[i].id == id then
|
||||
return processes[i].timer
|
||||
end
|
||||
end
|
||||
elseif processes[processes.current] then
|
||||
return processes[processes.current].timer
|
||||
end
|
||||
|
||||
return os.clock () + 3600
|
||||
end
|
||||
|
||||
|
||||
|
||||
function long_process.expire (secs, id)
|
||||
if id then
|
||||
for i = 1, #processes, 1 do
|
||||
if processes[i].id == id then
|
||||
if (processes[i].timer + secs) <= os.clock () then
|
||||
processes[i].breaker ()
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif processes[processes.current] then
|
||||
if (processes[processes.current].timer + secs) <= os.clock () then
|
||||
processes[processes.current].breaker ()
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
|
||||
function long_process.add (func, callback, ...)
|
||||
local args = { ... }
|
||||
local id = math.random (1000000)
|
||||
local thread
|
||||
|
||||
|
||||
local function thread_breaker ()
|
||||
coroutine.yield (thread)
|
||||
end
|
||||
|
||||
|
||||
local function thread_func ()
|
||||
return func (unpack (args))
|
||||
end
|
||||
|
||||
|
||||
local function thread_resume ()
|
||||
local results = { coroutine.resume (thread) }
|
||||
|
||||
if coroutine.status (thread) == "dead" then
|
||||
if callback then
|
||||
callback (id, unpack (results))
|
||||
end
|
||||
|
||||
long_process.remove (id)
|
||||
end
|
||||
end
|
||||
|
||||
thread = coroutine.create (thread_func)
|
||||
|
||||
if thread and coroutine.status (thread) == "suspended" then
|
||||
processes[#processes + 1] =
|
||||
{
|
||||
id = id,
|
||||
resume = thread_resume,
|
||||
breaker = thread_breaker,
|
||||
callback = callback,
|
||||
timer = os.clock ()
|
||||
}
|
||||
|
||||
if not after_job then
|
||||
after_job = minetest.after (RUN_INTERVAL, run_processes)
|
||||
end
|
||||
|
||||
return id
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
|
||||
utils.long_process = long_process
|
Loading…
Add table
Add a link
Reference in a new issue