mirror of
https://github.com/britzl/monarch.git
synced 2025-11-27 19:30:54 +01:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1b3b16c355 | ||
|
|
6529147e18 | ||
|
|
7aa3b9a7ef | ||
|
|
e6615e2888 | ||
|
|
ccd2b4a239 |
34
.test/run.sh
Executable file
34
.test/run.sh
Executable file
@@ -0,0 +1,34 @@
|
|||||||
|
|
||||||
|
if [ $# -eq 0 ]; then
|
||||||
|
PLATFORM="x86_64-linux"
|
||||||
|
else
|
||||||
|
PLATFORM="$1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "${PLATFORM}"
|
||||||
|
|
||||||
|
# {"version": "1.2.89", "sha1": "5ca3dd134cc960c35ecefe12f6dc81a48f212d40"}
|
||||||
|
SHA1=$(curl -s http://d.defold.com/stable/info.json | sed 's/.*sha1": "\(.*\)".*/\1/')
|
||||||
|
echo "Using Defold dmengine_headless version ${SHA1}"
|
||||||
|
|
||||||
|
#DMENGINE_URL="http://d.defold.com/archive/${SHA1}/engine/linux/dmengine_headless"
|
||||||
|
DMENGINE_URL="http://d.defold.com/archive/${SHA1}/engine/${PLATFORM}/dmengine_headless"
|
||||||
|
BOB_URL="http://d.defold.com/archive/${SHA1}/bob/bob.jar"
|
||||||
|
|
||||||
|
echo "Downloading ${DMENGINE_URL}"
|
||||||
|
curl -o dmengine_headless ${DMENGINE_URL}
|
||||||
|
chmod +x dmengine_headless
|
||||||
|
|
||||||
|
echo "Downloading ${BOB_URL}"
|
||||||
|
curl -o bob.jar ${BOB_URL}
|
||||||
|
|
||||||
|
if [ -n "${DEFOLD_AUTH}" ] && [ -n "${DEFOLD_USER}" ]; then
|
||||||
|
echo "Running bob.jar - resolving dependencies"
|
||||||
|
java -jar bob.jar --auth "${DEFOLD_AUTH}" --email "${DEFOLD_USER}" resolve
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Running bob.jar - building"
|
||||||
|
java -jar bob.jar --debug build
|
||||||
|
|
||||||
|
echo "Starting dmengine_headless"
|
||||||
|
./dmengine_headless
|
||||||
27
.travis.yml
Normal file
27
.travis.yml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
sudo: required
|
||||||
|
|
||||||
|
script:
|
||||||
|
- sudo unlink /usr/bin/gcc && sudo ln -s /usr/bin/gcc-5 /usr/bin/gcc
|
||||||
|
- gcc --version
|
||||||
|
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources:
|
||||||
|
- ubuntu-toolchain-r-test
|
||||||
|
packages:
|
||||||
|
- gcc-5
|
||||||
|
- g++-5
|
||||||
|
|
||||||
|
language: java
|
||||||
|
|
||||||
|
jdk:
|
||||||
|
- oraclejdk8
|
||||||
|
|
||||||
|
#DEFOLD_AUTH=auth token
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
- secure: "1rVLsDcb7dFdgyB9D1JQDr4JhWSosoMvgYgrqZNPxJ/Du3qtY3bk6dgQim+g2fDMQpDOPCQ/EhmhtrLJrIgBhhvOcsrVKT8gl9ZnATw5tHGI6XTw3eod8WgsU8owlc7CaT3XaUgwVshmW3oB/257SDf6kHwsCv/gAJuCEL5RZp76BhTWsfyeDCgz5XXgWx4a21tcIWz96jxEsrYQKLLV2ne55CxU5Hw9IMU7Ig7pkGoYCf1g+iUEA39NC8nIrQibUoJj3yNB2u3ZFwGf2LuDjjkSIsyYWn1LzA2fQYw5uAcjiQ/aDkj6sAEvwrWsIsJhOon5cQBFIU6cIIN2oK3A7BA0zJj0EsTFPUMIeryyoqiuLUDoIvHD/eEqouNduP6Kml02Ql0pDZnjDy/+nzp2e7VA5Sd9Xg1XKd1mmHKx4nc2U+IcIDZWAerFKcqQqeZSwzz5igv07w5zYZ99KCSBMH2K/2H/CNekHa6SQQ29mC8D3lDXOfwEq3fAhsabgUGe2uAgUY1nKwJBKEi7r+KEROBr5ydkWenzbCXv3GNNsuCHKpNFuoZv3QMyjUjlPBxZVndNLSv85juhkBx6wXAh8CxTt78Y8GV0xI8oazSM065gpDmENGVqyO1bUn2CZF8YRC4MLfHK+245QN82ui+YOqVudTX8RGWnX0GFUncjaRQ="
|
||||||
|
- DEFOLD_USER=bjorn.ritzl@king.com
|
||||||
|
|
||||||
|
script:
|
||||||
|
- "./.test/run.sh"
|
||||||
@@ -6,6 +6,8 @@ You can use Monarch in your own project by adding this project as a [Defold libr
|
|||||||
|
|
||||||
https://github.com/britzl/monarch/archive/master.zip
|
https://github.com/britzl/monarch/archive/master.zip
|
||||||
|
|
||||||
|
Or point to the ZIP file of a [specific release](https://github.com/britzl/monarch/releases).
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
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.
|
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.
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
name: "main"
|
name: "example"
|
||||||
scale_along_z: 0
|
scale_along_z: 0
|
||||||
embedded_instances {
|
embedded_instances {
|
||||||
id: "menu"
|
id: "menu"
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
[project]
|
[project]
|
||||||
title = Monarch
|
title = Monarch
|
||||||
version = 0.9
|
version = 0.9
|
||||||
|
dependencies = https://github.com/britzl/deftest/archive/1.2.1.zip
|
||||||
|
|
||||||
[bootstrap]
|
[bootstrap]
|
||||||
main_collection = /example/main.collectionc
|
main_collection = /test/test.collectionc
|
||||||
|
|
||||||
[input]
|
[input]
|
||||||
game_binding = /input/game.input_bindingc
|
game_binding = /input/game.input_bindingc
|
||||||
|
|||||||
@@ -43,7 +43,11 @@ local function screen_from_script()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function in_stack(id)
|
|
||||||
|
--- Check if a screen exists in the current screen stack
|
||||||
|
-- @param id
|
||||||
|
-- @return true of the screen is in the stack
|
||||||
|
function M.in_stack(id)
|
||||||
for i = 1, #stack do
|
for i = 1, #stack do
|
||||||
if stack[i].id == id then
|
if stack[i].id == id then
|
||||||
return true
|
return true
|
||||||
@@ -52,8 +56,33 @@ local function in_stack(id)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Check if a screen is at the top of the stack
|
||||||
|
-- (primarily used for unit tests, but could have a usecase outside tests)
|
||||||
|
-- @param id
|
||||||
|
-- @return true if the screen is at the top of the stack
|
||||||
|
function M.is_top(id)
|
||||||
|
local top = stack[#stack]
|
||||||
|
return top and top.id == id or false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Register a new screen
|
||||||
|
-- This is done automatically by the screen.script. It is expected that the
|
||||||
|
-- caller of this function is a script component attached to the same game
|
||||||
|
-- object as the proxy. This is required since monarch will acquire and
|
||||||
|
-- release input focus of the game object where the proxy is attached.
|
||||||
|
-- @param id Unique id of the screen
|
||||||
|
-- @param proxy URL to the collection proxy containing the screen
|
||||||
|
-- @param popup true the screen is a popup
|
||||||
|
-- @param transition_url Optional URL to a script that is
|
||||||
|
-- responsible for the screen transitions
|
||||||
|
-- @param focus_url Optional URL to a script that is to be notified of
|
||||||
|
-- focus lost/gained events
|
||||||
function M.register(id, proxy, popup, transition_url, focus_url)
|
function M.register(id, proxy, popup, transition_url, focus_url)
|
||||||
assert(not screens[id], ("There is already a screen registered with id %s"):format(tostring(id)))
|
assert(not screens[id], ("There is already a screen registered with id %s"):format(tostring(id)))
|
||||||
|
assert(proxy, "You must provide a collection proxy URL")
|
||||||
|
local url = msg.url(proxy)
|
||||||
screens[id] = {
|
screens[id] = {
|
||||||
id = id,
|
id = id,
|
||||||
proxy = proxy,
|
proxy = proxy,
|
||||||
@@ -64,6 +93,9 @@ function M.register(id, proxy, popup, transition_url, focus_url)
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Unregister a screen
|
||||||
|
-- This is done automatically by the screen.script
|
||||||
|
-- @param id Id of the screen to unregister
|
||||||
function M.unregister(id)
|
function M.unregister(id)
|
||||||
assert(screens[id], ("There is no screen registered with id %s"):format(tostring(id)))
|
assert(screens[id], ("There is no screen registered with id %s"):format(tostring(id)))
|
||||||
screens[id] = nil
|
screens[id] = nil
|
||||||
@@ -191,10 +223,10 @@ end
|
|||||||
-- @param id Id of the screen to show
|
-- @param id Id of the screen to show
|
||||||
-- @param options Table with options when showing the screen (can be nil). Valid values:
|
-- @param options Table with options when showing the screen (can be nil). Valid values:
|
||||||
-- * clear - Set to true if the stack should be cleared down to an existing instance of the screen
|
-- * clear - Set to true if the stack should be cleared down to an existing instance of the screen
|
||||||
-- * reload - Set to true if screen should be reloaded if it already exists in the stack and is loaded
|
-- * reload - Set to true if screen should be reloaded if it already exists in the stack and is loaded.
|
||||||
-- This would be the case if doing a show() from a popup on the screen just below the popup.
|
-- This would be the case if doing a show() from a popup on the screen just below the popup.
|
||||||
-- @param data Optional data to set on the screen. Can be retrieved by the data() function
|
-- @param data Optional data to set on the screen. Can be retrieved by the data() function
|
||||||
-- @ param cb Optional callback to invoke when screen is shown
|
-- @param cb Optional callback to invoke when screen is shown
|
||||||
function M.show(id, options, data, cb)
|
function M.show(id, options, data, cb)
|
||||||
assert(id, "You must provide a screen id")
|
assert(id, "You must provide a screen id")
|
||||||
assert(screens[id], ("There is no screen registered with id %s"):format(tostring(id)))
|
assert(screens[id], ("There is no screen registered with id %s"):format(tostring(id)))
|
||||||
@@ -224,7 +256,7 @@ function M.show(id, options, data, cb)
|
|||||||
-- to remove every screen on the stack up until and
|
-- to remove every screen on the stack up until and
|
||||||
-- including the screen itself
|
-- including the screen itself
|
||||||
if options and options.clear then
|
if options and options.clear then
|
||||||
while in_stack(id) do
|
while M.in_stack(id) do
|
||||||
table.remove(stack)
|
table.remove(stack)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -244,7 +276,7 @@ function M.back(data, cb)
|
|||||||
back_out(screen, top, cb)
|
back_out(screen, top, cb)
|
||||||
if top then
|
if top then
|
||||||
if data then
|
if data then
|
||||||
screen.data = data
|
top.data = data
|
||||||
end
|
end
|
||||||
back_in(top, screen)
|
back_in(top, screen)
|
||||||
end
|
end
|
||||||
@@ -274,6 +306,18 @@ function M.on_message(message_id, message, sender)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get a list of ids for the current screen stack
|
||||||
|
-- (primarily used for unit testing, but could have uses outside testing)
|
||||||
|
-- @return Table with screen ids. First entry is at the bottom of the
|
||||||
|
-- stack and the last value is at the top (and currently visible)
|
||||||
|
function M.get_stack()
|
||||||
|
local s = {}
|
||||||
|
for k,v in pairs(stack) do
|
||||||
|
s[k] = v.id
|
||||||
|
end
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
|
||||||
function M.dump_stack()
|
function M.dump_stack()
|
||||||
local s = ""
|
local s = ""
|
||||||
for i, screen in ipairs(stack) do
|
for i, screen in ipairs(stack) do
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
local monarch = require "monarch.monarch"
|
local monarch
|
||||||
|
|
||||||
go.property("screen_proxy", msg.url("#collectionproxy"))
|
go.property("screen_proxy", msg.url("#collectionproxy"))
|
||||||
go.property("screen_id", hash(""))
|
go.property("screen_id", hash(""))
|
||||||
@@ -8,6 +8,7 @@ go.property("focus_url", msg.url())
|
|||||||
|
|
||||||
|
|
||||||
function init(self)
|
function init(self)
|
||||||
|
monarch = require "monarch.monarch"
|
||||||
monarch.register(self.screen_id, self.screen_proxy, self.popup, self.transition_url, self.focus_url)
|
monarch.register(self.screen_id, self.screen_proxy, self.popup, self.transition_url, self.focus_url)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -27,7 +28,7 @@ function on_message(self, message_id, message, sender)
|
|||||||
or message_id == monarch.TRANSITION.BACK_IN
|
or message_id == monarch.TRANSITION.BACK_IN
|
||||||
or message_id == monarch.TRANSITION.BACK_OUT then
|
or message_id == monarch.TRANSITION.BACK_OUT then
|
||||||
msg.post(sender, monarch.TRANSITION.DONE)
|
msg.post(sender, monarch.TRANSITION.DONE)
|
||||||
else
|
else
|
||||||
monarch.on_message(message_id, message, sender)
|
monarch.on_message(message_id, message, sender)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|||||||
48
test/cowait.lua
Normal file
48
test/cowait.lua
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
local M = {}
|
||||||
|
|
||||||
|
|
||||||
|
local instances = {}
|
||||||
|
|
||||||
|
local function create(fn)
|
||||||
|
local instance = {
|
||||||
|
co = coroutine.running(),
|
||||||
|
fn = fn,
|
||||||
|
}
|
||||||
|
table.insert(instances, instance)
|
||||||
|
coroutine.yield(instance.co)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function M.seconds(amount)
|
||||||
|
local time = socket.gettime() + amount
|
||||||
|
create(function()
|
||||||
|
return socket.gettime() >= time
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function M.eval(fn)
|
||||||
|
create(fn)
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.update()
|
||||||
|
for k,instance in pairs(instances) do
|
||||||
|
if instance.fn() then
|
||||||
|
instances[k] = nil
|
||||||
|
coroutine.resume(instance.co)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return setmetatable(M, {
|
||||||
|
__call = function(self, arg1, ...)
|
||||||
|
if type(arg1) == "number" then
|
||||||
|
return M.seconds(arg1, ...)
|
||||||
|
elseif type(arg1) == "function" then
|
||||||
|
return M.eval(arg1, ...)
|
||||||
|
else
|
||||||
|
error("Unknown argument type")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
5
test/cowait.script
Normal file
5
test/cowait.script
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
local cowait = require "test.cowait"
|
||||||
|
|
||||||
|
function update(self, dt)
|
||||||
|
cowait.update()
|
||||||
|
end
|
||||||
37
test/data/screen1.collection
Normal file
37
test/data/screen1.collection
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
name: "screen1"
|
||||||
|
scale_along_z: 0
|
||||||
|
embedded_instances {
|
||||||
|
id: "go"
|
||||||
|
data: "components {\n"
|
||||||
|
" id: \"screen1\"\n"
|
||||||
|
" component: \"/test/data/screen1.gui\"\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
|
||||||
|
}
|
||||||
|
}
|
||||||
131
test/data/screen1.gui
Normal file
131
test/data/screen1.gui
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
script: "/test/data/screen1.gui_script"
|
||||||
|
fonts {
|
||||||
|
name: "example"
|
||||||
|
font: "/assets/example.font"
|
||||||
|
}
|
||||||
|
background_color {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 0.0
|
||||||
|
}
|
||||||
|
nodes {
|
||||||
|
position {
|
||||||
|
x: 320.0
|
||||||
|
y: 568.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
size {
|
||||||
|
x: 200.0
|
||||||
|
y: 100.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
color {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
type: TYPE_BOX
|
||||||
|
blend_mode: BLEND_MODE_ALPHA
|
||||||
|
texture: ""
|
||||||
|
id: "box"
|
||||||
|
xanchor: XANCHOR_NONE
|
||||||
|
yanchor: YANCHOR_NONE
|
||||||
|
pivot: PIVOT_CENTER
|
||||||
|
adjust_mode: ADJUST_MODE_FIT
|
||||||
|
layer: ""
|
||||||
|
inherit_alpha: true
|
||||||
|
slice9 {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 0.0
|
||||||
|
}
|
||||||
|
clipping_mode: CLIPPING_MODE_NONE
|
||||||
|
clipping_visible: true
|
||||||
|
clipping_inverted: false
|
||||||
|
alpha: 1.0
|
||||||
|
template_node_child: false
|
||||||
|
size_mode: SIZE_MODE_AUTO
|
||||||
|
}
|
||||||
|
nodes {
|
||||||
|
position {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
size {
|
||||||
|
x: 200.0
|
||||||
|
y: 100.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
color {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
type: TYPE_TEXT
|
||||||
|
blend_mode: BLEND_MODE_ALPHA
|
||||||
|
text: "1"
|
||||||
|
font: "example"
|
||||||
|
id: "text"
|
||||||
|
xanchor: XANCHOR_NONE
|
||||||
|
yanchor: YANCHOR_NONE
|
||||||
|
pivot: PIVOT_CENTER
|
||||||
|
outline {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
shadow {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
adjust_mode: ADJUST_MODE_FIT
|
||||||
|
line_break: false
|
||||||
|
parent: "box"
|
||||||
|
layer: ""
|
||||||
|
inherit_alpha: true
|
||||||
|
alpha: 1.0
|
||||||
|
outline_alpha: 1.0
|
||||||
|
shadow_alpha: 1.0
|
||||||
|
template_node_child: false
|
||||||
|
text_leading: 1.0
|
||||||
|
text_tracking: 0.0
|
||||||
|
}
|
||||||
|
material: "/builtins/materials/gui.material"
|
||||||
|
adjust_reference: ADJUST_REFERENCE_PARENT
|
||||||
|
max_nodes: 512
|
||||||
12
test/data/screen1.gui_script
Normal file
12
test/data/screen1.gui_script
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
function init(self)
|
||||||
|
print("init - screen1")
|
||||||
|
end
|
||||||
|
|
||||||
|
function final(self)
|
||||||
|
print("final - screen1")
|
||||||
|
end
|
||||||
|
|
||||||
|
function on_message(self, message_id, message, sender)
|
||||||
|
-- Add message-handling code here
|
||||||
|
-- Remove this function if not needed
|
||||||
|
end
|
||||||
37
test/data/screen2.collection
Normal file
37
test/data/screen2.collection
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
name: "screen2"
|
||||||
|
scale_along_z: 0
|
||||||
|
embedded_instances {
|
||||||
|
id: "go"
|
||||||
|
data: "components {\n"
|
||||||
|
" id: \"screen2\"\n"
|
||||||
|
" component: \"/test/data/screen2.gui\"\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
|
||||||
|
}
|
||||||
|
}
|
||||||
131
test/data/screen2.gui
Normal file
131
test/data/screen2.gui
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
script: "/test/data/screen2.gui_script"
|
||||||
|
fonts {
|
||||||
|
name: "example"
|
||||||
|
font: "/assets/example.font"
|
||||||
|
}
|
||||||
|
background_color {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 0.0
|
||||||
|
}
|
||||||
|
nodes {
|
||||||
|
position {
|
||||||
|
x: 320.0
|
||||||
|
y: 697.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
size {
|
||||||
|
x: 200.0
|
||||||
|
y: 100.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
color {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
type: TYPE_BOX
|
||||||
|
blend_mode: BLEND_MODE_ALPHA
|
||||||
|
texture: ""
|
||||||
|
id: "box"
|
||||||
|
xanchor: XANCHOR_NONE
|
||||||
|
yanchor: YANCHOR_NONE
|
||||||
|
pivot: PIVOT_CENTER
|
||||||
|
adjust_mode: ADJUST_MODE_FIT
|
||||||
|
layer: ""
|
||||||
|
inherit_alpha: true
|
||||||
|
slice9 {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 0.0
|
||||||
|
}
|
||||||
|
clipping_mode: CLIPPING_MODE_NONE
|
||||||
|
clipping_visible: true
|
||||||
|
clipping_inverted: false
|
||||||
|
alpha: 1.0
|
||||||
|
template_node_child: false
|
||||||
|
size_mode: SIZE_MODE_AUTO
|
||||||
|
}
|
||||||
|
nodes {
|
||||||
|
position {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
size {
|
||||||
|
x: 200.0
|
||||||
|
y: 100.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
color {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
type: TYPE_TEXT
|
||||||
|
blend_mode: BLEND_MODE_ALPHA
|
||||||
|
text: "2"
|
||||||
|
font: "example"
|
||||||
|
id: "text"
|
||||||
|
xanchor: XANCHOR_NONE
|
||||||
|
yanchor: YANCHOR_NONE
|
||||||
|
pivot: PIVOT_CENTER
|
||||||
|
outline {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
shadow {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
adjust_mode: ADJUST_MODE_FIT
|
||||||
|
line_break: false
|
||||||
|
parent: "box"
|
||||||
|
layer: ""
|
||||||
|
inherit_alpha: true
|
||||||
|
alpha: 1.0
|
||||||
|
outline_alpha: 1.0
|
||||||
|
shadow_alpha: 1.0
|
||||||
|
template_node_child: false
|
||||||
|
text_leading: 1.0
|
||||||
|
text_tracking: 0.0
|
||||||
|
}
|
||||||
|
material: "/builtins/materials/gui.material"
|
||||||
|
adjust_reference: ADJUST_REFERENCE_PARENT
|
||||||
|
max_nodes: 512
|
||||||
12
test/data/screen2.gui_script
Normal file
12
test/data/screen2.gui_script
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
function init(self)
|
||||||
|
print("init - screen2")
|
||||||
|
end
|
||||||
|
|
||||||
|
function final(self)
|
||||||
|
print("final - screen2")
|
||||||
|
end
|
||||||
|
|
||||||
|
function on_message(self, message_id, message, sender)
|
||||||
|
-- Add message-handling code here
|
||||||
|
-- Remove this function if not needed
|
||||||
|
end
|
||||||
118
test/data/screens.collection
Normal file
118
test/data/screens.collection
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
name: "screens"
|
||||||
|
scale_along_z: 0
|
||||||
|
embedded_instances {
|
||||||
|
id: "screen1"
|
||||||
|
data: "components {\n"
|
||||||
|
" id: \"screen\"\n"
|
||||||
|
" component: \"/monarch/screen.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"
|
||||||
|
" properties {\n"
|
||||||
|
" id: \"screen_id\"\n"
|
||||||
|
" value: \"screen1\"\n"
|
||||||
|
" type: PROPERTY_TYPE_HASH\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
"embedded_components {\n"
|
||||||
|
" id: \"collectionproxy\"\n"
|
||||||
|
" type: \"collectionproxy\"\n"
|
||||||
|
" data: \"collection: \\\"/test/data/screen1.collection\\\"\\n"
|
||||||
|
"exclude: false\\n"
|
||||||
|
"\"\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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
embedded_instances {
|
||||||
|
id: "screen2"
|
||||||
|
data: "components {\n"
|
||||||
|
" id: \"screen\"\n"
|
||||||
|
" component: \"/monarch/screen.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"
|
||||||
|
" properties {\n"
|
||||||
|
" id: \"screen_id\"\n"
|
||||||
|
" value: \"screen2\"\n"
|
||||||
|
" type: PROPERTY_TYPE_HASH\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
"embedded_components {\n"
|
||||||
|
" id: \"collectionproxy\"\n"
|
||||||
|
" type: \"collectionproxy\"\n"
|
||||||
|
" data: \"collection: \\\"/test/data/screen2.collection\\\"\\n"
|
||||||
|
"exclude: false\\n"
|
||||||
|
"\"\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
|
||||||
|
}
|
||||||
|
}
|
||||||
70
test/test.collection
Normal file
70
test/test.collection
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
name: "test"
|
||||||
|
scale_along_z: 0
|
||||||
|
embedded_instances {
|
||||||
|
id: "go"
|
||||||
|
data: "components {\n"
|
||||||
|
" id: \"test\"\n"
|
||||||
|
" component: \"/test/test.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"
|
||||||
|
"components {\n"
|
||||||
|
" id: \"cowait\"\n"
|
||||||
|
" component: \"/test/cowait.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"
|
||||||
|
"embedded_components {\n"
|
||||||
|
" id: \"screensfactory\"\n"
|
||||||
|
" type: \"collectionfactory\"\n"
|
||||||
|
" data: \"prototype: \\\"/test/data/screens.collection\\\"\\n"
|
||||||
|
"load_dynamically: false\\n"
|
||||||
|
"\"\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
|
||||||
|
}
|
||||||
|
}
|
||||||
9
test/test.script
Normal file
9
test/test.script
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
local deftest = require "deftest.deftest"
|
||||||
|
|
||||||
|
local test_monarch = require "test.test_monarch"
|
||||||
|
|
||||||
|
|
||||||
|
function init(self)
|
||||||
|
deftest.add(test_monarch)
|
||||||
|
deftest.run()
|
||||||
|
end
|
||||||
135
test/test_monarch.lua
Normal file
135
test/test_monarch.lua
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
local cowait = require "test.cowait"
|
||||||
|
local monarch = require "monarch.monarch"
|
||||||
|
|
||||||
|
local SCREEN1 = hash("screen1")
|
||||||
|
local SCREEN2 = hash("screen2")
|
||||||
|
local FOOBAR = hash("foobar")
|
||||||
|
|
||||||
|
return function()
|
||||||
|
|
||||||
|
local screens_instances = {}
|
||||||
|
|
||||||
|
local function is_shown(screen_id)
|
||||||
|
return monarch.is_top(screen_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function is_hidden(screen_id)
|
||||||
|
return not monarch.is_top(screen_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function wait_timeout(fn, ...)
|
||||||
|
local args = { ... }
|
||||||
|
local time = socket.gettime()
|
||||||
|
cowait(function()
|
||||||
|
return fn(unpack(args)) or socket.gettime() > time + 5
|
||||||
|
end)
|
||||||
|
return fn(...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function wait_until_shown(screen_id)
|
||||||
|
return wait_timeout(is_shown, screen_id)
|
||||||
|
end
|
||||||
|
local function wait_until_hidden(screen_id)
|
||||||
|
return wait_timeout(is_hidden, screen_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function assert_stack(expected_screens)
|
||||||
|
local actual_screens = monarch.get_stack()
|
||||||
|
if #actual_screens ~= #expected_screens then
|
||||||
|
error("Stack length mismatch", 2)
|
||||||
|
end
|
||||||
|
for i=1,#actual_screens do
|
||||||
|
if actual_screens[i] ~= expected_screens[i] then
|
||||||
|
error("Stack content not matching", 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
describe("monarch", function()
|
||||||
|
before(function()
|
||||||
|
monarch = require "monarch.monarch"
|
||||||
|
screens_instances = collectionfactory.create("#screensfactory")
|
||||||
|
end)
|
||||||
|
|
||||||
|
after(function()
|
||||||
|
package.loaded["monarch.monarch"] = nil
|
||||||
|
for id,instance_id in pairs(screens_instances) do
|
||||||
|
go.delete(instance_id)
|
||||||
|
end
|
||||||
|
cowait(0.1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
it("should be able to tell if a screen exists", function()
|
||||||
|
assert(monarch.screen_exists(SCREEN1))
|
||||||
|
assert(not monarch.screen_exists(hash("foobar")))
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
it("should be able to show screens and go back to previous screens", function()
|
||||||
|
monarch.show(SCREEN1)
|
||||||
|
assert(wait_until_shown(SCREEN1), "Screen1 was never shown")
|
||||||
|
assert_stack({ SCREEN1 })
|
||||||
|
|
||||||
|
monarch.show(SCREEN2)
|
||||||
|
assert(wait_until_hidden(SCREEN1), "Screen1 was never hidden")
|
||||||
|
assert(wait_until_shown(SCREEN2), "Screen2 was never shown")
|
||||||
|
assert_stack({ SCREEN1, SCREEN2 })
|
||||||
|
|
||||||
|
monarch.back()
|
||||||
|
assert(wait_until_hidden(SCREEN2), "Screen2 was never hidden")
|
||||||
|
assert(wait_until_shown(SCREEN1), "Screen1 was never shown")
|
||||||
|
assert_stack({ SCREEN1 })
|
||||||
|
|
||||||
|
monarch.back()
|
||||||
|
assert(wait_until_hidden(SCREEN1), "Screen1 was never hidden")
|
||||||
|
assert_stack({ })
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
it("should be able to pass data to a screen when showning it or going back to it", function()
|
||||||
|
local data1 = { foo = "bar" }
|
||||||
|
monarch.show(SCREEN1, nil, data1)
|
||||||
|
assert(wait_until_shown(SCREEN1), "Screen1 was never shown")
|
||||||
|
|
||||||
|
local data2 = { boo = "car" }
|
||||||
|
monarch.show(SCREEN2, nil, data2)
|
||||||
|
assert(wait_until_shown(SCREEN2), "Screen2 was never shown")
|
||||||
|
|
||||||
|
assert(monarch.data(SCREEN1) == data1, "Expected data on screen1 doesn't match actual data")
|
||||||
|
assert(monarch.data(SCREEN2) == data2, "Expected data on screen2 doesn't match actual data")
|
||||||
|
|
||||||
|
local data_back = { going = "back" }
|
||||||
|
monarch.back(data_back)
|
||||||
|
assert_stack({ SCREEN1 })
|
||||||
|
|
||||||
|
assert(monarch.data(SCREEN1) == data_back, "Expected data on screen1 doesn't match actual data")
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
it("should be able to show the same screen twice", function()
|
||||||
|
monarch.show(SCREEN1)
|
||||||
|
assert(wait_until_shown(SCREEN1), "Screen1 was never shown")
|
||||||
|
assert_stack({ SCREEN1 })
|
||||||
|
monarch.show(SCREEN1)
|
||||||
|
assert(wait_until_shown(SCREEN1), "Screen1 was never shown")
|
||||||
|
assert_stack({ SCREEN1, SCREEN1 })
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
it("should be able to clear the stack if trying to show the same screen twice", function()
|
||||||
|
monarch.show(SCREEN1)
|
||||||
|
assert(wait_until_shown(SCREEN1), "Screen1 was never shown")
|
||||||
|
assert_stack({ SCREEN1 })
|
||||||
|
monarch.show(SCREEN2)
|
||||||
|
assert(wait_until_shown(SCREEN2), "Screen2 was never shown")
|
||||||
|
assert_stack({ SCREEN1, SCREEN2 })
|
||||||
|
monarch.show(SCREEN1, { clear = true })
|
||||||
|
assert(wait_until_shown(SCREEN1), "Screen1 was never shown")
|
||||||
|
assert_stack({ SCREEN1 })
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
end)
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user