mirror of
https://github.com/britzl/monarch.git
synced 2025-11-26 19:00:53 +01:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c473aa053c | ||
|
|
169236acbd | ||
|
|
b7053d2ce4 | ||
|
|
91204ca30b | ||
|
|
6f79bd0326 | ||
|
|
e5214edb22 | ||
|
|
1d4e48c0de | ||
|
|
5bdc3e4540 | ||
|
|
85123c84e9 | ||
|
|
a605f4f6f8 |
@@ -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.
|
||||
@@ -207,12 +212,14 @@ IMPORTANT! You must call `monarch.on_message(message_id, message, sender)` from
|
||||
* `fn` (function) - The function to call screen focus changes
|
||||
|
||||
|
||||
## monarch.on_post(screen_id, fn)
|
||||
Set a function to be called when `msg.post()` is called on a specific screen. IMPORTANT! You must call `monarch.on_message(message_id, message, sender)` from the same script as this function was called.
|
||||
## monarch.on_post(screen_id, fn_or_url)
|
||||
Set either a function to be called when `msg.post()` is called on a specific screen or a URL where the message is sent.
|
||||
|
||||
IMPORTANT! If you provide a function you must also make sure to call `monarch.on_message(message_id, message, sender)` from the same script as this function was called.
|
||||
|
||||
**PARAMETERS**
|
||||
* `screen_id` (string|hash) - Id of the screen
|
||||
* `fn` (function) - The function to call when the screen receives a message using `msg.post`
|
||||
* `fn_or_url` (function) - The function to call or URL to send message to
|
||||
|
||||
|
||||
## monarch.debug()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -715,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)
|
||||
@@ -863,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()
|
||||
@@ -965,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
|
||||
@@ -997,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
|
||||
@@ -1317,20 +1331,30 @@ function M.on_focus_changed(id, fn)
|
||||
end
|
||||
|
||||
---
|
||||
-- Set a function to call when a screen is sent a message using monarch.post()
|
||||
-- The function will receive (message_id, message, sender)
|
||||
-- IMPORTANT! You must call monarch.on_message() from the same script as
|
||||
-- this function was called
|
||||
-- Set either a function to be called when msg.post() is called on a specific
|
||||
-- screen or a URL where the message is sent.
|
||||
-- IMPORTANT! If you provide a function you must also make sure to call
|
||||
-- monarch.on_message(message_id, message, sender) from the same script as
|
||||
-- this function was called.
|
||||
-- @param id Screen id to associate the message listener function with
|
||||
-- @param fn Message listener function
|
||||
function M.on_post(id, fn)
|
||||
-- @param fn_or_url The function to call or URL to send message to
|
||||
function M.on_post(id, fn_or_url)
|
||||
assert(id, "You must provide a screen id")
|
||||
assert(fn, "You must provide a post receiver function")
|
||||
id = tohash(id)
|
||||
assert(screens[id], ("There is no screen registered with id %s"):format(tostring(id)))
|
||||
local screen = screens[id]
|
||||
screen.receiver_url = msg.url()
|
||||
screen.receiver_fn = fn
|
||||
|
||||
local t = type(fn_or_url)
|
||||
if t == "function" then
|
||||
screen.receiver_fn = fn_or_url
|
||||
screen.receiver_url = msg.url()
|
||||
elseif t == "userdata" or t == "string" then
|
||||
screen.receiver_fn = nil
|
||||
screen.receiver_url = fn_or_url
|
||||
else
|
||||
screen.receiver_fn = nil
|
||||
screen.receiver_url = msg.url()
|
||||
end
|
||||
end
|
||||
|
||||
local function url_to_key(url)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user