Files

106 lines
2.0 KiB
Lua

local co = coroutine
local uv = vim.loop
local LinkedList = require('telescope.algos.linked_list')
local modes = setmetatable({
init = "init",
next = "next",
done = "done",
}, { __index = function(_, k)
error(string.format("'%s' is not a valid mode", k))
end })
local is_dead = function(c)
return co.status(c) == "dead"
end
local Executor = {}
Executor.__index = Executor
-- TODO: I would like to make it so we just have one function for each task,
-- but I think it's fine for now to store both things.
function Executor:new(func)
return setmetatable({
func = func,
-- mode = modes.init,
-- tasks = LinkedList:new(),
-- Will be initialized at each run.
_idle = nil,
}, self)
end
function Executor:run()
if not self._idle then
self._idle = uv.new_idle()
-- self._idle = uv.new_check()
end
self._idle:start((function()
-- if self.tasks.size == 0 then
-- return self:stop()
-- end
self:step()
if true then return end
if self.mode == modes.init then
self:start()
end
if self.mode == modes.next then
self:step()
elseif self.mode == modes.done then
self:complete()
else
error(debug.traceback("Unknown mode: " .. tostring(self.mode)))
end
end))
end
function Executor:start()
self.mode = modes.next
end
function Executor:step()
co.resume(self.func)
if is_dead(self.func) then
print("DEAD")
-- self.tasks:shift()
return self:stop()
else
return self
end
if self.tasks.size == 0 then return end
local task = self.tasks.head.item
if task == nil then
error("Should not get step with no tasks left")
end
local task_co = task[1]
co.resume(task_co, unpack(task[2]))
if is_dead(task_co) then
print("DEAD")
self.tasks:shift()
end
end
function Executor:complete()
end
function Executor:stop()
if not self._idle then return end
self._idle:stop()
self._idle:close()
self._idle = nil
return self
end
return Executor