3
0
mirror of https://github.com/britzl/monarch.git synced 2025-06-27 10:27:49 +02:00

Transition out and in again if showing the same screen twice

Fixes #54
This commit is contained in:
Björn Ritzl 2019-09-14 01:23:14 +02:00
parent 8001d370c2
commit 81237762be
3 changed files with 33 additions and 17 deletions

View File

@ -677,16 +677,16 @@ function M.show(id, options, data, cb)
-- close all popups, one by one
while top.popup do
stack[#stack] = nil
show_out(top, screen, function()
assert(coroutine.resume(co))
end)
coroutine.yield()
show_out(top, screen, callbacks.track())
callbacks.yield_until_done()
top = stack[#stack]
end
-- unload and transition out from top
-- unless we're showing the same screen as is already visible
if top and top.id ~= screen.id then
-- wait until we are done if showing the same screen as is already visible
local same_screen = top and top.id == screen.id
show_out(top, screen, callbacks.track())
if same_screen and then
callbacks.yield_until_done()
end
end
end
@ -817,7 +817,13 @@ function M.is_preloading(id)
local screen = screens[id]
return screen.preloading
end
function M.is_preloaded(id)
assert(id, "You must provide a screen id")
id = tohash(id)
assert(screens[id], ("There is no screen registered with id %s"):format(tostring(id)))
local screen = screens[id]
return screen.preloaded
end
--- Invoke a callback when a specific screen has been preloaded
-- This is mainly useful on app start when wanting to show a screen that

View File

@ -7,6 +7,10 @@ function M.create()
local callback = nil
local callback_count = 0
local function is_done()
return callback_count == 0
end
local function invoke_if_done()
if callback_count == 0 and callback then
local ok, err = pcall(callback)
@ -37,6 +41,17 @@ function M.create()
invoke_if_done()
end
function instance.yield_until_done()
local co = coroutine.running()
callback = function()
coroutine.resume(co)
end
invoke_if_done()
if not is_done() then
coroutine.yield()
end
end
return instance
end

View File

@ -405,18 +405,13 @@ return function()
end)
it("should be able to preload a screen and always keep it loaded", function()
monarch.show(SCREEN_PRELOAD, nil, { count = 1 })
monarch.show(SCREEN_PRELOAD)
assert(wait_until_shown(SCREEN_PRELOAD), "Screen_preload was never shown")
-- first time the screen gets loaded it will increment the count
assert(monarch.data(SCREEN_PRELOAD).count == 2)
monarch.show(SCREEN_PRELOAD, { clear = true }, { count = 1 })
assert(wait_until_shown(SCREEN_PRELOAD), "Screen_preload was never shown")
-- second time the screen gets shown it will already be loaded and not increment the count
assert(monarch.data(SCREEN_PRELOAD).count == 1)
monarch.back()
assert(wait_until_hidden(SCREEN_PRELOAD), "Screen_preload was never hidden")
assert(monarch.is_preloaded(SCREEN_PRELOAD))
end)
it("should be able to reload a preloaded screen", function()
monarch.show(SCREEN_PRELOAD, nil, { count = 1 })
assert(wait_until_shown(SCREEN_PRELOAD), "Screen_preload was never shown")