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

Compare commits

..

5 Commits
4.1.0 ... 4.3.0

Author SHA1 Message Date
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
7 changed files with 91 additions and 40 deletions

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

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

@@ -21,7 +21,7 @@ local MSG_ENABLE = hash("enable")
local MSG_DISABLE = hash("disable")
local DEPRECATED = hash("/__DEPRECATED__")
local DEPRECATED = hash("__DEPRECATED__")
-- transition messages
M.TRANSITION = {}
@@ -281,13 +281,13 @@ 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.path == DEPRECATED then
if screen.transition_url.fragment == DEPRECATED then
screen.transition_url = nil
end
if screen.focus_url.path == DEPRECATED then
if screen.focus_url.fragment == DEPRECATED then
screen.focus_url = nil
end
if screen.receiver_url.path == DEPRECATED then
if screen.receiver_url.fragment == DEPRECATED then
screen.receiver_url = nil
end
if screen.auto_preload then
@@ -965,21 +965,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
@@ -1173,17 +1190,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

@@ -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("__DEPRECATED__"))
go.property("focus_url", msg.url("__DEPRECATED__"))
go.property("receiver_url", msg.url("__DEPRECATED__"))
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)
@@ -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)