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

Compare commits

..

18 Commits
4.4.1 ... 5.2.0

Author SHA1 Message Date
Jerakin
18a8d1ea06 rewrite editor script to use editor.transact api (#115) 2025-10-06 13:39:13 +02:00
Björn Ritzl
d91e44f12d Update game.project 2025-07-17 08:07:52 +02:00
Björn Ritzl
9a6d5f7a7b Update ci-workflow.yml 2025-05-15 08:58:40 +02:00
Björn Ritzl
d68e27b2ad Update ci-workflow.yml 2025-05-15 08:57:50 +02:00
Björn Ritzl
5525707744 Cleaned up callback tests
Fixes #
2025-05-14 22:56:47 +02:00
Alexander
aea267cc35 fix gui template (#112)
https://github.com/britzl/monarch/issues/111
2024-09-27 08:58:51 +02:00
Pawel
6ba3064749 Fixed an error that appears when trying to delete an instance that is already deleted. (#109)
* Prevent deleting already removed instances.

* Prehashed empty hash.

* Use go.exists instead of pcall, when detecting non existing instances.
2024-03-04 16:06:56 +01:00
Björn Ritzl
b78b896ada Update README_API.md 2024-01-30 11:08:38 +01:00
SalavatR
679482f84d Add a check for missing resources in collection proxies. (#107)
* Update monarch.lua

* Update monarch.lua

* Update monarch.lua
2024-01-30 11:03:37 +01:00
Björn Ritzl
4c6e26fd71 Removed backward comp fix for monarch.back() 2024-01-12 08:31:48 +01:00
bedryck
00c30792a9 fix a problem of sequential in back function (#104) 2024-01-12 08:22:43 +01:00
Björn Ritzl
b01f5d28c3 Update monarch.lua 2023-12-27 15:54:09 +01:00
Pete Garcin
43e847dacc Guard DEPRECATED transition_id overwriting transition_url (#100) 2023-12-27 15:52:36 +01:00
Björn Ritzl
ce5ca26b6c Update README_TRANSITIONS.md
Fixes #102
2023-12-27 15:51:38 +01:00
Björn Ritzl
742779d749 Allow monarch.post() to loaded screens
Fixes #98
2023-10-26 13:54:14 +02:00
Björn Ritzl
84944f3f22 Added monarch.is_loaded() 2023-10-26 11:43:19 +02:00
Björn Ritzl
c473aa053c Update monarch.lua 2023-08-31 09:25:00 +02:00
Björn Ritzl
169236acbd Improved on_post() to also accept a url 2023-08-31 09:22:24 +02:00
16 changed files with 344 additions and 182 deletions

View File

@@ -7,13 +7,13 @@ jobs:
name: Build and run
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-java@v1
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
- uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9
with:
java-version: '17'
java-version: '21.0.5+11.0.LTS'
distribution: 'temurin'
- name: Run.sh
env:
DEFOLD_USER: bjorn.ritzl@gmail.com
DEFOLD_AUTH: foobar
DEFOLD_BOOSTRAP_COLLECTION: /test/test.collectionc
run: ./.test/run.sh

3
.gitignore vendored
View File

@@ -9,3 +9,6 @@ build
builtins
.internal
luacov.report.out
/.editor_settings
manifest.private.der
manifest.public.der

View File

@@ -5,7 +5,6 @@ else
PLATFORM="$1"
fi
echo "${PLATFORM}"
# {"version": "1.2.89", "sha1": "5ca3dd134cc960c35ecefe12f6dc81a48f212d40"}
@@ -16,26 +15,28 @@ echo "Using Defold dmengine_headless version ${SHA1}"
# Create dmengine_headless and bob.jar URLs
DMENGINE_URL="http://d.defold.com/archive/${SHA1}/engine/${PLATFORM}/dmengine_headless"
BOB_URL="http://d.defold.com/archive/${SHA1}/bob/bob.jar"
DMENGINE_FILE=dmengine_headless_${SHA1}
BOB_FILE=bob_${SHA1}.jar
# Download dmengine_headless
echo "Downloading ${DMENGINE_URL}"
curl -L -o dmengine_headless ${DMENGINE_URL}
chmod +x dmengine_headless
if ! [ -f ${DMENGINE_FILE} ]; then
echo "Downloading ${DMENGINE_URL} to ${DMENGINE_FILE}"
curl -L -o ${DMENGINE_FILE} ${DMENGINE_URL}
chmod +x ${DMENGINE_FILE}
fi
# Download bob.jar
echo "Downloading ${BOB_URL}"
curl -L -o bob.jar ${BOB_URL}
if ! [ -f ${BOB_FILE} ]; then
echo "Downloading ${BOB_URL} to ${BOB_FILE}"
curl -L -o ${BOB_FILE} ${BOB_URL}
fi
# Fetch libraries
echo "Running bob.jar - resolving dependencies"
java -jar bob.jar --auth "foobar" --email "john@doe.com" resolve
echo "Running ${BOB_FILE} - resolving dependencies"
java -jar ${BOB_FILE} --auth "foobar" --email "john@doe.com" resolve
echo "Running bob.jar - building"
java -jar bob.jar --debug build --keep-unused
echo "Running ${BOB_FILE} - building"
java -jar ${BOB_FILE} --debug build --settings=test.settings
echo "Starting dmengine_headless"
if [ -n "${DEFOLD_BOOSTRAP_COLLECTION}" ]; then
./dmengine_headless --config=bootstrap.main_collection=${DEFOLD_BOOSTRAP_COLLECTION}
else
./dmengine_headless
fi
echo "Starting ${DMENGINE_FILE}"
./${DMENGINE_FILE}

View File

@@ -20,10 +20,15 @@ Or point to the ZIP file of a [specific release](https://github.com/britzl/monar
Using Monarch requires that screens are created in a certain way. Once you have one or more screens created you can start navigating between the screens.
## Editor Script
Right click in on a`.gui` file in the outline and selected the menu item, it creates a `.collection` and a `.gui_script` with the same name as the `.gui` file. It adds the file with some basic setup done to them, adding the selected gui script to the created gui scene and in turns adds the gui scene to the newly created collection.
Right click in on a`.gui`, `.gui_script` or `.collection` file in the outline and selected the menu item, it creates the other two file types with the same name as the selected file. It adds the file with some basic setup done to them, adding the selected gui script to the created gui scene and in turns adds the gui scene to the newly created collection.
You can also right click on directory to get the option to create a monarch scene from it, the directory should be empty (or only contain other monarch scene files).Use the option and it will create all three files inside of the directory.
<img src="/docs/editor_script.gif" width="200px">
You can use Monarchs editor script with your own custom templates. Create the template files you want, these are normal defold files. Then inside of your game.project file add a path to the files you created.
## Creating screens
Monarch screens are created in individual collections and either loaded through collection proxies or created through collection factories.

View File

@@ -212,12 +212,21 @@ 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.has_missing_resources(screen_id)
Check if a screen has any missing resources. If the screen is loaded by a collection proxy with Load Dynamically this will use `collectionproxy.missing_resources()`. For other cases this function will always return false.
**RETURN**
* `result` (boolean) - true if the screen has missing resources
## monarch.debug()

View File

@@ -114,7 +114,7 @@ end
function on_message(self, message_id, message, sender)
if message_id == hash("my_resize_message") then
self.transition.window_resized(message.width, message.height)
transition.window_resized(message.width, message.height)
end
end
```

View File

@@ -29,7 +29,7 @@ function on_input(self, action_id, action)
end
elseif gui.pick_node(self.no, action.x, action.y) then
print("no")
monarch.back(function()
monarch.back(nil, nil, function()
print("back from popup done")
end)
end

View File

@@ -27,7 +27,7 @@ function on_input(self, action_id, action)
end)
elseif gui.pick_node(self.cancel, action.x, action.y) then
print("cancel")
monarch.back(function()
monarch.back(nil, nil, function()
print("back from popup done")
end)
elseif gui.pick_node(self.about, action.x, action.y) then

View File

@@ -19,7 +19,7 @@ function on_input(self, action_id, action)
end)
elseif gui.pick_node(self.back, action.x, action.y) then
print("back")
monarch.back(function()
monarch.back(nil, nil, function()
print("back from pregame done")
end)
end

View File

@@ -2,7 +2,6 @@
title = Monarch
version = 0.9
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/advanced/advanced.collectionc
@@ -20,10 +19,10 @@ display_profiles = /example/example.display_profilesc
shared_state = 1
[ios]
bundle_identifier = com.example.todo
bundle_identifier = com.defold.monarch
[osx]
bundle_identifier = com.example.todo
bundle_identifier = com.defold.monarch
[library]
include_dirs = monarch

View File

@@ -1,8 +1,13 @@
local M = {}
local collection_template
local gui_script_content
local gui_file_content
local gui_script_template
local gui_template
local function _log(msg)
io.stdout:write("ERROR:MONARCH: " .. msg .. "\n")
io.stdout:flush()
end
local function ends_with(str, ending)
return ending == "" or str:sub(-#ending) == ending
@@ -18,43 +23,138 @@ local function get_filename(path)
return main, filename
end
local function create_files(file_path)
-- Construct paths
local path = editor.get(file_path, "path")
local main, filename = get_filename(path)
local basename = filename:match("(.+)%..+")
local target_collection_path = "." .. main .. basename .. ".collection"
local target_gui_script_path = "." .. main .. basename .. ".gui_script"
local target_gui_path = "." .. main .. basename .. ".gui"
local function get_template(game_project_path)
-- The input file can be the "compiled" file. If they are they end with "c".
-- If they end with "c" remove the last charater.
local path = editor.get("/game.project", game_project_path)
if path == nil then
return
end
if ends_with(path, "c") then
return path:sub(1, -2)
end
return path
end
-- Create the files if they don't exists
if not file_exists(target_collection_path) then
local collection_content = collection_template(path, basename)
local collection = io.open(target_collection_path, "w")
collection:write(collection_content)
local function get_template_content(type_string)
local default_template = {
collection = collection_template,
gui_script = gui_script_template,
gui = gui_template,
}
local custom_template = {
collection = get_template("monarch.collection_template"),
gui_script = get_template("monarch.gui_script_template"),
gui = get_template("monarch.gui_template"),
}
local template = custom_template[type_string]
if template ~= nil then
local file = io.open("." .. template, "rb")
if file == nil then
_log("Could not read " .. type_string .. " template '" .. template .. "'")
return
end
local content = file:read("*a")
file:close()
return content
end
return default_template[type_string]
end
local function add_monarch_go(collection_file, gui_file, name)
return editor.tx.add(collection_file, "children", {
type = "go",
id = "monarch",
components = {
{
type = "component-reference",
id = name,
path = gui_file,
}
}
})
end
local function create_collection(collection_file, gui_file, name)
local _collection_content = get_template_content("collection")
if _collection_content == nil then
_log("Could not create colletion file at " .. gui)
return
end
local collection = io.open("." .. collection_file, "w")
if collection == nil then
_log("Could not create colletion file at " .. collection_file)
return
end
collection:write(_collection_content)
collection:close()
return add_monarch_go(collection_file, gui_file, name)
end
if not file_exists(target_gui_script_path) then
local gui_script = io.open(target_gui_script_path, "w")
gui_script:write(gui_script_content)
gui_script:close()
-- Put the gui_script path into the gui file
local gui_file = io.open("." .. path, "rb")
local gui_text = gui_file:read("*a")
gui_file:close()
gui_text = string.gsub(gui_text, 'script: "%.*"', [[script: "]] .. main .. basename .. ".gui_script" .. [["]])
gui_file = io.open("." .. path, "w")
gui_file:write(gui_text)
gui_file:close()
local function create_gui(gui_file, gui_script_file)
local gui_content = get_template_content("gui")
if gui_content == nil then
_log("Could not create gui file at " .. gui)
return
end
local gui = io.open("." .. gui_file, "w")
if gui == nil then
_log("Could not create gui file at " .. gui)
return
end
if not file_exists(target_gui_path) then
local gui_content = gui_template(path)
local gui = io.open(target_gui_path, "w")
gui:write(gui_content)
gui:close()
return editor.tx.set(gui_file, "script", gui_script_file)
end
local function create_files(directory, name)
-- Construct paths
local target_collection_path = directory .. name .. ".collection"
local target_gui_script_path = directory .. name .. ".gui_script"
local target_gui_path = directory .. name .. ".gui"
if not file_exists("." .. target_gui_script_path) then
local gui_script_template_content = get_template_content("gui_script")
if gui_script_template_content == nil then
return
end
local gui_script = io.open("." .. target_gui_script_path, "w")
gui_script:write(gui_script_template_content)
gui_script:close()
end
local transactions = {}
if file_exists("." .. target_gui_path) then
-- If the gui file exists change the script.
table.insert(transactions, editor.tx.set(target_gui_path, "script", target_gui_script_path)
)
else
-- If the gui file doesn't exist create a new one.
local transaction = create_gui(target_gui_path, target_gui_script_path)
if transaction == nil then
return
end
table.insert(transactions, transaction)
end
if file_exists("." .. target_collection_path) then
--- If the collection already exists we will add the monarch go to it.
local transaction = add_monarch_go(target_collection_path, target_gui_path, name)
if transaction == nil then
return
end
table.insert(transactions, transaction)
else
-- If the collection doesn't exists we create a new one.
local transaction = create_collection(target_collection_path, target_gui_path, name)
if transaction == nil then
return
end
table.insert(transactions, transaction)
end
if #transactions > 1 then
editor.transact(transactions)
editor.save()
end
end
@@ -68,30 +168,54 @@ function M.get_commands()
},
active = function(opts)
local path = editor.get(opts.selection, "path")
return ends_with(path, ".gui")
return ends_with(path, ".gui") or ends_with(path, ".gui_script") or ends_with(path, ".collection")
end,
run = function(opts)
create_files(opts.selection)
local path = editor.get(opts.selection, "path")
local directory, filename = get_filename(path)
local basename = filename:match("(.+)%..+")
create_files(directory, basename)
end
},
{
label="Create Monarch Scene From Directory",
locations = {"Assets"},
query = {
selection = {type = "resource", cardinality = "one"}
},
active = function(opts)
local _is_directory = editor.resource_attributes(editor.get(opts.selection, "path")).is_directory
if not _is_directory then
return false
end
local _children = editor.get(opts.selection, "children")
if #_children >= 3 then
return false
end
for i = 1, #_children do
local _path = editor.get(_children[i], "path")
if not (ends_with(_path, ".gui") or ends_with(_path, ".collection") or ends_with(_path, ".gui_script")) then
return false
end
end
return true
end,
run = function(opts)
local path = editor.get(opts.selection, "path")
local _, filename = get_filename(path)
create_files(path .. "/", filename)
end
}
}
end
gui_template = function(gui_script)
return [[script: "]].. gui_script .. [["
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
gui_template = [[
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512
]]
end
gui_script_content = [[local monarch = require "monarch.monarch"
gui_script_template = [[local monarch = require "monarch.monarch"
function init(self)
msg.post(".", "acquire_input_focus")
@@ -113,49 +237,10 @@ function on_reload(self)
end
]]
collection_template = function(gui_script, name)
return [[name: "]].. name .. [["
collection_template = [[
name: "m"
scale_along_z: 0
embedded_instances {
id: "go"
data: "components {\n"
" id: \"monarch\"\n"
" component: \"]].. gui_script .. [[\"\n"
" position {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" }\n"
" rotation {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" w: 1.0\n"
" }\n"
"}\n"
""
position {
x: 0.0
y: 0.0
z: 0.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale3 {
x: 1.0
y: 1.0
z: 1.0
}
}
]]
end
return M

10
monarch/ext.properties Normal file
View File

@@ -0,0 +1,10 @@
[monarch]
collection_template.type = resource
collection_template.filter = collection
gui_script_template.type = resource
gui_script_template.filter = gui_script
gui_template.type = resource
gui_template.filter = gui

View File

@@ -228,6 +228,17 @@ function M.is_visible(id)
end
--- Check if a screen is loaded
-- @param id (string|hash)
-- @return true if the screen is loaded
function M.is_loaded(id)
assert(id, "You must provide a screen id")
id = tohash(id)
assert(screens[id], ("There is no screen registered with id %s"):format(tostring(id)))
return screens[id].loaded
end
--- Check if a screen is a popup
-- @param id Screen id
-- @return true if the screen is a popup
@@ -419,8 +430,10 @@ local function unload(screen, force)
elseif screen.factory then
log("unload() factory", screen.id)
for id, instance in pairs(screen.factory_ids) do
if go.exists(instance) then
go.delete(instance)
end
end
screen.factory_ids = nil
if screen.auto_preload and not force then
screen.loaded = false
@@ -451,8 +464,7 @@ local function preload(screen)
screen.preloading = true
if screen.proxy then
log("preload() proxy")
local missing_resources = collectionproxy.missing_resources(screen.proxy)
if #missing_resources > 0 then
if M.has_missing_resources(screen.id) then
local error_message = ("preload() collection proxy %s is missing resources"):format(tostring(screen.id))
log(error_message)
screen.preloading = false
@@ -509,9 +521,13 @@ local function load(screen)
msg.post(screen.proxy, MSG_ENABLE)
elseif screen.factory then
screen.factory_ids = collectionfactory.create(screen.factory)
if screen.transition_id then
screen.transition_url = screen.factory_ids[screen.transition_id]
end
if screen.focus_id then
screen.focus_url = screen.factory_ids[screen.focus_id]
end
end
screen.loaded = true
screen.preloaded = false
return true
@@ -909,7 +925,7 @@ function M.hide(id, cb)
log("hide() you can only hide the screen at the top of the stack", id)
return false
end
return M.back(id, cb)
return M.back(nil, nil, cb)
else
log("hide() queuing action", id)
queue_action(function(action_done, action_error)
@@ -971,17 +987,6 @@ end
-- @param cb (function) - Optional callback to invoke when the previous screen is visible again
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()
@@ -1127,6 +1132,20 @@ function M.preload(id, options, cb)
return true -- return true for legacy reasons (before queue existed)
end
--- Check if a screen has missing resources, always returns false for factory
-- @param id (string|hash) - Id of the screen to preload
function M.has_missing_resources(id)
assert(id, "You must provide a screen 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
local missing_resources = collectionproxy.missing_resources(screen.proxy)
return #missing_resources > 0
end
return false
end
--- Unload a preloaded monarch screen
-- @param id (string|hash) - Id of the screen to unload
@@ -1178,8 +1197,8 @@ end
-- @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"
if not M.is_loaded(id) then
return false, "Unable to post message to screen if it isn't loaded"
end
assert(message_id, "You must provide a message_id")
@@ -1331,24 +1350,36 @@ 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]
local t = type(fn_or_url)
if t == "function" then
screen.receiver_fn = fn_or_url
screen.receiver_url = msg.url()
screen.receiver_fn = fn
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 empty_hash = hash("")
local function url_to_key(url)
return (url.socket or hash("")) .. (url.path or hash("")) .. (url.fragment or hash(""))
return (url.socket or empty_hash) .. (url.path or empty_hash) .. (url.fragment or empty_hash)
end

2
test.settings Normal file
View File

@@ -0,0 +1,2 @@
[bootstrap]
main_collection = /test/test.collectionc

View File

@@ -64,5 +64,17 @@ function M.last(url)
return messages[#messages]
end
function M.filter(url, fn)
local t = {}
local messages = M.messages(url)
for i=1,#messages do
local message = messages[i]
if fn(message) then
t[#t + 1] = message
end
end
return t
end
return M

View File

@@ -155,6 +155,17 @@ return function()
assert(wait_until_visible(POPUP1))
end)
it("should be able to tell if a screen is loaded or not", function()
assert(not monarch.is_loaded(SCREEN1))
monarch.show(SCREEN1)
assert(wait_until_visible(SCREEN1))
assert(monarch.is_loaded(SCREEN1))
monarch.hide(SCREEN1)
assert(wait_until_hidden(SCREEN1))
assert(not monarch.is_loaded(SCREEN1))
end)
it("should be able to show a screen without adding it to the stack", function()
monarch.show(BACKGROUND, { no_stack = true })
assert(wait_until_visible(BACKGROUND), "Background was never shown")
@@ -407,43 +418,37 @@ return function()
monarch.show(SCREEN1)
assert(wait_until_not_busy())
assert(mock_msg.messages(URL1)[1].message_id == monarch.SCREEN_TRANSITION_IN_STARTED)
assert(mock_msg.messages(URL1)[1].message.screen == SCREEN1)
assert(mock_msg.messages(URL2)[1].message_id == monarch.SCREEN_TRANSITION_IN_STARTED)
assert(mock_msg.messages(URL2)[1].message.screen == SCREEN1)
assert(mock_msg.messages(URL1)[2].message_id == monarch.SCREEN_TRANSITION_IN_FINISHED)
assert(mock_msg.messages(URL1)[2].message.screen == SCREEN1)
assert(mock_msg.messages(URL2)[2].message_id == monarch.SCREEN_TRANSITION_IN_FINISHED)
assert(mock_msg.messages(URL2)[2].message.screen == SCREEN1)
monarch.remove_listener(URL2)
monarch.show(SCREEN2)
assert(wait_until_not_busy())
assert(#mock_msg.messages(URL1) == 6)
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_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)
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_IN_STARTED)
assert(mock_msg.messages(URL1)[7].message.screen == SCREEN1)
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)
local messages = mock_msg.filter(URL1, function(m)
return m.message.screen == SCREEN1
end)
assert(messages[1].message_id == monarch.SCREEN_TRANSITION_IN_STARTED)
assert(messages[2].message_id == monarch.SCREEN_TRANSITION_IN_FINISHED)
assert(messages[3].message_id == monarch.SCREEN_TRANSITION_OUT_STARTED)
assert(messages[4].message_id == monarch.SCREEN_TRANSITION_OUT_FINISHED)
assert(messages[5].message_id == monarch.SCREEN_TRANSITION_IN_STARTED)
assert(messages[6].message_id == monarch.SCREEN_TRANSITION_IN_FINISHED)
messages = mock_msg.filter(URL2, function(m)
return m.message.screen == SCREEN1
end)
assert(messages[1].message_id == monarch.SCREEN_TRANSITION_IN_STARTED)
assert(messages[2].message_id == monarch.SCREEN_TRANSITION_IN_FINISHED)
messages = mock_msg.filter(URL1, function(m)
return m.message.screen == SCREEN2
end)
assert(messages[1].message_id == monarch.SCREEN_TRANSITION_IN_STARTED)
assert(messages[2].message_id == monarch.SCREEN_TRANSITION_IN_FINISHED)
assert(messages[3].message_id == monarch.SCREEN_TRANSITION_OUT_STARTED)
assert(messages[4].message_id == monarch.SCREEN_TRANSITION_OUT_FINISHED)
end)
it("should be able to show a screen even while it is preloading", function()