diff --git a/README_API.md b/README_API.md index d0b2bdd..cfdf941 100644 --- a/README_API.md +++ b/README_API.md @@ -48,13 +48,18 @@ Go back to a previous Monarch screen. This operation will be added to the queue * `callback` (function) - Optional function to call when the previous screen is visible. -## monarch.preload(screen_id, [callback]) +## monarch.preload(screen_id, [options], [callback]) Preload a Monarch screen. This will load but not enable the screen. This is useful for content heavy screens that you wish to be able to show without having to wait for it load. This operation will be added to the queue if Monarch is busy. **PARAMETERS** * `screen_id` (string|hash) - Id of the screen to preload. +* `options` (table) * `callback` (function) - Optional function to call when the screen is preloaded. +The options table can contain the following fields: + +* `keep_loaded` (boolean) - If the `keep_loaded` flag is set Monarch will keep the screen preloaded even after a `hide()` or `back()` navigation event that normally would unload the screen. + ## monarch.is_preloading(screen_id) Check if a Monarch screen is preloading (via monarch.preload() or the Preload screen setting). diff --git a/monarch/monarch.lua b/monarch/monarch.lua index 808e11c..56b0921 100644 --- a/monarch/monarch.lua +++ b/monarch/monarch.lua @@ -996,12 +996,19 @@ end --- Preload a screen. This will load but not enable and show a screen. Useful for "heavier" screens -- that you wish to show without any delay. -- @param id (string|hash) - Id of the screen to preload +-- @param options (table) -- @param cb (function) - Optional callback to invoke when screen is loaded -function M.preload(id, cb) +function M.preload(id, options, cb) 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))) + -- support old function signature (id, cb) + if type(options) == "function" and not cb then + cb = options + options = nil + end + log("preload() queuing action", id) queue_action(function(action_done, action_error) log("preload()", id) @@ -1012,6 +1019,10 @@ function M.preload(id, cb) return end + -- keep_loaded is an option for monarch.preload() + -- use it to get the same behavior as the auto preload checkbox + screen.auto_preload = screen.auto_preload or options and options.keep_loaded + if screen.preloaded or screen.loaded then pcallfn(cb) pcallfn(action_done) diff --git a/test/test_monarch.lua b/test/test_monarch.lua index eaf4bc5..ebff0f1 100644 --- a/test/test_monarch.lua +++ b/test/test_monarch.lua @@ -377,7 +377,21 @@ return function() end) assert(not monarch.is_preloading(TRANSITION1)) end) - + + it("should be able to preload a screen and keep it loaded", function() + assert(not monarch.is_preloading(TRANSITION1)) + monarch.preload(TRANSITION1, { keep_loaded = true }) + wait_until_done(function(done) + monarch.when_preloaded(TRANSITION1, done) + end) + + monarch.show(TRANSITION1) + assert(wait_until_visible(TRANSITION1), "Transition1 was never shown") + monarch.back() + assert(wait_until_hidden(TRANSITION1), "Transition1 was never hidden") + assert(monarch.is_preloaded(TRANSITION1)) + end) + it("should ignore any preload calls while busy", function() monarch.show(TRANSITION1) -- previously a call to preload() while also showing a screen would