diff --git a/monarch/monarch.lua b/monarch/monarch.lua index 09c271d..e0dc9d0 100644 --- a/monarch/monarch.lua +++ b/monarch/monarch.lua @@ -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 - show_out(top, screen, callbacks.track()) + -- 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 diff --git a/monarch/utils/callback_tracker.lua b/monarch/utils/callback_tracker.lua index 6151340..0c32966 100644 --- a/monarch/utils/callback_tracker.lua +++ b/monarch/utils/callback_tracker.lua @@ -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 diff --git a/test/test_monarch.lua b/test/test_monarch.lua index 80e2828..195390e 100644 --- a/test/test_monarch.lua +++ b/test/test_monarch.lua @@ -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")