3
0
mirror of https://github.com/britzl/monarch.git synced 2025-11-26 19:00:53 +01:00

Compare commits

...

13 Commits
4.0.1 ... 4.4.1

Author SHA1 Message Date
Björn Ritzl
b7053d2ce4 Fixed another back issue (and tests) 2023-08-10 00:21:15 +02:00
Björn Ritzl
91204ca30b Wait for both in and out transitions (#97) 2023-08-10 00:08:10 +02:00
Björn Ritzl
6f79bd0326 Swap transition count and listener order 2023-08-08 23:51:48 +02:00
Björn Ritzl
e5214edb22 Fix back() callback 2023-08-08 23:51:29 +02:00
Björn Ritzl
1d4e48c0de Update test_monarch.lua 2023-08-08 22:55:29 +02:00
Björn Ritzl
5bdc3e4540 Added option table to back() 2023-08-08 22:53:00 +02:00
Björn Ritzl
85123c84e9 Show how to use monarch listeners 2023-08-08 22:49:58 +02:00
Björn Ritzl
a605f4f6f8 Fixed tests 2023-08-03 10:42:06 +02:00
Björn Ritzl
5d8fa8e220 monarch.post() requires monarch.on_post() 2023-08-03 08:35:04 +02:00
Björn Ritzl
df2a2a62ea Improved screen proxy url detection 2023-08-03 08:34:26 +02:00
Björn Ritzl
4e13660d63 Use new on_transition() 2023-08-02 07:47:47 +02:00
Björn Ritzl
0191a4e540 Set focus, transition and receiver as deprecated 2023-08-02 07:47:32 +02:00
Björn Ritzl
c601174b9d Improved handling of unregistered screens (#93)
* Set cowait flag

* Set screen as unregistered

* Do not process screen which have been unregistered

* Java 17
2023-07-29 11:28:18 +02:00
20 changed files with 180 additions and 133 deletions

View File

@@ -10,7 +10,7 @@ jobs:
- uses: actions/checkout@v1
- uses: actions/setup-java@v1
with:
java-version: '11'
java-version: '17'
- name: Run.sh
env:
DEFOLD_USER: bjorn.ritzl@gmail.com

View File

@@ -40,13 +40,18 @@ Clear the stack of screens completely. Any visible screen will be hidden by navi
* `callback` (function) - Optional function to call when the stack has been cleared.
## monarch.back([data], [callback])
## monarch.back([options], [data], [callback])
Go back to a previous Monarch screen. This operation will be added to the queue if Monarch is busy.
**PARAMETERS**
* `options` (table) - Options when showing the new screen (see below).
* `data` (table) - Optional data to associate with the screen you are going back to. Retrieve using `monarch.data()`.
* `callback` (function) - Optional function to call when the previous screen is visible.
The options table can contain the following fields:
* `sequential` (boolean) - If the `sequential` flag is set Monarch will start loading the screen only after the previous screen finished transitioning out.
## 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.
@@ -177,7 +182,7 @@ Remove a previously added listener.
## monarch.post(screen_id, message_id, [message])
Post a message to a visible screen. If the screen is created through a collection proxy it must have specified a receiver url. If the screen is created through a collection factory the function will post the message to all game objects within the collection.
Post a message to a visible screen. The screen must have set a message listener using `monarch.on_post()`.
**PARAMETERS**
* `screen_id` (string|hash) - Id of the screen to post message to

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 92 KiB

View File

@@ -5,11 +5,13 @@ function init(self)
msg.post(".", "acquire_input_focus")
gui.set_render_order(15)
self.transition = transitions.create(gui.get_node("root"))
local transition = transitions.create(gui.get_node("root"))
.show_in(transitions.slide_in_top, gui.EASING_OUTQUAD, 0.6, 0)
.show_out(transitions.slide_out_top, gui.EASING_INQUAD, 0.6, 0)
.back_in(transitions.slide_in_top, gui.EASING_OUTQUAD, 0.6, 0)
.back_out(transitions.slide_out_top, gui.EASING_INQUAD, 0.6, 0)
monarch.on_transition("about", transition)
end
function on_input(self, action_id, action)
@@ -27,5 +29,5 @@ function on_input(self, action_id, action)
end
function on_message(self, message_id, message, sender)
self.transition.handle(message_id, message, sender)
monarch.on_message(message_id, message, sender)
end

View File

@@ -21,16 +21,6 @@ embedded_instances {
" value: \"menu\"\n"
" type: PROPERTY_TYPE_HASH\n"
" }\n"
" properties {\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"
" property_decls {\n"
" }\n"
"}\n"
@@ -146,11 +136,6 @@ embedded_instances {
" value: \"pregame\"\n"
" type: PROPERTY_TYPE_HASH\n"
" }\n"
" properties {\n"
" id: \"transition_url\"\n"
" value: \"pregame:/go#pregame\"\n"
" type: PROPERTY_TYPE_URL\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
@@ -211,11 +196,6 @@ embedded_instances {
" value: \"game\"\n"
" type: PROPERTY_TYPE_HASH\n"
" }\n"
" properties {\n"
" id: \"transition_url\"\n"
" value: \"game:/go#game\"\n"
" type: PROPERTY_TYPE_URL\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
@@ -287,16 +267,6 @@ embedded_instances {
" type: PROPERTY_TYPE_BOOLEAN\n"
" }\n"
" properties {\n"
" id: \"transition_url\"\n"
" value: \"about:/go#about\"\n"
" type: PROPERTY_TYPE_URL\n"
" }\n"
" properties {\n"
" id: \"focus_url\"\n"
" value: \"about:/go#about\"\n"
" type: PROPERTY_TYPE_URL\n"
" }\n"
" properties {\n"
" id: \"preload\"\n"
" value: \"true\"\n"
" type: PROPERTY_TYPE_BOOLEAN\n"
@@ -376,11 +346,6 @@ embedded_instances {
" value: \"true\"\n"
" type: PROPERTY_TYPE_BOOLEAN\n"
" }\n"
" properties {\n"
" id: \"transition_url\"\n"
" value: \"confirm:/go#confirm\"\n"
" type: PROPERTY_TYPE_URL\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"

View File

@@ -7,11 +7,13 @@ function init(self)
self.no = gui.get_node("no_button")
gui.set_render_order(15)
self.transition = transitions.create(gui.get_node("root"))
local transition = transitions.create(gui.get_node("root"))
.show_in(transitions.scale_in, gui.EASING_OUTBACK, 0.3, 0)
.show_out(transitions.scale_out, gui.EASING_INBACK, 0.3, 0)
.back_in(transitions.scale_in, gui.EASING_OUTBACK, 0.3, 0)
.back_out(transitions.scale_out, gui.EASING_INBACK, 0.3, 0)
monarch.on_transition("confirm", transition)
end
function on_input(self, action_id, action)
@@ -35,5 +37,5 @@ function on_input(self, action_id, action)
end
function on_message(self, message_id, message, sender)
self.transition.handle(message_id, message, sender)
monarch.on_message(message_id, message, sender)
end

View File

@@ -7,7 +7,8 @@ function init(self)
local data = monarch.data(hash("game"))
gui.set_text(gui.get_node("level"), tostring(data.level))
self.transition = transitions.in_right_out_left(gui.get_node("root"), 0.6, 0)
local transition = transitions.in_right_out_left(gui.get_node("root"), 0.6, 0)
monarch.on_transition("game", transition)
end
function on_input(self, action_id, action)
@@ -21,5 +22,5 @@ function on_input(self, action_id, action)
end
function on_message(self, message_id, message, sender)
self.transition.handle(message_id, message, sender)
monarch.on_message(message_id, message, sender)
end

View File

@@ -8,7 +8,8 @@ function init(self)
gui.animate(gui.get_node("spinner"), gui.PROP_ROTATION, vmath.vector3(0, 0, -360), gui.EASING_INOUTQUAD, 2, 0, nil, gui.PLAYBACK_LOOP_FORWARD)
self.transition = transitions.fade_in_out(gui.get_node("root"), 0.6, 0)
local transition = transitions.fade_in_out(gui.get_node("root"), 0.6, 0)
monarch.on_transition("menu", transition)
end
function on_input(self, action_id, action)
@@ -28,7 +29,7 @@ function on_input(self, action_id, action)
end
function on_message(self, message_id, message, sender)
self.transition.handle(message_id, message, sender)
monarch.on_message(message_id, message, sender)
if message_id == monarch.FOCUS.GAINED then
gui.set_text(gui.get_node("timestamp"), os.date())
end

View File

@@ -10,11 +10,12 @@ function init(self)
gui.animate(gui.get_node("spinner"), gui.PROP_ROTATION, vmath.vector3(0, 0, -360), gui.EASING_INOUTQUAD, 2, 0, nil, gui.PLAYBACK_LOOP_FORWARD)
self.transition = transitions.create(gui.get_node("root"))
local transition = transitions.create(gui.get_node("root"))
.show_in(transitions.scale_in, gui.EASING_OUTBACK, 0.3, 0)
.show_out(transitions.scale_out, gui.EASING_INBACK, 0.3, 0)
.back_in(transitions.scale_in, gui.EASING_OUTBACK, 0.3, 0)
.back_out(transitions.scale_out, gui.EASING_INBACK, 0.3, 0)
monarch.on_transition("popup", transition)
end
function on_input(self, action_id, action)
@@ -39,5 +40,5 @@ function on_input(self, action_id, action)
end
function on_message(self, message_id, message, sender)
self.transition.handle(message_id, message, sender)
monarch.on_message(message_id, message, sender)
end

View File

@@ -6,7 +6,8 @@ function init(self)
self.play = gui.get_node("play_button")
self.back = gui.get_node("back_button")
self.transition = transitions.in_right_out_left(gui.get_node("root"), 0.6, 0)
local transition = transitions.in_right_out_left(gui.get_node("root"), 0.6, 0)
monarch.on_transition("pregame", transition)
end
function on_input(self, action_id, action)
@@ -26,5 +27,5 @@ function on_input(self, action_id, action)
end
function on_message(self, message_id, message, sender)
self.transition.handle(message_id, message, sender)
monarch.on_message(message_id, message, sender)
end

View File

@@ -4,10 +4,25 @@ function init(self)
monarch.debug()
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
monarch.add_listener()
end
function final(self)
monarch.remove_listener()
end
function on_message(self, message_id, message, sender)
if message_id == hash("init_monarch") then
monarch.show(hash("window1"))
elseif message_id == monarch.SCREEN_TRANSITION_IN_STARTED then
print("Monarch screen transition in started", message.screen)
elseif message_id == monarch.SCREEN_TRANSITION_IN_FINISHED then
print("Monarch screen transition in finished", message.screen)
elseif message_id == monarch.SCREEN_TRANSITION_OUT_STARTED then
print("Monarch screen transition out started", message.screen)
elseif message_id == monarch.SCREEN_TRANSITION_OUT_FINISHED then
print("Monarch screen transition out finished", message.screen)
elseif message_id == monarch.SCREEN_TRANSITION_FAILED then
print("Monarch screen transition failed")
end
end

View File

@@ -23,6 +23,5 @@ function on_input(self, action_id, action)
end
function on_message(self, message_id, message, sender)
print("window2", message_id, message, sender)
monarch.on_message(message_id, message, sender)
end

View File

@@ -5,7 +5,7 @@ dependencies#0 = https://github.com/britzl/deftest/archive/2.7.0.zip
dependencies#1 = https://github.com/defold/lua-language-server/releases/download/v0.0.3/release.zip
[bootstrap]
main_collection = /example/slidingwindow/slidingwindow.collectionc
main_collection = /example/advanced/advanced.collectionc
[input]
game_binding = /input/game.input_bindingc

View File

@@ -3,6 +3,7 @@ local async = require "monarch.utils.async"
local M = {}
local WAITFOR_COWAIT = hash("waitfor_cowait")
local WAITFOR_CONTEXT = hash("waitfor_monarch_context")
local WAITFOR_PROXY_LOADED = hash("waitfor_proxy_loaded")
local WAITFOR_PROXY_UNLOADED = hash("waitfor_proxy_unloaded")
@@ -19,6 +20,9 @@ local MSG_UNLOAD = hash("unload")
local MSG_ENABLE = hash("enable")
local MSG_DISABLE = hash("disable")
local DEPRECATED = hash("__DEPRECATED__")
-- transition messages
M.TRANSITION = {}
M.TRANSITION.DONE = hash("transition_done")
@@ -86,10 +90,13 @@ local function assign(to, from)
return to
end
local function cowait(delay)
local function cowait(screen, delay)
log("cowait()", screen.id, delay)
local co = coroutine.running()
assert(co, "You must run this from within a coroutine")
screen.wait_for = WAITFOR_COWAIT
timer.delay(delay, false, function()
screen.wait_for = nil
assert(coroutine.resume(co))
end)
coroutine.yield()
@@ -265,12 +272,6 @@ end
-- keep input focus when below a popup
-- * others_keep_input_focus_when_below_screen - If screens below this
-- screen should keep input focus
-- * transition_url - URL to a script that is responsible for the
-- screen transitions
-- * focus_url - URL to a script that is to be notified of focus
-- lost/gained events
-- * receiver_url - URL to a script that is to receive messages sent
-- using monarch.send()
-- * auto_preload - true if the screen should be automatically preloaded
function M.register_proxy(id, proxy, settings)
assert(proxy, "You must provide a collection proxy URL")
@@ -280,6 +281,15 @@ function M.register_proxy(id, proxy, settings)
screen.focus_url = settings and settings.focus_url
screen.receiver_url = settings and settings.receiver_url
screen.auto_preload = settings and settings.auto_preload
if screen.transition_url.fragment == DEPRECATED then
screen.transition_url = nil
end
if screen.focus_url.fragment == DEPRECATED then
screen.focus_url = nil
end
if screen.receiver_url.fragment == DEPRECATED then
screen.receiver_url = nil
end
if screen.auto_preload then
M.preload(id)
end
@@ -302,10 +312,6 @@ M.register = M.register_proxy
-- keep input focus when below a popup
-- * others_keep_input_focus_when_below_screen - If screens below this
-- screen should keep input focus
-- * 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
-- * auto_preload - true if the screen should be automatically preloaded
function M.register_factory(id, factory, settings)
assert(factory, "You must provide a collection factory URL")
@@ -314,6 +320,13 @@ function M.register_factory(id, factory, settings)
screen.transition_id = settings and settings.transition_id
screen.focus_id = settings and settings.focus_id
screen.auto_preload = settings and settings.auto_preload
if screen.transition_id == DEPRECATED then
screen.transition_id = nil
end
if screen.focus_id == DEPRECATED then
screen.focus_id = nil
end
if screen.auto_preload then
M.preload(id)
end
@@ -327,6 +340,7 @@ function M.unregister(id)
id = tohash(id)
assert(screens[id], ("There is no screen registered with id %s"):format(tostring(id)))
log("unregister()", id)
local screen = screens[id]
screens[id] = nil
-- remove screen from stack
for i = #stack, 1, -1 do
@@ -334,6 +348,10 @@ function M.unregister(id)
table.remove(stack, i)
end
end
screen.unregistered = true
if screen.wait_for then
assert(coroutine.resume(screen.co))
end
end
local function acquire_input(screen)
@@ -381,6 +399,7 @@ local function change_context(screen)
end
local function unload(screen, force)
if screen.unregistered then return end
if screen.proxy then
log("unload() proxy", screen.id)
if screen.auto_preload and not force then
@@ -415,8 +434,8 @@ local function unload(screen, force)
-- we need to wait here in case the unloaded screen contained any screens
-- if this is the case we need to let these sub-screens have their final()
-- functions called so that they have time to call unregister()
cowait(0)
cowait(0)
cowait(screen, 0)
cowait(screen, 0)
end
@@ -443,6 +462,9 @@ local function preload(screen)
msg.post(screen.proxy, MSG_ASYNC_LOAD)
coroutine.yield()
screen.wait_for = nil
if screen.unregistered then
return false, "Screen was unregistered while loading"
end
elseif screen.factory then
log("preload() factory")
if collectionfactory.get_status(screen.factory) == collectionfactory.STATUS_UNLOADED then
@@ -450,6 +472,9 @@ local function preload(screen)
assert(coroutine.resume(screen.co))
end)
coroutine.yield()
if screen.unregistered then
return false, "Screen was unregistered while loading"
end
end
if collectionfactory.get_status(screen.factory) ~= collectionfactory.STATUS_LOADED then
@@ -494,6 +519,7 @@ end
local function transition(screen, message_id, message, wait)
log("transition()", screen.id)
if screen.unregistered then return end
if screen.transition_url then
screen.wait_for = WAITFOR_TRANSITION_DONE
msg.post(screen.transition_url, message_id, message)
@@ -517,14 +543,15 @@ end
local function focus_lost(screen, next_screen)
log("focus_lost()", screen.id)
if screen.unregistered then return end
if screen.focus_url then
msg.post(screen.focus_url, M.FOCUS.LOST, { id = next_screen and next_screen.id })
-- if there's no transition on the screen losing focus and it gets
-- unloaded this will happen before the focus_lost message reaches
-- the focus_url
-- we add a delay to ensure the message queue has time to be processed
cowait(0)
cowait(0)
cowait(screen, 0)
cowait(screen, 0)
else
log("focus_lost() no focus url - ignoring")
end
@@ -645,7 +672,7 @@ local function show_in(screen, previous_screen, reload, add_to_stack, wait_for_t
return
end
-- wait one frame so that the init() of any script have time to run before starting transitions
cowait(0)
cowait(screen, 0)
reset_timestep(screen)
transition(screen, M.TRANSITION.SHOW_IN, { previous_screen = previous_screen and previous_screen.id }, wait_for_transition)
screen.visible = true
@@ -671,7 +698,7 @@ local function back_in(screen, previous_screen, wait_for_transition, cb)
return
end
-- wait one frame so that the init() of any script have time to run before starting transitions
cowait(0)
cowait(screen, 0)
reset_timestep(screen)
if previous_screen and not previous_screen.popup then
transition(screen, M.TRANSITION.BACK_IN, { previous_screen = previous_screen.id }, wait_for_transition)
@@ -688,8 +715,8 @@ local function back_out(screen, next_screen, wait_for_transition, cb)
log("back_out()", screen.id)
assert(wait_for_transition ~= nil)
run_coroutine(screen, cb, function()
notify_transition_listeners(M.SCREEN_TRANSITION_OUT_STARTED, { screen = screen.id, next_screen = next_screen and next_screen.id })
active_transition_count = active_transition_count + 1
notify_transition_listeners(M.SCREEN_TRANSITION_OUT_STARTED, { screen = screen.id, next_screen = next_screen and next_screen.id })
change_context(screen)
release_input(screen, next_screen)
focus_lost(screen, next_screen)
@@ -836,13 +863,10 @@ function M.show(id, options, data, cb)
show_in(screen, top, options and options.reload, add_to_stack, WAIT_FOR_TRANSITION, callbacks.track())
else
-- show screen
local cb = callbacks.track()
show_in(screen, top, options and options.reload, add_to_stack, DO_NOT_WAIT_FOR_TRANSITION, function()
if add_to_stack and top and not top.popup then
show_out(top, screen, WAIT_FOR_TRANSITION, callbacks.track())
end
cb()
end)
show_in(screen, top, options and options.reload, add_to_stack, WAIT_FOR_TRANSITION, callbacks.track())
if add_to_stack and top and not top.popup then
show_out(top, screen, WAIT_FOR_TRANSITION, callbacks.track())
end
end
callbacks.when_done(function()
@@ -938,21 +962,38 @@ end
-- Go back to the previous screen in the stack.
-- @param options (table) - Table with options when backing out from the screen (can be nil).
-- Valid values:
-- * sequential - Set to true to wait for the current screen to hide itself out before starting the
-- back in transition even when transitioning to a different scene ID.
-- @param data (*) - Optional data to set for the previous screen
-- @param cb (function) - Optional callback to invoke when the previous screen is visible again
function M.back(data, cb)
function M.back(options, data, cb)
log("back() queuing action")
-- backwards compatibility with old version M.back(data, cb)
-- case when back(data, cb)
if type(data) == "function" then
cb = data
data = options
options = nil
-- case when back(data, nil)
elseif options ~= nil and data == nil and cb == nil then
data = options
options = nil
end
queue_action(function(action_done)
local callbacks = callback_tracker()
local back_cb = callbacks.track()
local screen = table.remove(stack)
if screen then
log("back()", screen.id)
local top = stack[#stack]
-- 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
if top and screen.id == top.id then
local same_screen = top and top.id == screen.id
if same_screen or (options and options.sequential) then
local back_cb = callbacks.track()
back_out(screen, top, WAIT_FOR_TRANSITION, function()
if data then
top.data = data
@@ -970,16 +1011,16 @@ function M.back(data, cb)
-- we do this to ensure that we do not reset the times step of the screen
-- we go back to until it is no longer obscured by the popup
if screen.popup and not top.popup then
local back_cb = callbacks.track()
back_out(screen, top, WAIT_FOR_TRANSITION, function()
back_in(top, screen, WAIT_FOR_TRANSITION, back_cb)
end)
else
back_in(top, screen, DO_NOT_WAIT_FOR_TRANSITION, function()
back_out(screen, top, WAIT_FOR_TRANSITION, back_cb)
end)
back_in(top, screen, WAIT_FOR_TRANSITION, callbacks.track())
back_out(screen, top, WAIT_FOR_TRANSITION, callbacks.track())
end
else
back_out(screen, top, WAIT_FOR_TRANSITION, back_cb)
back_out(screen, top, WAIT_FOR_TRANSITION, callbacks.track())
end
end
end
@@ -1146,17 +1187,11 @@ function M.post(id, message_id, message)
assert(screens[id], ("There is no screen registered with id %s"):format(tostring(id)))
local screen = screens[id]
if screen.proxy then
if screen.receiver_url then
log("post() sending message to", screen.receiver_url)
msg.post(screen.receiver_url, message_id, message)
else
return false, "Unable to post message since screen has no receiver url specified"
end
if screen.receiver_url then
log("post() sending message to", screen.receiver_url)
msg.post(screen.receiver_url, message_id, message)
else
for id,instance in pairs(screen.factory_ids) do
msg.post(instance, message_id, message)
end
return false, "Unable to post message since screen has no receiver url specified. Set one using monarch.on_post()."
end
return true
end

View File

@@ -6,8 +6,8 @@ go.property("popup", false)
go.property("popup_on_popup", false)
go.property("screen_keeps_input_focus_when_below_popup", false)
go.property("others_keep_input_focus_when_below_screen", false)
go.property("transition_id", hash(""))
go.property("focus_id", hash(""))
go.property("transition_id", hash("__DEPRECATED__"))
go.property("focus_id", hash("__DEPRECATED__"))
go.property("preload", false)

View File

@@ -7,9 +7,9 @@ go.property("popup_on_popup", false)
go.property("timestep_below_popup", 1)
go.property("screen_keeps_input_focus_when_below_popup", false)
go.property("others_keep_input_focus_when_below_screen", false)
go.property("transition_url", msg.url())
go.property("focus_url", msg.url())
go.property("receiver_url", msg.url())
go.property("transition_url", msg.url("#__DEPRECATED__"))
go.property("focus_url", msg.url("#__DEPRECATED__"))
go.property("receiver_url", msg.url("#__DEPRECATED__"))
go.property("preload", false)

View File

@@ -1,5 +1,11 @@
local monarch
function init(self)
print("init - screen1")
monarch = require "monarch.monarch"
print("init - screen1", msg.url())
monarch.on_post("screen1", function(message_id, message, sender)
_G.screen1_on_post = message or true
end)
end
function final(self)
@@ -7,7 +13,8 @@ function final(self)
end
function on_message(self, message_id, message, sender)
monarch.on_message(message_id, message, sender)
if message_id == hash("foobar") then
_G.screen1_foobar = message or true
_G.screen1_on_message = message or true
end
end

View File

@@ -1,5 +1,11 @@
local monarch
function init(self)
print("init - screen2")
monarch = require "monarch.monarch"
print("init - screen2", msg.url())
monarch.on_post("screen2", function(message_id, message, sender)
_G.screen2_on_post = message or true
end)
end
function final(self)
@@ -7,7 +13,8 @@ function final(self)
end
function on_message(self, message_id, message, sender)
monarch.on_message(message_id, message, sender)
if message_id == hash("foobar") then
_G.screen2_foobar = message or true
_G.screen2_on_message = message or true
end
end

View File

@@ -12,7 +12,6 @@ local FOCUS1 = hash("focus1")
local BACKGROUND = hash("background")
local POPUP1 = hash("popup1")
local POPUP2 = hash("popup2")
local FOOBAR = hash("foobar")
local TRANSITION1 = hash("transition1")
local function check_stack(expected_screens)
@@ -220,7 +219,7 @@ return function()
assert(monarch.data(SCREEN2) == data2, "Expected data on screen2 doesn't match actual data")
local data_back = { going = "back" }
monarch.back(data_back)
monarch.back(nil, data_back)
assert(wait_until_visible(SCREEN1))
assert(monarch.data(SCREEN1) == data_back, "Expected data on screen1 doesn't match actual data")
@@ -425,10 +424,10 @@ return function()
assert(#mock_msg.messages(URL2) == 2)
assert(mock_msg.messages(URL1)[3].message_id == monarch.SCREEN_TRANSITION_IN_STARTED)
assert(mock_msg.messages(URL1)[3].message.screen == SCREEN2)
assert(mock_msg.messages(URL1)[4].message_id == monarch.SCREEN_TRANSITION_IN_FINISHED)
assert(mock_msg.messages(URL1)[4].message.screen == SCREEN2)
assert(mock_msg.messages(URL1)[5].message_id == monarch.SCREEN_TRANSITION_OUT_STARTED)
assert(mock_msg.messages(URL1)[5].message.screen == SCREEN1)
assert(mock_msg.messages(URL1)[4].message_id == monarch.SCREEN_TRANSITION_OUT_STARTED)
assert(mock_msg.messages(URL1)[4].message.screen == SCREEN1)
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)
@@ -439,10 +438,10 @@ return function()
assert(#mock_msg.messages(URL2) == 2)
assert(mock_msg.messages(URL1)[7].message_id == monarch.SCREEN_TRANSITION_IN_STARTED)
assert(mock_msg.messages(URL1)[7].message.screen == SCREEN1)
assert(mock_msg.messages(URL1)[8].message_id == monarch.SCREEN_TRANSITION_IN_FINISHED)
assert(mock_msg.messages(URL1)[8].message.screen == SCREEN1)
assert(mock_msg.messages(URL1)[9].message_id == monarch.SCREEN_TRANSITION_OUT_STARTED)
assert(mock_msg.messages(URL1)[9].message.screen == SCREEN2)
assert(mock_msg.messages(URL1)[8].message_id == monarch.SCREEN_TRANSITION_OUT_STARTED)
assert(mock_msg.messages(URL1)[8].message.screen == SCREEN2)
assert(mock_msg.messages(URL1)[9].message_id == monarch.SCREEN_TRANSITION_IN_FINISHED)
assert(mock_msg.messages(URL1)[9].message.screen == SCREEN1)
assert(mock_msg.messages(URL1)[10].message_id == monarch.SCREEN_TRANSITION_OUT_FINISHED)
assert(mock_msg.messages(URL1)[10].message.screen == SCREEN2)
end)
@@ -491,49 +490,56 @@ return function()
it("should be able to post messages without message data to visible screens", function()
_G.screen1_foobar = nil
_G.screen2_foobar = nil
_G.screen1_on_message = nil
_G.screen1_on_post = nil
_G.screen2_on_message = nil
_G.screen2_on_post = nil
-- proxy screen
monarch.show(SCREEN1)
wait_until_visible(SCREEN1)
assert(monarch.post(SCREEN1, "foobar"), "Expected monarch.post() to return true")
cowait(0.1)
assert(_G.screen1_foobar, "Screen1 never received a message")
assert(_G.screen1_on_message, "Screen1 never received a message")
assert(_G.screen1_on_post, "Screen1 never received a callback")
-- factory screen
monarch.show(SCREEN2)
wait_until_visible(SCREEN2)
assert(monarch.post(SCREEN2, "foobar"), "Expected monarch.post() to return true")
cowait(0.1)
assert(_G.screen2_foobar, "Screen2 never received a message")
assert(_G.screen2_on_message, "Screen2 never received a message")
assert(_G.screen2_on_post, "Screen2 never received a callback")
end)
it("should be able to post messages with message data to visible screens", function()
_G.screen1_foobar = nil
_G.screen2_foobar = nil
_G.screen1_on_message = nil
_G.screen1_on_post = nil
_G.screen2_on_message = nil
_G.screen2_on_post = nil
-- proxy screen
monarch.show(SCREEN1)
wait_until_visible(SCREEN1)
assert(monarch.post(SCREEN1, "foobar", { foo = "bar" }), "Expected monarch.post() to return true")
cowait(0.1)
assert(_G.screen1_foobar, "Screen1 never received a message")
assert(_G.screen1_foobar.foo == "bar", "Screen1 never received message data")
assert(_G.screen1_on_message, "Screen1 never received a message")
assert(_G.screen1_on_message.foo == "bar", "Screen1 never received message data")
-- factory screen
monarch.show(SCREEN2)
wait_until_visible(SCREEN2)
assert(monarch.post(SCREEN2, "foobar", { foo = "bar" }), "Expected monarch.post() to return true")
cowait(0.1)
assert(_G.screen2_foobar, "Screen2 never received a message")
assert(_G.screen2_foobar.foo == "bar", "Screen2 never received message data")
assert(_G.screen2_on_message, "Screen2 never received a message")
assert(_G.screen2_on_message.foo == "bar", "Screen2 never received message data")
end)
it("should not be able to post messages to hidden screens", function()
_G.screen1_foobar = nil
_G.screen1_on_message = nil
_G.screen1_on_post = nil
monarch.show(SCREEN1)
monarch.show(SCREEN2)
@@ -542,7 +548,7 @@ return function()
local ok, err = monarch.post(SCREEN1, "foobar")
assert(not ok and err, "Expected monarch.post() to return false plus an error message")
cowait(0.1)
assert(not _G.screen1_foobar, "Screen1 should not have received a message")
assert(not _G.screen1_on_message, "Screen1 should not have received a message")
end)