From 3443484ccec870fb32a77647e0d4ef05241fd1d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ritzl?= Date: Fri, 27 Jul 2018 13:28:36 +0200 Subject: [PATCH] Added support for collection factories --- README.md | 15 ++- example/example.collection | 42 ++++--- monarch/monarch.lua | 213 ++++++++++++++++++++++++---------- monarch/screen.script | 32 +++-- monarch/screen_factory.script | 39 +++++++ monarch/screen_proxy.script | 44 +++++++ test/data/screens.collection | 23 ++-- test/test_monarch.lua | 33 ++++-- 8 files changed, 322 insertions(+), 119 deletions(-) create mode 100644 monarch/screen_factory.script create mode 100644 monarch/screen_proxy.script diff --git a/README.md b/README.md index 50612d2..313f1b3 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,10 @@ Using Monarch requires that screens are created in a certain way. Once you have ## Creating screens -Monarch screens are created in individual collections and loaded through collection proxies. The recommended setup is to create one game object per screen and per game object attach a collection proxy component and an instance of the ```screen.script``` provided by Monarch. The ```screen.script``` will take care of the setup of the screen. All you need to do is to make sure that the script properties on the ```screen.script``` are correct: +Monarch screens are created in individual collections and either loaded through collection proxies or created through collection factories. + +### Collection proxies +For proxies the recommended setup is to create one game object per screen and per game object attach a collection proxy component and an instance of the ```screen_proxy.script``` provided by Monarch. The ```screen_proxy.script``` will take care of the setup of the screen. All you need to do is to make sure that the script properties on the script are correct: * **Screen Proxy (url)** - The URL to the collection proxy component containing the actual screen. Defaults to ```#collectionproxy```. * **Screen Id (hash)** - A unique id that can be used to reference the screen when navigating your app. @@ -32,6 +35,16 @@ Monarch screens are created in individual collections and loaded through collect ![](docs/setup.png) +### Collection factories +For factories the recommended setup is to create one game object per screen and per game object attach a collection factory component and an instance of the ```screen_factory.script``` provided by Monarch. The ```screen_factory.script``` will take care of the setup of the screen. All you need to do is to make sure that the script properties on the script are correct: + +* **Screen Factory (url)** - The URL to the collection factory component containing the actual screen. Defaults to ```#collectionfactory```. +* **Screen Id (hash)** - A unique id that can be used to reference the screen when navigating your app. +* **Popup (boolean)** - Check this if the screen should be treated as a [popup](#popups). +* **Popup on Popup (boolean)** - Check this if the screen is a [popup](#popups) and it can be shown on top of other popups. +* **Transition Id (url)** - Optional id of the game object to send a message to when the screen is about to be shown/hidden. Use this to trigger a transition (see the section on [transitions](#transitions)). +* **Focus Id (url)** - Optional id of the game object to send a message to when the screen gains or loses focus (see the section on [screen focus](#screen-focus-gainloss)). + ## Navigating between screens The navigation in Monarch is based around a stack of screens. When a screen is shown it is pushed to the top of the stack. When going back to a previous screen the topmost screen on the stack is removed. Example: diff --git a/example/example.collection b/example/example.collection index 40e5bdc..c8b4ff7 100644 --- a/example/example.collection +++ b/example/example.collection @@ -4,7 +4,7 @@ embedded_instances { id: "menu" data: "components {\n" " id: \"screen\"\n" - " component: \"/monarch/screen.script\"\n" + " component: \"/monarch/screen_proxy.script\"\n" " position {\n" " x: 0.0\n" " y: 0.0\n" @@ -127,7 +127,7 @@ embedded_instances { id: "pregame" data: "components {\n" " id: \"screen\"\n" - " component: \"/monarch/screen.script\"\n" + " component: \"/monarch/screen_proxy.script\"\n" " position {\n" " x: 0.0\n" " y: 0.0\n" @@ -190,7 +190,7 @@ embedded_instances { id: "game" data: "components {\n" " id: \"screen\"\n" - " component: \"/monarch/screen.script\"\n" + " component: \"/monarch/screen_proxy.script\"\n" " position {\n" " x: 0.0\n" " y: 0.0\n" @@ -253,7 +253,7 @@ embedded_instances { id: "popup" data: "components {\n" " id: \"screen\"\n" - " component: \"/monarch/screen.script\"\n" + " component: \"/monarch/screen_factory.script\"\n" " position {\n" " x: 0.0\n" " y: 0.0\n" @@ -276,21 +276,26 @@ embedded_instances { " type: PROPERTY_TYPE_BOOLEAN\n" " }\n" " properties {\n" - " id: \"timestep_below_popup\"\n" - " value: \"0.0\"\n" - " type: PROPERTY_TYPE_NUMBER\n" + " id: \"popup_on_popup\"\n" + " value: \"true\"\n" + " type: PROPERTY_TYPE_BOOLEAN\n" " }\n" " properties {\n" - " id: \"transition_url\"\n" - " value: \"popup:/go#popup\"\n" - " type: PROPERTY_TYPE_URL\n" + " id: \"transition_id\"\n" + " value: \"/go\"\n" + " type: PROPERTY_TYPE_HASH\n" + " }\n" + " properties {\n" + " id: \"focus_id\"\n" + " value: \"/go\"\n" + " type: PROPERTY_TYPE_HASH\n" " }\n" "}\n" "embedded_components {\n" - " id: \"collectionproxy\"\n" - " type: \"collectionproxy\"\n" - " data: \"collection: \\\"/example/popup.collection\\\"\\n" - "exclude: false\\n" + " id: \"collectionfactory\"\n" + " type: \"collectionfactory\"\n" + " data: \"prototype: \\\"/example/popup.collection\\\"\\n" + "load_dynamically: false\\n" "\"\n" " position {\n" " x: 0.0\n" @@ -326,7 +331,7 @@ embedded_instances { id: "about" data: "components {\n" " id: \"screen\"\n" - " component: \"/monarch/screen.script\"\n" + " component: \"/monarch/screen_proxy.script\"\n" " position {\n" " x: 0.0\n" " y: 0.0\n" @@ -349,6 +354,11 @@ embedded_instances { " type: PROPERTY_TYPE_BOOLEAN\n" " }\n" " properties {\n" + " id: \"popup_on_popup\"\n" + " value: \"true\"\n" + " type: PROPERTY_TYPE_BOOLEAN\n" + " }\n" + " properties {\n" " id: \"transition_url\"\n" " value: \"about:/go#about\"\n" " type: PROPERTY_TYPE_URL\n" @@ -394,7 +404,7 @@ embedded_instances { id: "confirm" data: "components {\n" " id: \"screen\"\n" - " component: \"/monarch/screen.script\"\n" + " component: \"/monarch/screen_proxy.script\"\n" " position {\n" " x: 0.0\n" " y: 0.0\n" diff --git a/monarch/monarch.lua b/monarch/monarch.lua index 5bff26f..4642934 100644 --- a/monarch/monarch.lua +++ b/monarch/monarch.lua @@ -112,9 +112,23 @@ function M.is_top(id) end ---- Register a new screen --- This is done automatically by the screen.script. It is expected that the --- caller of this function is a script component attached to the same game +local function register(id, settings) + assert(id, "You must provide a screen id") + id = tohash(id) + assert(not screens[id], ("There is already a screen registered with id %s"):format(tostring(id))) + screens[id] = { + id = id, + script = msg.url(), + popup = settings and settings.popup, + popup_on_popup = settings and settings.popup_on_popup, + timestep_below_popup = settings and settings.timestep_below_popup or 1, + } + return screens[id] +end + +--- Register a new screen contained in a collection proxy +-- This is done automatically by the screen_proxy.script. It is expected that +-- the caller of this function is a script component attached to the same game -- object as the proxy. This is required since monarch will acquire and -- release input focus of the game object where the proxy is attached. -- @param id Unique id of the screen @@ -128,22 +142,37 @@ end -- * focus_url - URL to a script that is to be notified of focus -- lost/gained events -- * timestep_below_popup - Timestep to set on proxy when below a popup -function M.register(id, proxy, settings) - assert(id, "You must provide a screen id") - id = tohash(id) - assert(not screens[id], ("There is already a screen registered with id %s"):format(tostring(id))) +function M.register_proxy(id, proxy, settings) assert(proxy, "You must provide a collection proxy URL") - local url = msg.url(proxy) - screens[id] = { - id = id, - proxy = proxy, - script = msg.url(), - popup = settings and settings.popup, - popup_on_popup = settings and settings.popup_on_popup, - transition_url = settings and settings.transition_url, - focus_url = settings and settings.focus_url, - timestep_below_popup = settings and settings.timestep_below_popup or 1, - } + local screen = register(id, settings) + screen.proxy = proxy + screen.transition_url = settings and settings.transition_url + screen.focus_url = settings and settings.focus_url +end +M.register = M.register_proxy + + +--- Register a new screen contained in a collection factory +-- This is done automatically by the screen_factory.script. It is expected that +-- the caller of this function is a script component attached to the same game +-- object as the factory. This is required since monarch will acquire and +-- release input focus of the game object where the factory is attached. +-- @param id Unique id of the screen +-- @param factory URL to the collection factory containing the screen +-- @param settings Settings table for screen. Accepted values: +-- * popup - true the screen is a popup +-- * popup_on_popup - true if this popup can be shown on top of +-- another popup or false if an underlying popup should be closed +-- * transition_id - Id of the game object in the collection that is responsible +-- for the screen transitions +-- * focus_id - Id of the game object in the collection that is to be notified +-- of focus lost/gained events +function M.register_factory(id, factory, settings) + assert(factory, "You must provide a collection factory URL") + local screen = register(id, settings) + screen.factory = factory + screen.transition_id = settings and settings.transition_id + screen.focus_id = settings and settings.focus_id end --- Unregister a screen @@ -159,7 +188,13 @@ end local function acquire_input(screen) log("change_context()", screen.id) if not screen.input then - msg.post(screen.script, ACQUIRE_INPUT_FOCUS) + if screen.proxy then + msg.post(screen.script, ACQUIRE_INPUT_FOCUS) + elseif screen.factory then + for id,instance in pairs(screen.factory_ids) do + msg.post(instance, ACQUIRE_INPUT_FOCUS) + end + end screen.input = true end end @@ -167,7 +202,13 @@ end local function release_input(screen) log("change_context()", screen.id) if screen.input then - msg.post(screen.script, RELEASE_INPUT_FOCUS) + if screen.proxy then + msg.post(screen.script, RELEASE_INPUT_FOCUS) + elseif screen.factory then + for id,instance in pairs(screen.factory_ids) do + msg.post(instance, RELEASE_INPUT_FOCUS) + end + end screen.input = false end end @@ -182,50 +223,98 @@ 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 + + if screen.proxy then + screen.wait_for = PROXY_UNLOADED + msg.post(screen.proxy, UNLOAD) + coroutine.yield() + screen.loaded = false + screen.wait_for = nil + elseif screen.factory then + for id, instance in pairs(screen.factory_ids) do + go.delete(instance) + end + screen.factory_ids = nil + collectionfactory.unload(screen.factory) + screen.loaded = false + end end -local function async_load(screen) - log("async_load()", screen.id) - -- if the screen has been preloaded we need to enable it +local function preload(screen) + log("preload() preloading screen", screen.id) + assert(screen.co, "You must assign a coroutine to the screen") + if screen.preloaded then - log("show_in() screen was preloaded", screen.id) - msg.post(screen.proxy, ENABLE) - screen.loaded = true - screen.preloaded = false - -- the screen could be loaded if the previous screen was a popup - -- and the popup asked to show this screen again - -- in that case we shouldn't attempt to load it again - elseif not screen.loaded then - log("show_in() loading screen", screen.id) + log("preload() screen already preloaded", screen.id) + return + end + + if screen.proxy then 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 - else - log("show_in() screen already loaded", screen.id) + elseif screen.factory then + if collectionfactory.get_status(screen.factory) == collectionfactory.STATUS_UNLOADED then + collectionfactory.load(screen.factory, function(self, url, result) + assert(coroutine.resume(screen.co)) + end) + coroutine.yield() + end + + if collectionfactory.get_status(screen.factory) ~= collectionfactory.STATUS_LOADED then + log("preload() error loading factory resources") + return + end end + screen.preloaded = true +end + +local function load(screen) + log("load()", screen.id) + assert(screen.co, "You must assign a coroutine to the screen") + + if screen.loaded then + log("load() screen already loaded", screen.id) + return + end + + preload(screen) + + if not screen.preloaded then + log("load() screen wasn't preloaded", screen.id) + return + end + + if screen.proxy then + msg.post(screen.proxy, ENABLE) + elseif screen.factory then + screen.factory_ids = collectionfactory.create(screen.factory) + screen.transition_url = screen.factory_ids[screen.transition_id] + screen.focus_url = screen.factory_ids[screen.focus_id] + end + screen.loaded = true + screen.preloaded = false end local function transition(screen, message_id, message) log("transition()", screen.id) - screen.wait_for = M.TRANSITION.DONE - msg.post(screen.transition_url, message_id, message) - coroutine.yield() - screen.wait_for = nil + if screen.transition_url then + screen.wait_for = M.TRANSITION.DONE + msg.post(screen.transition_url, message_id, message) + coroutine.yield() + screen.wait_for = nil + else + log("transition() no transition url - ignoring") + end 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 }) + else + log("focus_gained() no focus url - ignoring") end end @@ -233,16 +322,20 @@ 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 }) + else + log("focus_lost() no focus url - ignoring") end end local function change_timestep(screen) - screen.changed_timestep = true - msg.post(screen.proxy, "set_time_step", { mode = 0, factor = screen.timestep_below_popup }) + if screen.proxy then + screen.changed_timestep = true + msg.post(screen.proxy, "set_time_step", { mode = 0, factor = screen.timestep_below_popup }) + end end local function reset_timestep(screen) - if screen.changed_timestep then + if screen.proxy and screen.changed_timestep then msg.post(screen.proxy, "set_time_step", { mode = 0, factor = 1 }) screen.changed_timestep = false end @@ -264,7 +357,7 @@ local function disable(screen, next_screen) screen.co = nil if cb then cb() end end) - coroutine.resume(co) + assert(coroutine.resume(co)) end local function enable(screen, previous_screen) @@ -279,7 +372,7 @@ local function enable(screen, previous_screen) screen.co = nil if cb then cb() end end) - coroutine.resume(co) + assert(coroutine.resume(co)) end local function show_out(screen, next_screen, cb) @@ -323,7 +416,7 @@ local function show_in(screen, previous_screen, reload, cb) log("show_in() reloading", screen.id) unload(screen) end - async_load(screen) + load(screen) stack[#stack + 1] = screen reset_timestep(screen) transition(screen, M.TRANSITION.SHOW_IN, { previous_screen = previous_screen and previous_screen.id }) @@ -345,7 +438,7 @@ local function back_in(screen, previous_screen, cb) notify_listeners(M.SCREEN_TRANSITION_IN_STARTED, { screen = screen.id, previous_screen = previous_screen and previous_screen.id }) screen.co = co change_context(screen) - async_load(screen) + load(screen) reset_timestep(screen) if previous_screen and not previous_screen.popup then transition(screen, M.TRANSITION.BACK_IN, { previous_screen = previous_screen.id }) @@ -364,7 +457,7 @@ local function back_out(screen, next_screen, cb) log("back_out()", screen.id) local co co = coroutine.create(function() - notify_listeners(M.SCREEN_TRANSITION_OUT_STARTED, { screen = screen.id, next_screen = next_screen.id }) + notify_listeners(M.SCREEN_TRANSITION_OUT_STARTED, { screen = screen.id, next_screen = next_screen and next_screen.id }) active_transition_count = active_transition_count + 1 screen.co = co change_context(screen) @@ -378,7 +471,7 @@ local function back_out(screen, next_screen, cb) screen.co = nil active_transition_count = active_transition_count - 1 if cb then cb() end - notify_listeners(M.SCREEN_TRANSITION_OUT_FINISHED, { screen = screen.id, next_screen = next_screen.id }) + notify_listeners(M.SCREEN_TRANSITION_OUT_FINISHED, { screen = screen.id, next_screen = next_screen and next_screen.id }) end) coroutine.resume(co) end @@ -522,6 +615,7 @@ function M.back(data, cb) return true 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 @@ -532,6 +626,7 @@ function M.preload(id, cb) assert(screens[id], ("There is no screen registered with id %s"):format(tostring(id))) local screen = screens[id] + log("preload()", screen.id) if screen.preloaded or screen.loaded then if cb then cb() end return @@ -540,14 +635,10 @@ function M.preload(id, cb) co = coroutine.create(function() screen.co = co change_context(screen) - screen.wait_for = PROXY_LOADED - msg.post(screen.proxy, ASYNC_LOAD) - coroutine.yield() - screen.preloaded = true - screen.wait_for = nil + preload(screen) if cb then cb() end end) - coroutine.resume(co) + assert(coroutine.resume(co)) end diff --git a/monarch/screen.script b/monarch/screen.script index f183b12..5dbbc84 100644 --- a/monarch/screen.script +++ b/monarch/screen.script @@ -1,7 +1,7 @@ local monarch go.property("screen_proxy", msg.url("#collectionproxy")) -go.property("screen_id", hash("")) +go.property("screen_id", hash("UNIQUE ID HERE")) go.property("popup", false) go.property("popup_on_popup", false) go.property("timestep_below_popup", 1) @@ -10,19 +10,22 @@ go.property("focus_url", msg.url()) function init(self) + print("WARNING - screen.script is deprecated. Please use screen_proxy.script") monarch = require "monarch.monarch" + local url = msg.url() assert(not self.popup_on_popup or (self.popup_on_popup and self.popup), "Popup on Popups can only be set if the Popup flag is set") - monarch.register( - self.screen_id, - self.screen_proxy, - { - popup = self.popup, - popup_on_popup = self.popup_on_popup, - transition_url = self.transition_url, - focus_url = self.focus_url, - timestep_below_popup = self.timestep_below_popup, - } - ) + assert(self.screen_proxy ~= url, "You must specify either a proxy URL") + assert(self.timestep_below_popup >= 0, "Timestep must be positive") + + local settings = { + popup = self.popup, + popup_on_popup = self.popup_on_popup, + transition_url = self.transition_url ~= url and self.transition_url or nil, + focus_url = self.focus_url ~= url and self.focus_url or nil, + timestep_below_popup = self.timestep_below_popup, + } + + monarch.register_proxy(self.screen_id, self.screen_proxy, settings) end function final(self) @@ -36,11 +39,6 @@ function on_message(self, message_id, message, sender) monarch.back() elseif message_id == hash("back") then monarch.back() - elseif message_id == monarch.TRANSITION.SHOW_IN - or message_id == monarch.TRANSITION.SHOW_OUT - or message_id == monarch.TRANSITION.BACK_IN - or message_id == monarch.TRANSITION.BACK_OUT then - msg.post(sender, monarch.TRANSITION.DONE) else monarch.on_message(message_id, message, sender) end diff --git a/monarch/screen_factory.script b/monarch/screen_factory.script new file mode 100644 index 0000000..4c00e25 --- /dev/null +++ b/monarch/screen_factory.script @@ -0,0 +1,39 @@ +local monarch + +go.property("screen_factory", msg.url("#collectionfactory")) +go.property("screen_id", hash("UNIQUE ID HERE")) +go.property("popup", false) +go.property("popup_on_popup", false) +go.property("transition_id", hash("")) +go.property("focus_id", hash("")) + + +function init(self) + monarch = require "monarch.monarch" + assert(not self.popup_on_popup or (self.popup_on_popup and self.popup), "Popup on Popups can only be set if the Popup flag is set") + assert(self.screen_factory ~= msg.url(), "You must specify either a factory URL") + + local settings = { + popup = self.popup, + popup_on_popup = self.popup_on_popup, + transition_id = self.transition_id, + focus_id = self.focus_id, + } + monarch.register_factory(self.screen_id, self.screen_factory, settings) +end + +function final(self) + monarch.unregister(self.screen_id) +end + +function on_message(self, message_id, message, sender) + if message_id == hash("show") then + monarch.show(self.screen_id, { clear = message.clear }) + elseif message_id == hash("hide") then + monarch.back() + elseif message_id == hash("back") then + monarch.back() + else + monarch.on_message(message_id, message, sender) + end +end diff --git a/monarch/screen_proxy.script b/monarch/screen_proxy.script new file mode 100644 index 0000000..1fc5191 --- /dev/null +++ b/monarch/screen_proxy.script @@ -0,0 +1,44 @@ +local monarch + +go.property("screen_proxy", msg.url("#collectionproxy")) +go.property("screen_id", hash("UNIQUE ID HERE")) +go.property("popup", false) +go.property("popup_on_popup", false) +go.property("timestep_below_popup", 1) +go.property("transition_url", msg.url()) +go.property("focus_url", msg.url()) + + +function init(self) + monarch = require "monarch.monarch" + local url = msg.url() + assert(not self.popup_on_popup or (self.popup_on_popup and self.popup), "Popup on Popups can only be set if the Popup flag is set") + assert(self.screen_proxy ~= url, "You must specify either a proxy URL") + assert(self.timestep_below_popup >= 0, "Timestep must be positive") + + local settings = { + popup = self.popup, + popup_on_popup = self.popup_on_popup, + transition_url = self.transition_url ~= url and self.transition_url or nil, + focus_url = self.focus_url ~= url and self.focus_url or nil, + timestep_below_popup = self.timestep_below_popup, + } + + monarch.register_proxy(self.screen_id, self.screen_proxy, settings) +end + +function final(self) + monarch.unregister(self.screen_id) +end + +function on_message(self, message_id, message, sender) + if message_id == hash("show") then + monarch.show(self.screen_id, { clear = message.clear }) + elseif message_id == hash("hide") then + monarch.back() + elseif message_id == hash("back") then + monarch.back() + else + monarch.on_message(message_id, message, sender) + end +end diff --git a/test/data/screens.collection b/test/data/screens.collection index 593f919..666cd13 100644 --- a/test/data/screens.collection +++ b/test/data/screens.collection @@ -4,7 +4,7 @@ embedded_instances { id: "screen1" data: "components {\n" " id: \"screen\"\n" - " component: \"/monarch/screen.script\"\n" + " component: \"/monarch/screen_proxy.script\"\n" " position {\n" " x: 0.0\n" " y: 0.0\n" @@ -62,7 +62,7 @@ embedded_instances { id: "screen2" data: "components {\n" " id: \"screen\"\n" - " component: \"/monarch/screen.script\"\n" + " component: \"/monarch/screen_factory.script\"\n" " position {\n" " x: 0.0\n" " y: 0.0\n" @@ -81,10 +81,10 @@ embedded_instances { " }\n" "}\n" "embedded_components {\n" - " id: \"collectionproxy\"\n" - " type: \"collectionproxy\"\n" - " data: \"collection: \\\"/test/data/screen2.collection\\\"\\n" - "exclude: false\\n" + " id: \"collectionfactory\"\n" + " type: \"collectionfactory\"\n" + " data: \"prototype: \\\"/test/data/screen2.collection\\\"\\n" + "load_dynamically: false\\n" "\"\n" " position {\n" " x: 0.0\n" @@ -120,7 +120,7 @@ embedded_instances { id: "popup1" data: "components {\n" " id: \"screen\"\n" - " component: \"/monarch/screen.script\"\n" + " component: \"/monarch/screen_proxy.script\"\n" " position {\n" " x: 0.0\n" " y: 0.0\n" @@ -142,11 +142,6 @@ embedded_instances { " value: \"true\"\n" " type: PROPERTY_TYPE_BOOLEAN\n" " }\n" - " properties {\n" - " id: \"popup_on_popup\"\n" - " value: \"false\"\n" - " type: PROPERTY_TYPE_BOOLEAN\n" - " }\n" "}\n" "embedded_components {\n" " id: \"collectionproxy\"\n" @@ -188,7 +183,7 @@ embedded_instances { id: "popup2" data: "components {\n" " id: \"screen\"\n" - " component: \"/monarch/screen.script\"\n" + " component: \"/monarch/screen_proxy.script\"\n" " position {\n" " x: 0.0\n" " y: 0.0\n" @@ -256,7 +251,7 @@ embedded_instances { id: "transition1" data: "components {\n" " id: \"screen\"\n" - " component: \"/monarch/screen.script\"\n" + " component: \"/monarch/screen_proxy.script\"\n" " position {\n" " x: 0.0\n" " y: 0.0\n" diff --git a/test/test_monarch.lua b/test/test_monarch.lua index 3951b77..3a04f47 100644 --- a/test/test_monarch.lua +++ b/test/test_monarch.lua @@ -63,6 +63,10 @@ return function() end) after(function() + while #monarch.get_stack() > 0 do + monarch.back() + wait_until_not_busy() + end mock_msg.unmock() unload.unload("monarch%..*") for id,instance_id in pairs(screens_instances) do @@ -254,22 +258,31 @@ return function() monarch.remove_listener(URL2) monarch.show(SCREEN2) assert(wait_until_not_busy()) - - monarch.back() - assert(wait_until_not_busy()) - - local messages_1 = mock_msg.messages(URL1) - local messages_2 = mock_msg.messages(URL2) - assert(#mock_msg.messages(URL1) == 10) + + assert(#mock_msg.messages(URL1) == 6) assert(#mock_msg.messages(URL2) == 2) assert(mock_msg.messages(URL1)[3].message_id == monarch.SCREEN_TRANSITION_OUT_STARTED) assert(mock_msg.messages(URL1)[3].message.screen == SCREEN1) assert(mock_msg.messages(URL1)[4].message_id == monarch.SCREEN_TRANSITION_IN_STARTED) assert(mock_msg.messages(URL1)[4].message.screen == SCREEN2) - assert(mock_msg.messages(URL1)[5].message_id == monarch.SCREEN_TRANSITION_OUT_FINISHED) - assert(mock_msg.messages(URL1)[5].message.screen == SCREEN1) - assert(mock_msg.messages(URL1)[6].message_id == monarch.SCREEN_TRANSITION_IN_FINISHED) + assert(mock_msg.messages(URL1)[5].message_id == monarch.SCREEN_TRANSITION_IN_FINISHED) + assert(mock_msg.messages(URL1)[5].message.screen == SCREEN2) + assert(mock_msg.messages(URL1)[6].message_id == monarch.SCREEN_TRANSITION_OUT_FINISHED) + assert(mock_msg.messages(URL1)[6].message.screen == SCREEN1) + + monarch.back() + assert(wait_until_not_busy()) + + assert(#mock_msg.messages(URL1) == 10) + assert(#mock_msg.messages(URL2) == 2) + assert(mock_msg.messages(URL1)[7].message_id == monarch.SCREEN_TRANSITION_OUT_STARTED) assert(mock_msg.messages(URL1)[7].message.screen == SCREEN2) + assert(mock_msg.messages(URL1)[8].message_id == monarch.SCREEN_TRANSITION_IN_STARTED) + assert(mock_msg.messages(URL1)[8].message.screen == SCREEN1) + assert(mock_msg.messages(URL1)[9].message_id == monarch.SCREEN_TRANSITION_OUT_FINISHED) + assert(mock_msg.messages(URL1)[9].message.screen == SCREEN2) + assert(mock_msg.messages(URL1)[10].message_id == monarch.SCREEN_TRANSITION_IN_FINISHED) + assert(mock_msg.messages(URL1)[10].message.screen == SCREEN1) end) end) end