mirror of
https://github.com/kepler155c/opus
synced 2025-01-14 09:25:42 +00:00
reduce coroutine creation
This commit is contained in:
parent
39e8307511
commit
d5896ca873
@ -1,4 +1,5 @@
|
|||||||
local os = _G.os
|
local os = _G.os
|
||||||
|
local table = _G.table
|
||||||
|
|
||||||
local Event = {
|
local Event = {
|
||||||
uid = 1, -- unique id for handlers
|
uid = 1, -- unique id for handlers
|
||||||
@ -6,8 +7,29 @@ local Event = {
|
|||||||
types = { }, -- event handlers
|
types = { }, -- event handlers
|
||||||
timers = { }, -- named timers
|
timers = { }, -- named timers
|
||||||
terminate = false,
|
terminate = false,
|
||||||
|
free = { },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- Use a pool of coroutines for event handlers
|
||||||
|
local function createCoroutine(h)
|
||||||
|
local co = table.remove(Event.free)
|
||||||
|
if not co then
|
||||||
|
co = coroutine.create(function(_, ...)
|
||||||
|
local args = { ... }
|
||||||
|
while true do
|
||||||
|
h.fn(table.unpack(args))
|
||||||
|
h.co = nil
|
||||||
|
table.insert(Event.free, co)
|
||||||
|
args = { coroutine.yield() }
|
||||||
|
h = table.remove(args, 1)
|
||||||
|
h.co = co
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
h.primeCo = true -- TODO: fix...
|
||||||
|
return co
|
||||||
|
end
|
||||||
|
|
||||||
local Routine = { }
|
local Routine = { }
|
||||||
|
|
||||||
function Routine:isDead()
|
function Routine:isDead()
|
||||||
@ -24,18 +46,20 @@ function Routine:terminate()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Routine:resume(event, ...)
|
function Routine:resume(event, ...)
|
||||||
--if coroutine.status(self.co) == 'running' then
|
|
||||||
--return
|
|
||||||
--end
|
|
||||||
|
|
||||||
if not self.co then
|
if not self.co then
|
||||||
error('Cannot resume a dead routine')
|
error('Cannot resume a dead routine')
|
||||||
end
|
end
|
||||||
|
|
||||||
if not self.filter or self.filter == event or event == "terminate" then
|
if not self.filter or self.filter == event or event == "terminate" then
|
||||||
local s, m = coroutine.resume(self.co, event, ...)
|
local s, m
|
||||||
|
if self.primeCo then
|
||||||
if coroutine.status(self.co) == 'dead' then
|
-- Only need self passed when using a coroutine from the pool
|
||||||
|
s, m = coroutine.resume(self.co, self, event, ...)
|
||||||
|
self.primeCo = nil
|
||||||
|
else
|
||||||
|
s, m = coroutine.resume(self.co, event, ...)
|
||||||
|
end
|
||||||
|
if self:isDead() then
|
||||||
self.co = nil
|
self.co = nil
|
||||||
self.filter = nil
|
self.filter = nil
|
||||||
Event.routines[self.uid] = nil
|
Event.routines[self.uid] = nil
|
||||||
@ -83,8 +107,12 @@ end
|
|||||||
function Event.off(h)
|
function Event.off(h)
|
||||||
if h and h.event then
|
if h and h.event then
|
||||||
for _,event in pairs(h.event) do
|
for _,event in pairs(h.event) do
|
||||||
|
local handler = Event.types[event][h.uid]
|
||||||
|
handler:terminate()
|
||||||
Event.types[event][h.uid] = nil
|
Event.types[event][h.uid] = nil
|
||||||
end
|
end
|
||||||
|
elseif h and h.co then
|
||||||
|
h:terminate()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -107,7 +135,12 @@ local function addTimer(interval, recurring, fn)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Event.onInterval(interval, fn)
|
function Event.onInterval(interval, fn)
|
||||||
return addTimer(interval, true, fn)
|
return Event.addRoutine(function()
|
||||||
|
while true do
|
||||||
|
os.sleep(interval)
|
||||||
|
fn()
|
||||||
|
end
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Event.onTimeout(timeout, fn)
|
function Event.onTimeout(timeout, fn)
|
||||||
@ -183,7 +216,7 @@ local function processHandlers(event)
|
|||||||
for _,h in pairs(handlers) do
|
for _,h in pairs(handlers) do
|
||||||
if not h.co then
|
if not h.co then
|
||||||
-- callbacks are single threaded (only 1 co per handler)
|
-- callbacks are single threaded (only 1 co per handler)
|
||||||
h.co = coroutine.create(h.fn)
|
h.co = createCoroutine(h)
|
||||||
Event.routines[h.uid] = h
|
Event.routines[h.uid] = h
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user