When you call enter/resume, the coroutine will exit exactly right where you entered!. Additionally, when you resume a state, it will resume exactly where you exited!
Code: Select all
Usage
run = require 'run'
run2 = run() -- call to create new state
-- define callbacks like you would for love
function run.update(dt)
end
...
function run.draw()
end
-- resume the coroutine and pass (once) arg to run.load callback
-- return true if the coroutine ran successfully plus additional parameters
boolean,... = run.enter(arg)
-- yield the coroutine and pass any additional parameters when yielding
run.exit(...)
Code: Select all
local resume= coroutine.resume
local yield = coroutine.yield
local insert= table.insert
local unpack= unpack
local function getEvents(t)
local __eventqueue = {}
if love.event then
love.event.pump()
for e,a,b,c,d in love.event.poll() do
insert(__eventqueue,{e,a,b,c,d})
end
end
return __eventqueue
end
local function pushEvents(t)
if love.event then
local eq = t.__eventqueue
for i = 1,#t.__eventqueue do
love.event.push(unpack(eq[i]))
eq[i] = nil
end
end
end
local function swapEvents(t)
local __eventqueue = getEvents(t)
pushEvents(t)
t.__eventqueue = __eventqueue
end
local function new()
local t = {__eventqueue = {}}
local run = coroutine.create(function(arg)
if t.load then t.load(arg) end
while true do
if love.event then
love.event.pump()
for e,a,b,c,d in love.event.poll() do
if e == "quit" then
if not t.quit or not t.quit() then
-- if love.audio then -- manually handle audio per state
-- love.audio.stop()
-- end
swapEvents(t)
return
end
end
if t[e] then t[e](a,b,c,d) end
end
end
if love.timer then
love.timer.step()
dt = love.timer.getDelta()
end
if t.update then t.update(dt) end
if love.graphics then
love.graphics.clear()
if t.draw then t.draw() end
end
if love.timer then love.timer.sleep(0.001) end
if love.graphics then love.graphics.present() end
end
end)
local function exit(...)
swapEvents(t)
yield(...)
end
local function enter(arg)
swapEvents(t)
return resume(run,arg)
end
t.enter = enter
t.exit = exit
return t
end
return setmetatable(new(),{__call = function(self) return new() end})