mirror of
https://github.com/hexedtech/codemp-nvim.git
synced 2024-11-22 07:24:52 +01:00
feat: improved async poller for events
now, when :abort() is available, it properly cancels promises so that we dont get dangling references
This commit is contained in:
parent
e8005fbeab
commit
5ae49d3c49
2 changed files with 59 additions and 13 deletions
|
@ -29,18 +29,44 @@ local function color(name)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@class AsyncPoller
|
||||||
|
---@field promise WorkspaceEventPromise | nil
|
||||||
|
---@field timer luv.Timer
|
||||||
|
---@field generator fun(): WorkspaceEventPromise
|
||||||
|
---@field callback fun(e: WorkspaceEvent)
|
||||||
|
---@field stop fun(self: AsyncPoller)
|
||||||
|
|
||||||
|
---@return AsyncPoller
|
||||||
local function async_poller(generator, callback)
|
local function async_poller(generator, callback)
|
||||||
local promise = nil
|
---@type AsyncPoller
|
||||||
local timer = vim.loop.new_timer()
|
local poller = {
|
||||||
timer:start(500, 500, function()
|
promise = nil,
|
||||||
if promise == nil then promise = generator() end
|
generator = generator,
|
||||||
if promise.ready then
|
callback = callback,
|
||||||
local res = promise:await()
|
timer = vim.uv.new_timer(),
|
||||||
vim.schedule(function() callback(res) end)
|
stop = function (this)
|
||||||
promise = nil
|
print("stopping async poller")
|
||||||
|
if this.promise ~= nil then
|
||||||
|
-- TODO the :abort() change still hasnt been merged, so check for its presence!
|
||||||
|
if this.promise.abort ~= nil then
|
||||||
|
this.promise:abort()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
this.timer:stop()
|
||||||
|
this.timer:close()
|
||||||
|
end
|
||||||
|
}
|
||||||
|
poller.timer:start(500, 500, function()
|
||||||
|
print("ticking poller")
|
||||||
|
if poller.promise == nil then poller.promise = poller.generator() end
|
||||||
|
if poller.promise.ready then
|
||||||
|
print("spawning callback")
|
||||||
|
local res = poller.promise:await()
|
||||||
|
vim.schedule(function() poller.callback(res) end)
|
||||||
|
poller.promise = nil
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
return poller
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param first integer
|
---@param first integer
|
||||||
|
|
|
@ -150,6 +150,8 @@ local function register_cursor_handler(controller)
|
||||||
controller:callback(function (_controller) async:send() end)
|
controller:callback(function (_controller) async:send() end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local events_poller = nil
|
||||||
|
|
||||||
---@param workspace string workspace name to join
|
---@param workspace string workspace name to join
|
||||||
---join a workspace and register event handlers
|
---join a workspace and register event handlers
|
||||||
local function join(workspace)
|
local function join(workspace)
|
||||||
|
@ -169,8 +171,14 @@ local function join(workspace)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
require('codemp.window').update()
|
require('codemp.window').update()
|
||||||
utils.poller(
|
local ws_name = ws.name
|
||||||
function() return ws:event() end,
|
events_poller = utils.poller(
|
||||||
|
function()
|
||||||
|
if CODEMP.client == nil then return nil end
|
||||||
|
local wspace = CODEMP.client:get_workspace(ws_name)
|
||||||
|
if wspace == nil then return nil end
|
||||||
|
return wspace:event()
|
||||||
|
end,
|
||||||
function(event)
|
function(event)
|
||||||
if event.type == "leave" then
|
if event.type == "leave" then
|
||||||
if buffers.users[event.value] ~= nil then
|
if buffers.users[event.value] ~= nil then
|
||||||
|
@ -198,9 +206,21 @@ local function join(workspace)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function leave()
|
local function leave()
|
||||||
CODEMP.client:leave_workspace(CODEMP.workspace.name)
|
local name = CODEMP.workspace.name
|
||||||
print(" -- left workspace")
|
|
||||||
CODEMP.workspace = nil
|
CODEMP.workspace = nil
|
||||||
|
if events_poller ~= nil then
|
||||||
|
events_poller:stop()
|
||||||
|
events_poller = nil
|
||||||
|
end
|
||||||
|
if not CODEMP.client:leave_workspace(name) then
|
||||||
|
collectgarbage("collect")
|
||||||
|
-- TODO codemp disconnects when all references to its objects are dropped. since it
|
||||||
|
-- hands out Arc<> of things, all references still not garbage collected in Lua will
|
||||||
|
-- prevent it from disconnecting. while running a full cycle may be a bit slow, this
|
||||||
|
-- only happens when manually requested, and it's not like the extra garbage collection
|
||||||
|
-- is an effort for nothing... still it would be more elegant to not need this!!
|
||||||
|
end
|
||||||
|
print(" -- left workspace " .. name)
|
||||||
require('codemp.window').update()
|
require('codemp.window').update()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue