mirror of
https://github.com/britzl/monarch.git
synced 2025-06-27 10:27:49 +02:00
Improved on the state handling while showing/hiding screens
Also added simple debug logging
This commit is contained in:
parent
6caa41e9f6
commit
007a4eced3
@ -1,6 +1,7 @@
|
|||||||
local monarch = require "monarch.monarch"
|
local monarch = require "monarch.monarch"
|
||||||
|
|
||||||
function init(self)
|
function init(self)
|
||||||
|
monarch.debug()
|
||||||
msg.post("@render:/", "clear_color", { color = vmath.vector4(0.4, 0.6, 0.8,1.0) })
|
msg.post("@render:/", "clear_color", { color = vmath.vector4(0.4, 0.6, 0.8,1.0) })
|
||||||
msg.post("#", "init_monarch") -- wait until init() has been called for all screen.script instances
|
msg.post("#", "init_monarch") -- wait until init() has been called for all screen.script instances
|
||||||
end
|
end
|
||||||
|
@ -26,6 +26,12 @@ M.FOCUS.GAINED = hash("monarch_focus_gained")
|
|||||||
M.FOCUS.LOST = hash("monarch_focus_lost")
|
M.FOCUS.LOST = hash("monarch_focus_lost")
|
||||||
|
|
||||||
|
|
||||||
|
local function log(...) end
|
||||||
|
|
||||||
|
function M.debug()
|
||||||
|
log = print
|
||||||
|
end
|
||||||
|
|
||||||
local function screen_from_proxy(proxy)
|
local function screen_from_proxy(proxy)
|
||||||
for _, screen in pairs(screens) do
|
for _, screen in pairs(screens) do
|
||||||
if screen.proxy == proxy then
|
if screen.proxy == proxy then
|
||||||
@ -101,29 +107,85 @@ function M.unregister(id)
|
|||||||
screens[id] = nil
|
screens[id] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function acquire_input(screen)
|
||||||
|
log("change_context()", screen.id)
|
||||||
|
if not screen.input then
|
||||||
|
msg.post(screen.script, ACQUIRE_INPUT_FOCUS)
|
||||||
|
screen.input = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function release_input(screen)
|
||||||
|
log("change_context()", screen.id)
|
||||||
|
if screen.input then
|
||||||
|
msg.post(screen.script, RELEASE_INPUT_FOCUS)
|
||||||
|
screen.input = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function change_context(screen)
|
||||||
|
log("change_context()", screen.id)
|
||||||
|
screen.wait_for = CONTEXT
|
||||||
|
msg.post(screen.script, CONTEXT)
|
||||||
|
coroutine.yield()
|
||||||
|
screen.wait_for = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local function unload(screen)
|
||||||
|
log("unload()", screen.id)
|
||||||
|
screen.wait_for = PROXY_UNLOADED
|
||||||
|
msg.post(screen.proxy, UNLOAD)
|
||||||
|
coroutine.yield()
|
||||||
|
screen.loaded = false
|
||||||
|
screen.wait_for = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local function async_load(screen)
|
||||||
|
log("async_load()", screen.id)
|
||||||
|
screen.wait_for = PROXY_LOADED
|
||||||
|
msg.post(screen.proxy, ASYNC_LOAD)
|
||||||
|
coroutine.yield()
|
||||||
|
msg.post(screen.proxy, ENABLE)
|
||||||
|
screen.loaded = true
|
||||||
|
screen.wait_for = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local function transition(screen, message_id)
|
||||||
|
log("transition()", screen.id)
|
||||||
|
screen.wait_for = M.TRANSITION.DONE
|
||||||
|
msg.post(screen.transition_url, message_id)
|
||||||
|
coroutine.yield()
|
||||||
|
screen.wait_for = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local function focus_gained(screen, previous_screen)
|
||||||
|
log("focus_gained()", screen.id)
|
||||||
|
if screen.focus_url then
|
||||||
|
msg.post(screen.focus_url, M.FOCUS.GAINED, {id = previous_screen and previous_screen.id})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function focus_lost(screen, next_screen)
|
||||||
|
log("focus_lost()", screen.id)
|
||||||
|
if screen.focus_url then
|
||||||
|
msg.post(screen.focus_url, M.FOCUS.LOST, {id = next_screen and next_screen.id})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function show_out(screen, next_screen, cb)
|
local function show_out(screen, next_screen, cb)
|
||||||
local co
|
local co
|
||||||
co = coroutine.create(function()
|
co = coroutine.create(function()
|
||||||
screen.co = co
|
screen.co = co
|
||||||
msg.post(screen.script, RELEASE_INPUT_FOCUS)
|
change_context(screen)
|
||||||
screen.input = false
|
release_input(screen)
|
||||||
|
focus_lost(screen, next_screen)
|
||||||
if screen.focus_url then
|
|
||||||
msg.post(screen.focus_url, M.FOCUS.LOST, {id = next_screen.id})
|
|
||||||
end
|
|
||||||
|
|
||||||
msg.post(screen.script, CONTEXT)
|
|
||||||
coroutine.yield()
|
|
||||||
-- if the next screen is a popup we want the current screen to stay visible below the popup
|
-- if the next screen is a popup we want the current screen to stay visible below the popup
|
||||||
-- if the next screen isn't a popup the current one should be unloaded and transitioned out
|
-- if the next screen isn't a popup the current one should be unloaded and transitioned out
|
||||||
local next_is_popup = next_screen and not next_screen.popup
|
local next_is_popup = next_screen and not next_screen.popup
|
||||||
local current_is_popup = screen.popup
|
local current_is_popup = screen.popup
|
||||||
if (next_is_popup and not current_is_popup) or (current_is_popup) then
|
if (next_is_popup and not current_is_popup) or (current_is_popup) then
|
||||||
msg.post(screen.transition_url, M.TRANSITION.SHOW_OUT)
|
transition(screen, M.TRANSITION.SHOW_OUT)
|
||||||
coroutine.yield()
|
unload(screen)
|
||||||
msg.post(screen.proxy, UNLOAD)
|
|
||||||
coroutine.yield()
|
|
||||||
screen.loaded = false
|
|
||||||
end
|
end
|
||||||
screen.co = nil
|
screen.co = nil
|
||||||
if cb then cb() end
|
if cb then cb() end
|
||||||
@ -132,39 +194,25 @@ local function show_out(screen, next_screen, cb)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function show_in(screen, previous_screen, reload, cb)
|
local function show_in(screen, previous_screen, reload, cb)
|
||||||
|
log("show_in()", screen.id)
|
||||||
local co
|
local co
|
||||||
co = coroutine.create(function()
|
co = coroutine.create(function()
|
||||||
screen.co = co
|
screen.co = co
|
||||||
msg.post(screen.script, CONTEXT)
|
change_context(screen)
|
||||||
coroutine.yield()
|
|
||||||
|
|
||||||
if reload and screen.loaded then
|
if reload and screen.loaded then
|
||||||
msg.post(screen.proxy, UNLOAD)
|
log("show_in() reloading", screen.id)
|
||||||
coroutine.yield()
|
unload(screen)
|
||||||
screen.loaded = false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- the screen could be loaded if the previous screen was a popup
|
-- the screen could be loaded if the previous screen was a popup
|
||||||
-- and the popup asked to show this screen again
|
-- and the popup asked to show this screen again
|
||||||
-- in that case we shouldn't attempt to load it again
|
-- in that case we shouldn't attempt to load it again
|
||||||
if not screen.loaded then
|
if not screen.loaded then
|
||||||
msg.post(screen.proxy, ASYNC_LOAD)
|
async_load(screen)
|
||||||
coroutine.yield()
|
|
||||||
msg.post(screen.proxy, ENABLE)
|
|
||||||
screen.loaded = true
|
|
||||||
end
|
end
|
||||||
stack[#stack + 1] = screen
|
stack[#stack + 1] = screen
|
||||||
msg.post(screen.transition_url, M.TRANSITION.SHOW_IN)
|
transition(screen, M.TRANSITION.SHOW_IN)
|
||||||
coroutine.yield()
|
acquire_input(screen)
|
||||||
|
focus_gained(screen, previous_screen)
|
||||||
if not screen.input then
|
|
||||||
msg.post(screen.script, ACQUIRE_INPUT_FOCUS)
|
|
||||||
screen.input = true
|
|
||||||
end
|
|
||||||
|
|
||||||
if screen.focus_url then
|
|
||||||
msg.post(screen.focus_url, M.FOCUS.GAINED, {id = previous_screen and previous_screen.id})
|
|
||||||
end
|
|
||||||
screen.co = nil
|
screen.co = nil
|
||||||
if cb then cb() end
|
if cb then cb() end
|
||||||
end)
|
end)
|
||||||
@ -175,27 +223,15 @@ local function back_in(screen, previous_screen, cb)
|
|||||||
local co
|
local co
|
||||||
co = coroutine.create(function()
|
co = coroutine.create(function()
|
||||||
screen.co = co
|
screen.co = co
|
||||||
msg.post(screen.script, CONTEXT)
|
change_context(screen)
|
||||||
coroutine.yield()
|
|
||||||
if not screen.loaded then
|
if not screen.loaded then
|
||||||
msg.post(screen.proxy, ASYNC_LOAD)
|
async_load(screen)
|
||||||
coroutine.yield()
|
|
||||||
msg.post(screen.proxy, ENABLE)
|
|
||||||
screen.loaded = true
|
|
||||||
end
|
end
|
||||||
if previous_screen and not previous_screen.popup then
|
if previous_screen and not previous_screen.popup then
|
||||||
msg.post(screen.transition_url, M.TRANSITION.BACK_IN)
|
transition(screen, M.TRANSITION.BACK_IN)
|
||||||
coroutine.yield()
|
|
||||||
end
|
|
||||||
|
|
||||||
if not screen.input then
|
|
||||||
msg.post(screen.script, ACQUIRE_INPUT_FOCUS)
|
|
||||||
screen.input = true
|
|
||||||
end
|
|
||||||
|
|
||||||
if screen.focus_url then
|
|
||||||
msg.post(screen.focus_url, M.FOCUS.GAINED, {id = previous_screen.id})
|
|
||||||
end
|
end
|
||||||
|
acquire_input(screen)
|
||||||
|
focus_gained(screen, previous_screen)
|
||||||
screen.co = nil
|
screen.co = nil
|
||||||
if cb then cb() end
|
if cb then cb() end
|
||||||
end)
|
end)
|
||||||
@ -206,18 +242,11 @@ local function back_out(screen, next_screen, cb)
|
|||||||
local co
|
local co
|
||||||
co = coroutine.create(function()
|
co = coroutine.create(function()
|
||||||
screen.co = co
|
screen.co = co
|
||||||
msg.post(screen.script, RELEASE_INPUT_FOCUS)
|
change_context(screen)
|
||||||
screen.input = false
|
release_input(screen)
|
||||||
if screen.focus_url then
|
focus_lost(screen, next_screen)
|
||||||
msg.post(screen.focus_url, M.FOCUS.LOST, {id = next_screen and next_screen.id})
|
transition(screen, M.TRANSITION.BACK_OUT)
|
||||||
end
|
unload(screen)
|
||||||
msg.post(screen.script, CONTEXT)
|
|
||||||
coroutine.yield()
|
|
||||||
msg.post(screen.transition_url, M.TRANSITION.BACK_OUT)
|
|
||||||
coroutine.yield()
|
|
||||||
msg.post(screen.proxy, UNLOAD)
|
|
||||||
coroutine.yield()
|
|
||||||
screen.loaded = false
|
|
||||||
screen.co = nil
|
screen.co = nil
|
||||||
if cb then cb() end
|
if cb then cb() end
|
||||||
end)
|
end)
|
||||||
@ -256,6 +285,8 @@ function M.show(id, options, data, cb)
|
|||||||
local screen = screens[id]
|
local screen = screens[id]
|
||||||
screen.data = data
|
screen.data = data
|
||||||
|
|
||||||
|
log("show()", screen.id)
|
||||||
|
|
||||||
-- manipulate the current top
|
-- manipulate the current top
|
||||||
-- close popup if needed
|
-- close popup if needed
|
||||||
-- transition out
|
-- transition out
|
||||||
@ -279,6 +310,7 @@ function M.show(id, options, data, cb)
|
|||||||
-- to remove every screen on the stack up until and
|
-- to remove every screen on the stack up until and
|
||||||
-- including the screen itself
|
-- including the screen itself
|
||||||
if options and options.clear then
|
if options and options.clear then
|
||||||
|
log("show() clearing")
|
||||||
while M.in_stack(id) do
|
while M.in_stack(id) do
|
||||||
table.remove(stack)
|
table.remove(stack)
|
||||||
end
|
end
|
||||||
@ -295,6 +327,7 @@ end
|
|||||||
function M.back(data, cb)
|
function M.back(data, cb)
|
||||||
local screen = table.remove(stack)
|
local screen = table.remove(stack)
|
||||||
if screen then
|
if screen then
|
||||||
|
log("back()", screen.id)
|
||||||
local top = stack[#stack]
|
local top = stack[#stack]
|
||||||
-- if we go back to the same screen we need to first hide it
|
-- if we go back to the same screen we need to first hide it
|
||||||
-- and wait until it is hidden before we show it again
|
-- and wait until it is hidden before we show it again
|
||||||
@ -324,20 +357,28 @@ function M.on_message(message_id, message, sender)
|
|||||||
if message_id == PROXY_LOADED then
|
if message_id == PROXY_LOADED then
|
||||||
local screen = screen_from_proxy(sender)
|
local screen = screen_from_proxy(sender)
|
||||||
assert(screen, "Unable to find screen for loaded proxy")
|
assert(screen, "Unable to find screen for loaded proxy")
|
||||||
|
if screen.wait_for == PROXY_LOADED then
|
||||||
assert(coroutine.resume(screen.co))
|
assert(coroutine.resume(screen.co))
|
||||||
|
end
|
||||||
elseif message_id == PROXY_UNLOADED then
|
elseif message_id == PROXY_UNLOADED then
|
||||||
local screen = screen_from_proxy(sender)
|
local screen = screen_from_proxy(sender)
|
||||||
assert(screen, "Unable to find screen for unloaded proxy")
|
assert(screen, "Unable to find screen for unloaded proxy")
|
||||||
|
if screen.wait_for == PROXY_UNLOADED then
|
||||||
assert(coroutine.resume(screen.co))
|
assert(coroutine.resume(screen.co))
|
||||||
|
end
|
||||||
elseif message_id == CONTEXT then
|
elseif message_id == CONTEXT then
|
||||||
local screen = screen_from_script()
|
local screen = screen_from_script()
|
||||||
assert(screen, "Unable to find screen for current script url")
|
assert(screen, "Unable to find screen for current script url")
|
||||||
|
if screen.wait_for == CONTEXT then
|
||||||
assert(coroutine.resume(screen.co))
|
assert(coroutine.resume(screen.co))
|
||||||
|
end
|
||||||
elseif message_id == M.TRANSITION.DONE then
|
elseif message_id == M.TRANSITION.DONE then
|
||||||
local screen = screen_from_script()
|
local screen = screen_from_script()
|
||||||
assert(screen, "Unable to find screen for current script url")
|
assert(screen, "Unable to find screen for current script url")
|
||||||
|
if screen.wait_for == M.TRANSITION.DONE then
|
||||||
assert(coroutine.resume(screen.co))
|
assert(coroutine.resume(screen.co))
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Get a list of ids for the current screen stack
|
--- Get a list of ids for the current screen stack
|
||||||
|
Loading…
x
Reference in New Issue
Block a user