3
0
mirror of https://github.com/britzl/monarch.git synced 2025-06-27 10:27:49 +02:00

Added support for monarch.post()

This commit is contained in:
Björn Ritzl 2019-08-01 07:21:20 +02:00
parent c7981e77cf
commit 6b3cc11073
8 changed files with 132 additions and 5 deletions

View File

@ -33,6 +33,7 @@ For proxies the recommended setup is to create one game object per screen and pe
* **Timestep below Popup (number)** - Timestep to set on screen proxy when it is below a popup. This is useful when pausing animations and gameplay while a popup is open. * **Timestep below Popup (number)** - Timestep to set on screen proxy when it is below a popup. This is useful when pausing animations and gameplay while a popup is open.
* **Transition Url (url)** - Optional URL to post messages to when the screen is about to be shown/hidden. Use this to trigger a transition (see the section on [transitions](#transitions)). * **Transition Url (url)** - Optional URL to post messages to when the screen is about to be shown/hidden. Use this to trigger a transition (see the section on [transitions](#transitions)).
* **Focus Url (url)** - Optional URL to post messages to when the screen gains or loses focus (see the section on [screen focus](#screen-focus-gainloss)). * **Focus Url (url)** - Optional URL to post messages to when the screen gains or loses focus (see the section on [screen focus](#screen-focus-gainloss)).
* **Receiver Url (url)** - Optional URL to post messages to using monarch.post().
* **Preload (boolean)** - Check this if the screen should be preloaded and kept loaded at all times. For a collection proxy it means that it will be async loaded but not enabled at all times while not visible. This can also temporarily be achieved through the `monarch.preload()` function. * **Preload (boolean)** - Check this if the screen should be preloaded and kept loaded at all times. For a collection proxy it means that it will be async loaded but not enabled at all times while not visible. This can also temporarily be achieved through the `monarch.preload()` function.
![](docs/setup_proxy.png) ![](docs/setup_proxy.png)
@ -441,6 +442,19 @@ Remove a previously added listener.
* ```url``` (url) - URL to remove. Will use current URL if omitted. * ```url``` (url) - URL to remove. Will use current URL if omitted.
### 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.
**PARAMETERS**
* ```screen_id``` (string|hash) - Id of the screen to post message to
* ```message_id``` (string|hash) - Id of the message to send
* ```message``` (table|nil) - Optional message data to send
**RETURN**
* ```result``` (boolean) - True if the message was sent
* ```error``` (string|nil) - Error message if unable to send message
### monarch.debug() ### monarch.debug()
Enable verbose logging of the internals of Monarch. Enable verbose logging of the internals of Monarch.

View File

@ -170,6 +170,8 @@ end
-- screen transitions -- screen transitions
-- * focus_url - URL to a script that is to be notified of focus -- * focus_url - URL to a script that is to be notified of focus
-- lost/gained events -- lost/gained events
-- * receiver_url - URL to a script that is to receive messages sent
-- using monarch.send()
-- * timestep_below_popup - Timestep to set on proxy when below a popup -- * timestep_below_popup - Timestep to set on proxy when below a popup
-- * auto_preload - true if the screen should be automatically preloaded -- * auto_preload - true if the screen should be automatically preloaded
function M.register_proxy(id, proxy, settings) function M.register_proxy(id, proxy, settings)
@ -178,6 +180,7 @@ function M.register_proxy(id, proxy, settings)
screen.proxy = proxy screen.proxy = proxy
screen.transition_url = settings and settings.transition_url screen.transition_url = settings and settings.transition_url
screen.focus_url = settings and settings.focus_url screen.focus_url = settings and settings.focus_url
screen.receiver_url = settings and settings.receiver_url
screen.auto_preload = settings and settings.auto_preload screen.auto_preload = settings and settings.auto_preload
if screen.auto_preload then if screen.auto_preload then
M.preload(id) M.preload(id)
@ -814,6 +817,43 @@ function M.unload(id, cb)
end end
--- Post a message to a screen (using msg.post)
-- @param id (string|hash) Id of the screen to send message to
-- @param message_id (string|hash) Id of the message to send
-- @param message (table|nil) Optional message data to send
-- @return result (boolean) true if successful
-- @return error (string|nil) Error message if unable to send message
function M.post(id, message_id, message)
assert(id, "You must provide a screen id")
if not M.is_visible(id) then
return false, "Unable to post message to screen if it isn't visible"
end
assert(message_id, "You must provide a message_id")
id = tohash(id)
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
else
run_coroutine(screen, nil, function()
change_context(screen)
log("post() sending message to", screen.receiver_url)
for id,instance in pairs(screen.factory_ids) do
msg.post(instance, message_id, message)
end
end)
end
return true
end
function M.on_message(message_id, message, sender) function M.on_message(message_id, message, sender)
if message_id == PROXY_LOADED then if message_id == PROXY_LOADED then
local screen = screen_from_proxy(sender) local screen = screen_from_proxy(sender)

View File

@ -7,6 +7,7 @@ go.property("popup_on_popup", false)
go.property("timestep_below_popup", 1) go.property("timestep_below_popup", 1)
go.property("transition_url", msg.url()) go.property("transition_url", msg.url())
go.property("focus_url", msg.url()) go.property("focus_url", msg.url())
go.property("receiver_url", msg.url())
go.property("preload", false) go.property("preload", false)
@ -22,6 +23,7 @@ function init(self)
popup_on_popup = self.popup_on_popup, popup_on_popup = self.popup_on_popup,
transition_url = self.transition_url ~= url and self.transition_url or nil, transition_url = self.transition_url ~= url and self.transition_url or nil,
focus_url = self.focus_url ~= url and self.focus_url or nil, focus_url = self.focus_url ~= url and self.focus_url or nil,
receiver_url = self.receiver_url ~= url and self.receiver_url or nil,
timestep_below_popup = self.timestep_below_popup, timestep_below_popup = self.timestep_below_popup,
auto_preload = self.preload, auto_preload = self.preload,
} }

View File

@ -7,6 +7,7 @@ function final(self)
end end
function on_message(self, message_id, message, sender) function on_message(self, message_id, message, sender)
-- Add message-handling code here if message_id == hash("foobar") then
-- Remove this function if not needed _G.screen1_foobar = message or true
end
end end

View File

@ -7,6 +7,7 @@ function final(self)
end end
function on_message(self, message_id, message, sender) function on_message(self, message_id, message, sender)
-- Add message-handling code here if message_id == hash("foobar") then
-- Remove this function if not needed _G.screen2_foobar = message or true
end
end end

View File

@ -21,6 +21,11 @@ embedded_instances {
" value: \"screen1\"\n" " value: \"screen1\"\n"
" type: PROPERTY_TYPE_HASH\n" " type: PROPERTY_TYPE_HASH\n"
" }\n" " }\n"
" properties {\n"
" id: \"receiver_url\"\n"
" value: \"screen1:/go\"\n"
" type: PROPERTY_TYPE_URL\n"
" }\n"
"}\n" "}\n"
"embedded_components {\n" "embedded_components {\n"
" id: \"collectionproxy\"\n" " id: \"collectionproxy\"\n"

View File

@ -9,6 +9,6 @@ function init(self)
deftest.add(test_callback_tracker) deftest.add(test_callback_tracker)
deftest.run({ deftest.run({
coverage = { enabled = true }, coverage = { enabled = true },
--pattern = "preload", pattern = "",
}) })
end end

View File

@ -416,5 +416,69 @@ return function()
assert(wait_until_hidden(FOCUS1), "Focus1 was never hidden") assert(wait_until_hidden(FOCUS1), "Focus1 was never hidden")
assert(_G.focus1_lost) assert(_G.focus1_lost)
end) end)
it("should be able to post messages without message data to visible screens", function()
_G.screen1_foobar = nil
_G.screen2_foobar = nil
-- proxy screen
monarch.show(SCREEN1)
wait_until_shown(SCREEN1)
assert(monarch.post(SCREEN1, "foobar"), "Expected monarch.post() to return true")
cowait(0.1)
assert(_G.screen1_foobar, "Screen1 never received a message")
-- factory screen
monarch.show(SCREEN2)
wait_until_shown(SCREEN2)
assert(monarch.post(SCREEN2, "foobar"), "Expected monarch.post() to return true")
cowait(0.1)
assert(_G.screen2_foobar, "Screen2 never received a message")
end)
it("should be able to post messages with message data to visible screens", function()
_G.screen1_foobar = nil
_G.screen2_foobar = nil
-- proxy screen
monarch.show(SCREEN1)
wait_until_shown(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")
-- factory screen
monarch.show(SCREEN2)
wait_until_shown(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")
end)
it("should not be able to post messages to hidden screens", function()
_G.screen1_foobar = nil
monarch.show(SCREEN1)
wait_until_shown(SCREEN1)
monarch.show(SCREEN2)
wait_until_shown(SCREEN2)
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")
end)
it("should not be able to post messages to proxy screens without a receiver url", function()
monarch.show(POPUP1)
wait_until_shown(POPUP1)
local ok, err = monarch.post(POPUP1, "foobar")
assert(not ok and err, "Expected monarch.post() to return false plus an error message")
end)
end) end)
end end