mirror of
https://github.com/britzl/monarch.git
synced 2025-11-26 19:00:53 +01:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b13adcfb62 | ||
|
|
3947e86169 | ||
|
|
e570eac40b | ||
|
|
d1cf8281c9 | ||
|
|
091fab0c7f | ||
|
|
01196ad350 | ||
|
|
4231b0b89c | ||
|
|
c2239d67e5 | ||
|
|
9765daa2a9 | ||
|
|
7b2b269c72 | ||
|
|
cf75bef8da | ||
|
|
66b1f7ca2e | ||
|
|
0fdfb6fd11 | ||
|
|
6fbec4ab8f | ||
|
|
ffc148b4bf |
60
CHANGELOG.md
Normal file
60
CHANGELOG.md
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
## Monarch 2.8.0 [britzl released 2018-06-10]
|
||||||
|
NEW: Prevent show/hide operations while busy showing/hiding another screen
|
||||||
|
FIX: Make sure to properly finish active transitions when layout changes
|
||||||
|
|
||||||
|
## Monarch 2.7.0 [britzl released 2018-06-04]
|
||||||
|
NEW: Added monarch.top([offset]) and monarch.bottom([offset]) to get screen id of top and bottom screens (w. optional offset)
|
||||||
|
NEW: Transition messages now contain `next_screen` or `previous_screen`
|
||||||
|
|
||||||
|
## Monarch 2.6.1 [britzl released 2018-06-04]
|
||||||
|
FIX: Check if screen has already been preloaded before trying to preload it again (the callback will still be invoked).
|
||||||
|
|
||||||
|
## Monarch 2.6.0 [britzl released 2018-06-03]
|
||||||
|
NEW: monarch.preload() to load but not show a screen. Useful for content heavy screens that you wish to show without delay.
|
||||||
|
|
||||||
|
## Monarch 2.5.0 [britzl released 2018-06-01]
|
||||||
|
NEW: Transitions will send a `transition_done` message to the creator of the transition to notify that the transition has finished. The `message` will contain which transition that was finished.
|
||||||
|
|
||||||
|
## Monarch 2.4.0 [britzl released 2018-05-26]
|
||||||
|
NEW: Screen transitions are remembered so that they can be replayed when the screen layout changes.
|
||||||
|
|
||||||
|
## Monarch 2.3.0 [britzl released 2018-03-24]
|
||||||
|
CHANGE: The functions in monarch.lua that previously only accepted a hash as screen id now also accepts strings (and does the conversion internally)
|
||||||
|
|
||||||
|
## Monarch 2.2.0 [britzl released 2018-03-19]
|
||||||
|
NEW: Transitions now handle layout changes (via `layout_changed` message)
|
||||||
|
NEW: Transitions can now be notified of changes in window size using transition.window_resize(width, height)
|
||||||
|
|
||||||
|
## Monarch 2.1 [britzl released 2017-12-27]
|
||||||
|
NEW: Added Popup on Popup flag that allows a popup to be shown on top of another popup
|
||||||
|
|
||||||
|
## Monarch 2.0 [britzl released 2017-12-08]
|
||||||
|
BREAKING CHANGE: If you are using custom screen transitions (ie your own transition functions) you need to make a change to the function. The previous function signature was ```(node, to, easing, duration, delay, url)``` where ```url``` was the URL to where the ```transition_done``` message was supposed to be posted. The new function signature for a transition function is: ```(node, to, easing, duration, delay, cb)``` where ```cb``` is a function that should be invoked when the transition is completed.
|
||||||
|
|
||||||
|
FIX: Fixed issues related to screen transitions.
|
||||||
|
FIX: Code cleanup to reduce code duplication.
|
||||||
|
FIX: Improved documentation regarding transitions.
|
||||||
|
|
||||||
|
## Monarch 1.4 [britzl released 2017-12-06]
|
||||||
|
FIX: Several bugfixes for specific corner cases.
|
||||||
|
|
||||||
|
## Monarch 1.3 [britzl released 2017-12-01]
|
||||||
|
FIX: monarch.back(data, cb) set the data on the previous screen not the new current screen.
|
||||||
|
NEW: monarch.is_top(id)
|
||||||
|
NEW: monarch.get_stack()
|
||||||
|
NEW: monarch.in_stack(id)
|
||||||
|
|
||||||
|
## Monarch 1.2 [britzl released 2017-11-28]
|
||||||
|
NEW: Message id constants exposed from the Monarch module
|
||||||
|
NEW: Focus lost/gained contains id of next/previous screen
|
||||||
|
|
||||||
|
## Monarch 1.1 [britzl released 2017-11-22]
|
||||||
|
FIX: Bugfixes for transitions and state under certain circumstances
|
||||||
|
NEW: Added 'reload' option to show() command.
|
||||||
|
|
||||||
|
## Monarch 1.0 [britzl released 2017-09-28]
|
||||||
|
First public stable release
|
||||||
|
|
||||||
|
## Monarch 0.9 [britzl released 2017-09-17]
|
||||||
|
|
||||||
|
|
||||||
121
README.md
121
README.md
@@ -6,6 +6,7 @@
|
|||||||
# Monarch
|
# Monarch
|
||||||
Monarch is a screen manager for the [Defold](https://www.defold.com) game engine.
|
Monarch is a screen manager for the [Defold](https://www.defold.com) game engine.
|
||||||
|
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
You can use Monarch in your own project by adding this project as a [Defold library dependency](http://www.defold.com/manuals/libraries/). Open your game.project file and in the dependencies field under project add:
|
You can use Monarch in your own project by adding this project as a [Defold library dependency](http://www.defold.com/manuals/libraries/). Open your game.project file and in the dependencies field under project add:
|
||||||
|
|
||||||
@@ -13,9 +14,11 @@ https://github.com/britzl/monarch/archive/master.zip
|
|||||||
|
|
||||||
Or point to the ZIP file of a [specific release](https://github.com/britzl/monarch/releases).
|
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.
|
||||||
|
|
||||||
|
|
||||||
## Creating screens
|
## Creating screens
|
||||||
Monarch screens are created in individual collections and loaded through collection proxies. The recommended setup is to create one game object per screen and per game object attach a collection proxy component and an instance of the ```screen.script``` provided by Monarch. The ```screen.script``` will take care of the setup of the screen. All you need to do is to make sure that the script properties on the ```screen.script``` are correct:
|
Monarch screens are created in individual collections and loaded through collection proxies. The recommended setup is to create one game object per screen and per game object attach a collection proxy component and an instance of the ```screen.script``` provided by Monarch. The ```screen.script``` will take care of the setup of the screen. All you need to do is to make sure that the script properties on the ```screen.script``` are correct:
|
||||||
|
|
||||||
@@ -28,6 +31,7 @@ Monarch screens are created in individual collections and loaded through collect
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
## Navigating between screens
|
## Navigating between screens
|
||||||
The navigation in Monarch is based around a stack of screens. When a screen is shown it is pushed to the top of the stack. When going back to a previous screen the topmost screen on the stack is removed. Example:
|
The navigation in Monarch is based around a stack of screens. When a screen is shown it is pushed to the top of the stack. When going back to a previous screen the topmost screen on the stack is removed. Example:
|
||||||
|
|
||||||
@@ -118,8 +122,10 @@ You can add optional transitions when navigating between screens. The default be
|
|||||||
* ```transition_back_in``` (constant defined as ```monarch.TRANSITION.BACK_IN```)
|
* ```transition_back_in``` (constant defined as ```monarch.TRANSITION.BACK_IN```)
|
||||||
* ```transition_back_out``` (constant defined as ```monarch.TRANSITION.BACK_OUT```)
|
* ```transition_back_out``` (constant defined as ```monarch.TRANSITION.BACK_OUT```)
|
||||||
|
|
||||||
When a transition is completed it is up to the developer to send a ```transition_done``` (constant ```monarch.TRANSITION.DONE```) message back to the sender to indicate that the transition is completed and that Monarch can continue the navigation sequence. Monarch comes with a system for setting up transitions easily in a gui_script. Example:
|
When a transition is completed it is up to the developer to send a ```transition_done``` (constant ```monarch.TRANSITION.DONE```) message back to the sender to indicate that the transition is completed and that Monarch can continue the navigation sequence.
|
||||||
|
|
||||||
|
|
||||||
|
### Predefined transitions
|
||||||
Monarch comes with a system for setting up transitions easily in a gui_script using the ```monarch.transitions.gui``` module. Example:
|
Monarch comes with a system for setting up transitions easily in a gui_script using the ```monarch.transitions.gui``` module. Example:
|
||||||
|
|
||||||
local transitions = require "monarch.transitions.gui"
|
local transitions = require "monarch.transitions.gui"
|
||||||
@@ -144,7 +150,6 @@ Monarch comes with a system for setting up transitions easily in a gui_script us
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
### Predefined transitions
|
|
||||||
The predefined transitions provided by ```monarch.transitions.gui``` are:
|
The predefined transitions provided by ```monarch.transitions.gui``` are:
|
||||||
|
|
||||||
* ```slide_in_right```
|
* ```slide_in_right```
|
||||||
@@ -158,6 +163,23 @@ The predefined transitions provided by ```monarch.transitions.gui``` are:
|
|||||||
* ```scale_in```
|
* ```scale_in```
|
||||||
* ```scale_out```
|
* ```scale_out```
|
||||||
|
|
||||||
|
Additionally there's functionality to create a full set of transitions for common transition styles:
|
||||||
|
|
||||||
|
* ```transitions.in_right_out_left(node, duration, [delay], [easing])```
|
||||||
|
* ```transitions.in_left_out_right(node, duration, [delay], [easing])```
|
||||||
|
* ```transitions.in_left_out_left(node, duration, [delay], [easing])```
|
||||||
|
* ```transitions.in_right_out_right(node, duration, [delay], [easing])```
|
||||||
|
|
||||||
|
**PARAMETERS**
|
||||||
|
* ```node``` (node) - Gui node to animate.
|
||||||
|
* ```duration``` (number) - Transition duration in seconds.
|
||||||
|
* ```delay``` (number) - Transition delay in seconds.
|
||||||
|
* ```easing``` (table) - Easing table, created from a function provided by ```monarch.transitions.easings```
|
||||||
|
|
||||||
|
**RETURN**
|
||||||
|
* ```instance``` - The created transition instance
|
||||||
|
|
||||||
|
|
||||||
### Custom transitions
|
### Custom transitions
|
||||||
You can create and use your own transition as long as the provided transition function has the following function signature:
|
You can create and use your own transition as long as the provided transition function has the following function signature:
|
||||||
|
|
||||||
@@ -171,6 +193,7 @@ You can create and use your own transition as long as the provided transition fu
|
|||||||
* ```delay``` (number) - Transition delay in seconds.
|
* ```delay``` (number) - Transition delay in seconds.
|
||||||
* ```cb``` (function) - This function must be called when the transition is completed.
|
* ```cb``` (function) - This function must be called when the transition is completed.
|
||||||
|
|
||||||
|
|
||||||
### Dynamic orientation and resized windows
|
### Dynamic orientation and resized windows
|
||||||
When using dynamic screen orientation together with gui layouts or using transitions on a platform where the window can be resized it's important to make sure that the created transitions adapt to the change in orientation or window size. The transition system takes care of layout changes automatically, but when it comes to changes in window size you need to notify the transition manually:
|
When using dynamic screen orientation together with gui layouts or using transitions on a platform where the window can be resized it's important to make sure that the created transitions adapt to the change in orientation or window size. The transition system takes care of layout changes automatically, but when it comes to changes in window size you need to notify the transition manually:
|
||||||
|
|
||||||
@@ -187,6 +210,26 @@ When using dynamic screen orientation together with gui layouts or using transit
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
### Screen stack info and transitions
|
||||||
|
The transition message sent to the Transition Url specified in the screen configuration contains additional information about the transition. For the ```transition_show_in``` and ```transition_back_out``` messages the message contains the previous screen id:
|
||||||
|
|
||||||
|
function on_message(self, message_id, message, sender)
|
||||||
|
if message_id == hash("transition_show_in") or message_id == hash("transition_back_out") then
|
||||||
|
print(message.previous_screen)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
For the ```transition_show_out``` and ```transition_back_in``` messages the message contains the next screen id:
|
||||||
|
|
||||||
|
function on_message(self, message_id, message, sender)
|
||||||
|
if message_id == hash("transition_show_out") or message_id == hash("transition_back_in") then
|
||||||
|
print(message.next_screen)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
This information can be used to create dynamic transitions where the direction of the transition depends on the previous/next screen
|
||||||
|
|
||||||
|
|
||||||
## Screen focus gain/loss
|
## Screen focus gain/loss
|
||||||
Monarch will send focus gain and focus loss messages if a Focus Url was provided when the screen was created. The focus gained message will contain the id of the previous screen and the focus loss message will contain the id of the next screen. Example:
|
Monarch will send focus gain and focus loss messages if a Focus Url was provided when the screen was created. The focus gained message will contain the id of the previous screen and the focus loss message will contain the id of the next screen. Example:
|
||||||
|
|
||||||
@@ -200,9 +243,11 @@ Monarch will send focus gain and focus loss messages if a Focus Url was provided
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
## Callbacks
|
## Callbacks
|
||||||
Both the ```monarch.show()``` and ```monarch.back()``` functions take an optional callback function that will be invoked when the ```transition_show_in``` (or the ```transition_back_in``` in the case of a ```monarch.back()``` call) transition is completed. The transition is considered completed when a ```transition_done``` message has been received (see section on [transitions](#transitions) above).
|
Both the ```monarch.show()``` and ```monarch.back()``` functions take an optional callback function that will be invoked when the ```transition_show_in``` (or the ```transition_back_in``` in the case of a ```monarch.back()``` call) transition is completed. The transition is considered completed when a ```transition_done``` message has been received (see section on [transitions](#transitions) above).
|
||||||
|
|
||||||
|
|
||||||
## Monarch API
|
## Monarch API
|
||||||
|
|
||||||
### monarch.show(screen_id, [options], [data], [callback])
|
### monarch.show(screen_id, [options], [data], [callback])
|
||||||
@@ -219,6 +264,10 @@ The options table can contain the following fields:
|
|||||||
* ```clear``` (boolean) - If the clear flag is set Monarch will search the stack for the screen that is to be shown. If the screen already exists in the stack and the clear flag is set Monarch will remove all screens between the current top and the screen in question.
|
* ```clear``` (boolean) - If the clear flag is set Monarch will search the stack for the screen that is to be shown. If the screen already exists in the stack and the clear flag is set Monarch will remove all screens between the current top and the screen in question.
|
||||||
* ```reload``` (boolean) - If the reload flag is set Monarch will reload the collection proxy if it's already loaded (this can happen if the previous screen was a popup).
|
* ```reload``` (boolean) - If the reload flag is set Monarch will reload the collection proxy if it's already loaded (this can happen if the previous screen was a popup).
|
||||||
|
|
||||||
|
**RETURN**
|
||||||
|
* ```success``` (boolean) - True if the process of showing the screen was started successfully. False if already busy showing/hiding a screen.
|
||||||
|
|
||||||
|
|
||||||
### monarch.back([data], [callback])
|
### monarch.back([data], [callback])
|
||||||
Go back to a previous Monarch screen
|
Go back to a previous Monarch screen
|
||||||
|
|
||||||
@@ -226,6 +275,37 @@ Go back to a previous Monarch screen
|
|||||||
* ```data``` (table) - Optional data to associate with the screen you are going back to. Retrieve using ```monarch.data()```.
|
* ```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.
|
* ```callback``` (function) - Optional function to call when the previous screen is visible.
|
||||||
|
|
||||||
|
**RETURN**
|
||||||
|
* ```success``` (boolean) - True if the process of going back to a previous screen was started successfully. False if already busy showing/hiding a screen.
|
||||||
|
|
||||||
|
|
||||||
|
### monarch.preload(screen_id, [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.
|
||||||
|
|
||||||
|
**PARAMETERS**
|
||||||
|
* ```screen_id``` (hash) - Id of the screen to preload.
|
||||||
|
* ```callback``` (function) - Optional function to call when the new screen is preloaded.
|
||||||
|
|
||||||
|
|
||||||
|
### monarch.top([offset])
|
||||||
|
Get the id of the screen at the top of the stack.
|
||||||
|
|
||||||
|
**PARAMETERS**
|
||||||
|
* ```offset``` (number) - Optional offset from the top of the stack, ie -1 to get the previous screen
|
||||||
|
|
||||||
|
**RETURN**
|
||||||
|
* ```screen_id``` (hash) - Id of the requested screen
|
||||||
|
|
||||||
|
|
||||||
|
### monarch.bottom([offset])
|
||||||
|
Get the id of the screen at the bottom of the stack.
|
||||||
|
|
||||||
|
**PARAMETERS**
|
||||||
|
* ```offset``` (number) - Optional offset from the bottom of the stack
|
||||||
|
|
||||||
|
**RETURN**
|
||||||
|
* ```screen_id``` (hash) - Id of the requested screen
|
||||||
|
|
||||||
|
|
||||||
### monarch.data(screen_id)
|
### monarch.data(screen_id)
|
||||||
Get the data associated with a screen (from a call to ```monarch.show()``` or ```monarch.back()```).
|
Get the data associated with a screen (from a call to ```monarch.show()``` or ```monarch.back()```).
|
||||||
@@ -247,5 +327,42 @@ Check if a Monarch screen exists.
|
|||||||
* ```exists``` (boolean) - True if the screen exists.
|
* ```exists``` (boolean) - True if the screen exists.
|
||||||
|
|
||||||
|
|
||||||
|
### monarch.is_busy()
|
||||||
|
Check if Monarch is busy showing and/or hiding a screen.
|
||||||
|
|
||||||
|
**RETURN**
|
||||||
|
* ```busy``` (boolean) - True if busy hiding and/or showing a screen.
|
||||||
|
|
||||||
|
|
||||||
|
### monarch.add_listener([url])
|
||||||
|
Add a URL that will be notified of navigation events.
|
||||||
|
|
||||||
|
**PARAMETERS**
|
||||||
|
* ```url``` (url) - URL to send navigation events to. Will use current URL if omitted.
|
||||||
|
|
||||||
|
|
||||||
|
### monarch.remove_listener([url])
|
||||||
|
Remove a previously added listener.
|
||||||
|
|
||||||
|
**PARAMETERS**
|
||||||
|
* ```url``` (url) - URL to remove. Will use current URL if omitted.
|
||||||
|
|
||||||
|
|
||||||
### monarch.debug()
|
### monarch.debug()
|
||||||
Enable verbose logging of the internals of Monarch.
|
Enable verbose logging of the internals of Monarch.
|
||||||
|
|
||||||
|
|
||||||
|
### monarch.SCREEN_VISIBLE
|
||||||
|
Message sent to listeners when a screen becomes visible.
|
||||||
|
|
||||||
|
**PARAMETERS**
|
||||||
|
* ```screen``` (hash) - Id of the screen
|
||||||
|
* ```previous_screen``` (hash) - Id of theprevious screen (if any)
|
||||||
|
|
||||||
|
|
||||||
|
### monarch.SCREEN_HIDDEN
|
||||||
|
Message sent to listeners when a screen is hidden.
|
||||||
|
|
||||||
|
**PARAMETERS**
|
||||||
|
* ```screen``` (hash) - Id of the screen
|
||||||
|
* ```next_screen``` (hash) - Id of the next screen (if any)
|
||||||
|
|||||||
@@ -7,11 +7,7 @@ function init(self)
|
|||||||
local data = monarch.data(hash("game"))
|
local data = monarch.data(hash("game"))
|
||||||
gui.set_text(gui.get_node("level"), tostring(data.level))
|
gui.set_text(gui.get_node("level"), tostring(data.level))
|
||||||
|
|
||||||
self.transition = transitions.create(gui.get_node("root"))
|
self.transition = transitions.in_right_out_left(gui.get_node("root"), 0.6, 0)
|
||||||
.show_in(transitions.slide_in_right, gui.EASING_OUTQUAD, 0.6, 0)
|
|
||||||
.show_out(transitions.slide_out_left, gui.EASING_INQUAD, 0.6, 0)
|
|
||||||
.back_in(transitions.slide_in_left, gui.EASING_OUTQUAD, 0.6, 0)
|
|
||||||
.back_out(transitions.slide_out_right, gui.EASING_INQUAD, 0.6, 0)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function on_input(self, action_id, action)
|
function on_input(self, action_id, action)
|
||||||
|
|||||||
@@ -6,11 +6,7 @@ function init(self)
|
|||||||
|
|
||||||
gui.set_text(gui.get_node("timestamp"), os.date())
|
gui.set_text(gui.get_node("timestamp"), os.date())
|
||||||
|
|
||||||
self.transition = transitions.create(gui.get_node("root"))
|
self.transition = transitions.in_right_out_left(gui.get_node("root"), 0.6, 0)
|
||||||
.show_in(transitions.slide_in_right, gui.EASING_OUTQUAD, 0.6, 0)
|
|
||||||
.show_out(transitions.slide_out_left, gui.EASING_INQUAD, 0.6, 0)
|
|
||||||
.back_in(transitions.slide_in_left, gui.EASING_OUTQUAD, 0.6, 0)
|
|
||||||
.back_out(transitions.slide_out_right, gui.EASING_INQUAD, 0.6, 0)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function on_input(self, action_id, action)
|
function on_input(self, action_id, action)
|
||||||
|
|||||||
@@ -6,11 +6,7 @@ function init(self)
|
|||||||
self.play = gui.get_node("play_button")
|
self.play = gui.get_node("play_button")
|
||||||
self.back = gui.get_node("back_button")
|
self.back = gui.get_node("back_button")
|
||||||
|
|
||||||
self.transition = transitions.create(gui.get_node("root"))
|
self.transition = transitions.in_right_out_left(gui.get_node("root"), 0.6, 0)
|
||||||
.show_in(transitions.slide_in_right, gui.EASING_OUTQUAD, 0.6, 0)
|
|
||||||
.show_out(transitions.slide_out_left, gui.EASING_INQUAD, 0.6, 0)
|
|
||||||
.back_in(transitions.slide_in_left, gui.EASING_OUTQUAD, 0.6, 0)
|
|
||||||
.back_out(transitions.slide_out_right, gui.EASING_INQUAD, 0.6, 0)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function on_input(self, action_id, action)
|
function on_input(self, action_id, action)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[project]
|
[project]
|
||||||
title = Monarch
|
title = Monarch
|
||||||
version = 0.9
|
version = 0.9
|
||||||
dependencies = https://github.com/britzl/deftest/archive/1.2.1.zip
|
dependencies = https://github.com/britzl/deftest/archive/2.3.0.zip
|
||||||
|
|
||||||
[bootstrap]
|
[bootstrap]
|
||||||
main_collection = /example/example.collectionc
|
main_collection = /example/example.collectionc
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
local screens = {}
|
|
||||||
|
|
||||||
local stack = {}
|
|
||||||
|
|
||||||
local CONTEXT = hash("monarch_context")
|
local CONTEXT = hash("monarch_context")
|
||||||
local PROXY_LOADED = hash("proxy_loaded")
|
local PROXY_LOADED = hash("proxy_loaded")
|
||||||
local PROXY_UNLOADED = hash("proxy_unloaded")
|
local PROXY_UNLOADED = hash("proxy_unloaded")
|
||||||
@@ -14,6 +10,7 @@ local ASYNC_LOAD = hash("async_load")
|
|||||||
local UNLOAD = hash("unload")
|
local UNLOAD = hash("unload")
|
||||||
local ENABLE = hash("enable")
|
local ENABLE = hash("enable")
|
||||||
|
|
||||||
|
-- transition messages
|
||||||
M.TRANSITION = {}
|
M.TRANSITION = {}
|
||||||
M.TRANSITION.DONE = hash("transition_done")
|
M.TRANSITION.DONE = hash("transition_done")
|
||||||
M.TRANSITION.SHOW_IN = hash("transition_show_in")
|
M.TRANSITION.SHOW_IN = hash("transition_show_in")
|
||||||
@@ -21,10 +18,29 @@ M.TRANSITION.SHOW_OUT = hash("transition_show_out")
|
|||||||
M.TRANSITION.BACK_IN = hash("transition_back_in")
|
M.TRANSITION.BACK_IN = hash("transition_back_in")
|
||||||
M.TRANSITION.BACK_OUT = hash("transition_back_out")
|
M.TRANSITION.BACK_OUT = hash("transition_back_out")
|
||||||
|
|
||||||
|
-- focus messages
|
||||||
M.FOCUS = {}
|
M.FOCUS = {}
|
||||||
M.FOCUS.GAINED = hash("monarch_focus_gained")
|
M.FOCUS.GAINED = hash("monarch_focus_gained")
|
||||||
M.FOCUS.LOST = hash("monarch_focus_lost")
|
M.FOCUS.LOST = hash("monarch_focus_lost")
|
||||||
|
|
||||||
|
-- listener messages
|
||||||
|
M.SCREEN_VISIBLE = hash("monarch_screen_visible")
|
||||||
|
M.SCREEN_HIDDEN = hash("monarch_screen_hidden")
|
||||||
|
|
||||||
|
|
||||||
|
-- all registered screens
|
||||||
|
local screens = {}
|
||||||
|
|
||||||
|
-- the current stack of screens
|
||||||
|
local stack = {}
|
||||||
|
|
||||||
|
-- navigation listeners
|
||||||
|
local listeners = {}
|
||||||
|
|
||||||
|
-- the number of active transitions
|
||||||
|
-- monarch is considered busy while there are active transitions
|
||||||
|
local active_transition_count = 0
|
||||||
|
|
||||||
|
|
||||||
local function log(...) end
|
local function log(...) end
|
||||||
|
|
||||||
@@ -40,9 +56,15 @@ local function tohash(s)
|
|||||||
return hash_lookup[s]
|
return hash_lookup[s]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function notify_listeners(message_id, message)
|
||||||
|
log("notify_listeners()", message_id)
|
||||||
|
for _,url in pairs(listeners) do
|
||||||
|
msg.post(url, message_id, message or {})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function screen_from_proxy(proxy)
|
local function screen_from_proxy(proxy)
|
||||||
for _, screen in pairs(screens) do
|
for _,screen in pairs(screens) do
|
||||||
if screen.proxy == proxy then
|
if screen.proxy == proxy then
|
||||||
return screen
|
return screen
|
||||||
end
|
end
|
||||||
@@ -51,7 +73,7 @@ end
|
|||||||
|
|
||||||
local function screen_from_script()
|
local function screen_from_script()
|
||||||
local url = msg.url()
|
local url = msg.url()
|
||||||
for _, screen in pairs(screens) do
|
for _,screen in pairs(screens) do
|
||||||
if screen.script == url then
|
if screen.script == url then
|
||||||
return screen
|
return screen
|
||||||
end
|
end
|
||||||
@@ -171,10 +193,10 @@ local function async_load(screen)
|
|||||||
screen.wait_for = nil
|
screen.wait_for = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
local function transition(screen, message_id)
|
local function transition(screen, message_id, message)
|
||||||
log("transition()", screen.id)
|
log("transition()", screen.id)
|
||||||
screen.wait_for = M.TRANSITION.DONE
|
screen.wait_for = M.TRANSITION.DONE
|
||||||
msg.post(screen.transition_url, message_id)
|
msg.post(screen.transition_url, message_id, message)
|
||||||
coroutine.yield()
|
coroutine.yield()
|
||||||
screen.wait_for = nil
|
screen.wait_for = nil
|
||||||
end
|
end
|
||||||
@@ -182,14 +204,14 @@ end
|
|||||||
local function focus_gained(screen, previous_screen)
|
local function focus_gained(screen, previous_screen)
|
||||||
log("focus_gained()", screen.id)
|
log("focus_gained()", screen.id)
|
||||||
if screen.focus_url then
|
if screen.focus_url then
|
||||||
msg.post(screen.focus_url, M.FOCUS.GAINED, {id = previous_screen and previous_screen.id})
|
msg.post(screen.focus_url, M.FOCUS.GAINED, { id = previous_screen and previous_screen.id })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function focus_lost(screen, next_screen)
|
local function focus_lost(screen, next_screen)
|
||||||
log("focus_lost()", screen.id)
|
log("focus_lost()", screen.id)
|
||||||
if screen.focus_url then
|
if screen.focus_url then
|
||||||
msg.post(screen.focus_url, M.FOCUS.LOST, {id = next_screen and next_screen.id})
|
msg.post(screen.focus_url, M.FOCUS.LOST, { id = next_screen and next_screen.id })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -225,6 +247,7 @@ local function show_out(screen, next_screen, cb)
|
|||||||
log("show_out()", screen.id)
|
log("show_out()", screen.id)
|
||||||
local co
|
local co
|
||||||
co = coroutine.create(function()
|
co = coroutine.create(function()
|
||||||
|
active_transition_count = active_transition_count + 1
|
||||||
screen.co = co
|
screen.co = co
|
||||||
change_context(screen)
|
change_context(screen)
|
||||||
release_input(screen)
|
release_input(screen)
|
||||||
@@ -234,11 +257,13 @@ local function show_out(screen, next_screen, cb)
|
|||||||
local next_is_popup = next_screen and not next_screen.popup
|
local next_is_popup = next_screen and not next_screen.popup
|
||||||
local current_is_popup = screen.popup
|
local current_is_popup = screen.popup
|
||||||
if (next_is_popup and not current_is_popup) or (current_is_popup) then
|
if (next_is_popup and not current_is_popup) or (current_is_popup) then
|
||||||
transition(screen, M.TRANSITION.SHOW_OUT)
|
transition(screen, M.TRANSITION.SHOW_OUT, { next_screen = next_screen.id })
|
||||||
unload(screen)
|
unload(screen)
|
||||||
end
|
end
|
||||||
screen.co = nil
|
screen.co = nil
|
||||||
|
active_transition_count = active_transition_count - 1
|
||||||
if cb then cb() end
|
if cb then cb() end
|
||||||
|
notify_listeners(M.SCREEN_HIDDEN, { screen = screen.id, next_screen = next_screen.id })
|
||||||
end)
|
end)
|
||||||
coroutine.resume(co)
|
coroutine.resume(co)
|
||||||
end
|
end
|
||||||
@@ -247,60 +272,84 @@ local function show_in(screen, previous_screen, reload, cb)
|
|||||||
log("show_in()", screen.id)
|
log("show_in()", screen.id)
|
||||||
local co
|
local co
|
||||||
co = coroutine.create(function()
|
co = coroutine.create(function()
|
||||||
|
active_transition_count = active_transition_count + 1
|
||||||
screen.co = co
|
screen.co = co
|
||||||
change_context(screen)
|
change_context(screen)
|
||||||
if reload and screen.loaded then
|
if reload and screen.loaded then
|
||||||
log("show_in() reloading", screen.id)
|
log("show_in() reloading", screen.id)
|
||||||
unload(screen)
|
unload(screen)
|
||||||
end
|
end
|
||||||
|
-- if the screen has been preloaded we need to enable it
|
||||||
|
if screen.preloaded then
|
||||||
|
log("show_in() screen was preloaded", screen.id)
|
||||||
|
msg.post(screen.proxy, ENABLE)
|
||||||
|
screen.loaded = true
|
||||||
|
screen.preloaded = false
|
||||||
-- the screen could be loaded if the previous screen was a popup
|
-- the screen could be loaded if the previous screen was a popup
|
||||||
-- and the popup asked to show this screen again
|
-- and the popup asked to show this screen again
|
||||||
-- in that case we shouldn't attempt to load it again
|
-- in that case we shouldn't attempt to load it again
|
||||||
if not screen.loaded then
|
elseif not screen.loaded then
|
||||||
|
log("show_in() loading screen", screen.id)
|
||||||
async_load(screen)
|
async_load(screen)
|
||||||
end
|
end
|
||||||
stack[#stack + 1] = screen
|
stack[#stack + 1] = screen
|
||||||
transition(screen, M.TRANSITION.SHOW_IN)
|
transition(screen, M.TRANSITION.SHOW_IN, { previous_screen = previous_screen and previous_screen.id })
|
||||||
acquire_input(screen)
|
acquire_input(screen)
|
||||||
focus_gained(screen, previous_screen)
|
focus_gained(screen, previous_screen)
|
||||||
screen.co = nil
|
screen.co = nil
|
||||||
|
active_transition_count = active_transition_count - 1
|
||||||
if cb then cb() end
|
if cb then cb() end
|
||||||
|
notify_listeners(M.SCREEN_VISIBLE, { screen = screen.id, previous_screen = previous_screen and previous_screen.id })
|
||||||
end)
|
end)
|
||||||
coroutine.resume(co)
|
coroutine.resume(co)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function back_in(screen, previous_screen, cb)
|
local function back_in(screen, previous_screen, cb)
|
||||||
log("back_in()", screen.id)
|
log("back_in()", screen.id)
|
||||||
|
print("back_in()", screen.id)
|
||||||
local co
|
local co
|
||||||
co = coroutine.create(function()
|
co = coroutine.create(function()
|
||||||
|
active_transition_count = active_transition_count + 1
|
||||||
screen.co = co
|
screen.co = co
|
||||||
change_context(screen)
|
change_context(screen)
|
||||||
if not screen.loaded then
|
if screen.preloaded then
|
||||||
|
log("back_in() screen was preloaded", screen.id)
|
||||||
|
msg.post(screen.proxy, ENABLE)
|
||||||
|
screen.preloaded = false
|
||||||
|
screen.loaded = true
|
||||||
|
elseif not screen.loaded then
|
||||||
|
log("back_in() loading screen", screen.id)
|
||||||
async_load(screen)
|
async_load(screen)
|
||||||
end
|
end
|
||||||
if previous_screen and not previous_screen.popup then
|
if previous_screen and not previous_screen.popup then
|
||||||
transition(screen, M.TRANSITION.BACK_IN)
|
transition(screen, M.TRANSITION.BACK_IN, { previous_screen = previous_screen.id })
|
||||||
end
|
end
|
||||||
acquire_input(screen)
|
acquire_input(screen)
|
||||||
focus_gained(screen, previous_screen)
|
focus_gained(screen, previous_screen)
|
||||||
screen.co = nil
|
screen.co = nil
|
||||||
|
active_transition_count = active_transition_count - 1
|
||||||
if cb then cb() end
|
if cb then cb() end
|
||||||
|
notify_listeners(M.SCREEN_VISIBLE, { screen = screen.id, previous_screen = previous_screen.id })
|
||||||
end)
|
end)
|
||||||
coroutine.resume(co)
|
coroutine.resume(co)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function back_out(screen, next_screen, cb)
|
local function back_out(screen, next_screen, cb)
|
||||||
log("back_out()", screen.id)
|
log("back_out()", screen.id)
|
||||||
|
print("back_out()", screen.id)
|
||||||
local co
|
local co
|
||||||
co = coroutine.create(function()
|
co = coroutine.create(function()
|
||||||
|
active_transition_count = active_transition_count + 1
|
||||||
screen.co = co
|
screen.co = co
|
||||||
change_context(screen)
|
change_context(screen)
|
||||||
release_input(screen)
|
release_input(screen)
|
||||||
focus_lost(screen, next_screen)
|
focus_lost(screen, next_screen)
|
||||||
transition(screen, M.TRANSITION.BACK_OUT)
|
transition(screen, M.TRANSITION.BACK_OUT, { next_screen = next_screen and next_screen.id })
|
||||||
unload(screen)
|
unload(screen)
|
||||||
screen.co = nil
|
screen.co = nil
|
||||||
|
active_transition_count = active_transition_count - 1
|
||||||
if cb then cb() end
|
if cb then cb() end
|
||||||
|
notify_listeners(M.SCREEN_HIDDEN, { screen = screen.id, next_screen = next_screen and next_screen.id })
|
||||||
end)
|
end)
|
||||||
coroutine.resume(co)
|
coroutine.resume(co)
|
||||||
end
|
end
|
||||||
@@ -316,6 +365,7 @@ function M.data(id)
|
|||||||
return screens[id].data
|
return screens[id].data
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Checks to see if a screen id is registered
|
--- Checks to see if a screen id is registered
|
||||||
-- @param id (string|hash) Id of the screen to check if is registered
|
-- @param id (string|hash) Id of the screen to check if is registered
|
||||||
-- @return True or False if the screen id is registered or not
|
-- @return True or False if the screen id is registered or not
|
||||||
@@ -325,16 +375,29 @@ function M.screen_exists(id)
|
|||||||
return screens[id] ~= nil
|
return screens[id] ~= nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Check if Monarch is busy hiding and or showing a screen
|
||||||
|
-- @return true if busy
|
||||||
|
function M.is_busy()
|
||||||
|
return active_transition_count > 0
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Show a new screen
|
--- Show a new screen
|
||||||
-- @param id (string|hash) - Id of the screen to show
|
-- @param id (string|hash) - Id of the screen to show
|
||||||
-- @param options (table) - Table with options when showing the screen (can be nil). Valid values:
|
-- @param options (table) - 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 (function) - Optional callback to invoke when screen is shown
|
-- @param cb (function) - Optional callback to invoke when screen is shown
|
||||||
|
-- @return success True if screen is successfully shown, false if busy performing another operation
|
||||||
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")
|
||||||
|
if M.is_busy() then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
id = tohash(id)
|
id = tohash(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)))
|
||||||
|
|
||||||
@@ -379,13 +442,20 @@ function M.show(id, options, data, cb)
|
|||||||
|
|
||||||
-- show screen
|
-- show screen
|
||||||
show_in(screen, top, options and options.reload, cb)
|
show_in(screen, top, options and options.reload, cb)
|
||||||
|
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Go back to the previous screen in the stack
|
-- Go back to the previous screen in the stack
|
||||||
-- @param data (*) - Optional data to set for the previous screen
|
-- @param data (*) - Optional data to set for the previous screen
|
||||||
-- @param cb (function) - Optional callback to invoke when the previous screen is visible again
|
-- @param cb (function) - Optional callback to invoke when the previous screen is visible again
|
||||||
|
-- @return true if successfully going back, false if busy performing another operation
|
||||||
function M.back(data, cb)
|
function M.back(data, cb)
|
||||||
|
if M.is_busy() then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
local screen = table.remove(stack)
|
local screen = table.remove(stack)
|
||||||
if screen then
|
if screen then
|
||||||
log("back()", screen.id)
|
log("back()", screen.id)
|
||||||
@@ -411,6 +481,35 @@ function M.back(data, cb)
|
|||||||
elseif cb then
|
elseif cb then
|
||||||
cb()
|
cb()
|
||||||
end
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Preload a screen. This will load but not enable and show a screen. Useful for "heavier" screens
|
||||||
|
-- that you wish to show without any delay.
|
||||||
|
-- @param id (string|hash) - Id of the screen to preload
|
||||||
|
-- @param cb (function) - Optional callback to invoke when screen is loaded
|
||||||
|
function M.preload(id, cb)
|
||||||
|
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.preloaded or screen.loaded then
|
||||||
|
if cb then cb() end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local co
|
||||||
|
co = coroutine.create(function()
|
||||||
|
screen.co = co
|
||||||
|
change_context(screen)
|
||||||
|
screen.wait_for = PROXY_LOADED
|
||||||
|
msg.post(screen.proxy, ASYNC_LOAD)
|
||||||
|
coroutine.yield()
|
||||||
|
screen.preloaded = true
|
||||||
|
screen.wait_for = nil
|
||||||
|
if cb then cb() end
|
||||||
|
end)
|
||||||
|
coroutine.resume(co)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -454,6 +553,45 @@ function M.get_stack()
|
|||||||
return s
|
return s
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get the screen on top of the stack
|
||||||
|
-- @param offset Optional offset from the top of the stack, (eg -1 for the previous screen)
|
||||||
|
-- @return Id of the requested screen
|
||||||
|
function M.top(offset)
|
||||||
|
local screen = stack[#stack + (offset or 0)]
|
||||||
|
return screen and screen.id
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get the screen at the bottom of the stack
|
||||||
|
-- @param offset Optional offset from the bottom of the stack
|
||||||
|
-- @return Id of the requested screen
|
||||||
|
function M.bottom(offset)
|
||||||
|
local screen = stack[1 + (offset or 0)]
|
||||||
|
return screen and screen.id
|
||||||
|
end
|
||||||
|
|
||||||
|
local function url_to_key(url)
|
||||||
|
return (url.socket or hash("")) .. (url.path or hash("")) .. (url.fragment or hash(""))
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Add a listener to be notified of when screens are shown or hidden
|
||||||
|
-- @param url The url to notify, nil for current url
|
||||||
|
function M.add_listener(url)
|
||||||
|
url = url or msg.url()
|
||||||
|
listeners[url_to_key(url)] = url
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Remove a previously added listener
|
||||||
|
-- @param url The url to remove, nil for current url
|
||||||
|
function M.remove_listener(url)
|
||||||
|
url = url or msg.url()
|
||||||
|
listeners[url_to_key(url)] = nil
|
||||||
|
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
|
||||||
|
|||||||
26
monarch/transitions/easings.lua
Normal file
26
monarch/transitions/easings.lua
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
local M = {}
|
||||||
|
|
||||||
|
|
||||||
|
local function create(name)
|
||||||
|
assert(gui["EASING_OUT" .. name])
|
||||||
|
assert(gui["EASING_IN" .. name])
|
||||||
|
return {
|
||||||
|
IN = gui["EASING_OUT" .. name],
|
||||||
|
OUT = gui["EASING_IN" .. name],
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function M.BACK() return create("BACK") end
|
||||||
|
function M.BOUNCE() return create("BOUNCE") end
|
||||||
|
function M.CIRC() return create("CIRC") end
|
||||||
|
function M.CUBIC() return create("CUBIC") end
|
||||||
|
function M.ELASTIC() return create("ELASTIC") end
|
||||||
|
function M.EXPO() return create("EXPO") end
|
||||||
|
function M.QUAD() return create("QUAD") end
|
||||||
|
function M.QUART() return create("QUART") end
|
||||||
|
function M.QUINT() return create("QUINT") end
|
||||||
|
function M.SINE() return create("SINE") end
|
||||||
|
|
||||||
|
|
||||||
|
return M
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
local monarch = require "monarch.monarch"
|
local monarch = require "monarch.monarch"
|
||||||
|
local easings = require "monarch.transitions.easings"
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
@@ -110,22 +111,28 @@ function M.create(node)
|
|||||||
delay = delay,
|
delay = delay,
|
||||||
in_progress = false,
|
in_progress = false,
|
||||||
urls = {},
|
urls = {},
|
||||||
|
id = nil
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function finish_transition(transition)
|
||||||
|
transition.in_progress = false
|
||||||
|
local message = { transition = transition.id }
|
||||||
|
while #transition.urls > 0 do
|
||||||
|
local url = table.remove(transition.urls)
|
||||||
|
msg.post(url, monarch.TRANSITION.DONE, message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function start_transition(transition, transition_id, url)
|
local function start_transition(transition, transition_id, url)
|
||||||
table.insert(transition.urls, url)
|
table.insert(transition.urls, url)
|
||||||
if not transition.in_progress then
|
if not transition.in_progress then
|
||||||
table.insert(transition.urls, msg.url())
|
table.insert(transition.urls, msg.url())
|
||||||
current_transition = transition
|
|
||||||
transition.in_progress = true
|
transition.in_progress = true
|
||||||
|
transition.id = transition_id
|
||||||
|
current_transition = transition
|
||||||
transition.fn(node, initial_data, transition.easing, transition.duration, transition.delay or 0, function()
|
transition.fn(node, initial_data, transition.easing, transition.duration, transition.delay or 0, function()
|
||||||
transition.in_progress = false
|
finish_transition(transition)
|
||||||
local message = { transition = transition_id }
|
|
||||||
while #transition.urls > 0 do
|
|
||||||
local url = table.remove(transition.urls)
|
|
||||||
msg.post(url, monarch.TRANSITION.DONE, message)
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -139,6 +146,9 @@ function M.create(node)
|
|||||||
-- were transitioned out
|
-- were transitioned out
|
||||||
if current_transition then
|
if current_transition then
|
||||||
current_transition.fn(node, initial_data, current_transition.easing, 0, 0)
|
current_transition.fn(node, initial_data, current_transition.easing, 0, 0)
|
||||||
|
if current_transition.in_progress then
|
||||||
|
finish_transition(current_transition)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
local transition = transitions[message_id]
|
local transition = transitions[message_id]
|
||||||
@@ -189,4 +199,60 @@ function M.create(node)
|
|||||||
return instance
|
return instance
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Create transition where the screen slides in from the right when shown and out
|
||||||
|
-- to the left when hidden (and the reverse when going back)
|
||||||
|
-- @param node
|
||||||
|
-- @param duration
|
||||||
|
-- @param delay Optional. Defaults to 0
|
||||||
|
-- @param easing Optional. A constant from monarch.transitions.easing
|
||||||
|
-- @return Transition instance
|
||||||
|
function M.in_right_out_left(node, duration, delay, easing)
|
||||||
|
assert(node, "You must provide a node")
|
||||||
|
assert(duration, "You must provide a duration")
|
||||||
|
easing = easing or easings.QUAD()
|
||||||
|
return M.create(node)
|
||||||
|
.show_in(M.slide_in_right, easing.OUT, duration, delay or 0)
|
||||||
|
.show_out(M.slide_out_left, easing.IN, duration, delay or 0)
|
||||||
|
.back_in(M.slide_in_left, easing.OUT, duration, delay or 0)
|
||||||
|
.back_out(M.slide_out_right, easing.IN, duration, delay or 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function M.in_left_out_right(node, duration, delay, easing)
|
||||||
|
assert(node, "You must provide a node")
|
||||||
|
assert(duration, "You must provide a duration")
|
||||||
|
easing = easing or easings.QUAD()
|
||||||
|
return M.create(node)
|
||||||
|
.show_in(M.slide_in_left, easing.OUT, duration, delay or 0)
|
||||||
|
.show_out(M.slide_out_right, easing.IN, duration, delay or 0)
|
||||||
|
.back_in(M.slide_in_right, easing.OUT, duration, delay or 0)
|
||||||
|
.back_out(M.slide_out_left, easing.IN, duration, delay or 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function M.in_right_out_right(node, duration, delay, easing)
|
||||||
|
assert(node, "You must provide a node")
|
||||||
|
assert(duration, "You must provide a duration")
|
||||||
|
easing = easing or easings.QUAD()
|
||||||
|
return M.create(node)
|
||||||
|
.show_in(M.slide_in_right, easing.OUT, duration, delay or 0)
|
||||||
|
.show_out(M.slide_out_right, easing.IN, duration, delay or 0)
|
||||||
|
.back_in(M.slide_in_right, easing.OUT, duration, delay or 0)
|
||||||
|
.back_out(M.slide_out_right, easing.IN, duration, delay or 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function M.in_left_out_left(node, duration, delay, easing)
|
||||||
|
assert(node, "You must provide a node")
|
||||||
|
assert(duration, "You must provide a duration")
|
||||||
|
easing = easing or easings.QUAD()
|
||||||
|
return M.create(node)
|
||||||
|
.show_in(M.slide_in_left, easing.OUT, duration, delay or 0)
|
||||||
|
.show_out(M.slide_out_left, easing.IN, duration, delay or 0)
|
||||||
|
.back_in(M.slide_in_left, easing.OUT, duration, delay or 0)
|
||||||
|
.back_out(M.slide_out_left, easing.IN, duration, delay or 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|||||||
@@ -252,3 +252,106 @@ embedded_instances {
|
|||||||
z: 1.0
|
z: 1.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
embedded_instances {
|
||||||
|
id: "transition1"
|
||||||
|
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: \"transition1\"\n"
|
||||||
|
" type: PROPERTY_TYPE_HASH\n"
|
||||||
|
" }\n"
|
||||||
|
" properties {\n"
|
||||||
|
" id: \"transition_url\"\n"
|
||||||
|
" value: \"transition1:/go\"\n"
|
||||||
|
" type: PROPERTY_TYPE_URL\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
"embedded_components {\n"
|
||||||
|
" id: \"collectionproxy\"\n"
|
||||||
|
" type: \"collectionproxy\"\n"
|
||||||
|
" data: \"collection: \\\"/test/data/transition1.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: "listener1"
|
||||||
|
data: ""
|
||||||
|
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: "listener2"
|
||||||
|
data: ""
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
37
test/data/transition1.collection
Normal file
37
test/data/transition1.collection
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
name: "transition1"
|
||||||
|
scale_along_z: 0
|
||||||
|
embedded_instances {
|
||||||
|
id: "go"
|
||||||
|
data: "components {\n"
|
||||||
|
" id: \"transition1\"\n"
|
||||||
|
" component: \"/test/data/transition1.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/transition1.gui
Normal file
131
test/data/transition1.gui
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
script: "/test/data/transition1.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: "root"
|
||||||
|
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: "transition 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: "root"
|
||||||
|
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
|
||||||
10
test/data/transition1.gui_script
Normal file
10
test/data/transition1.gui_script
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
local transitions = require "monarch.transitions.gui"
|
||||||
|
|
||||||
|
function init(self)
|
||||||
|
self.transition = transitions.in_right_out_left(gui.get_node("root"), 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
function on_message(self, message_id, message, sender)
|
||||||
|
print(message_id)
|
||||||
|
self.transition.handle(message_id, message, sender)
|
||||||
|
end
|
||||||
52
test/msg.lua
Normal file
52
test/msg.lua
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
local mock = require "deftest.mock.mock"
|
||||||
|
|
||||||
|
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
|
||||||
|
local recipients = {}
|
||||||
|
|
||||||
|
local history = {}
|
||||||
|
|
||||||
|
local function get_recipient(url)
|
||||||
|
recipients[url] = recipients[url] or {}
|
||||||
|
return recipients[url]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function post(url, message_id, message)
|
||||||
|
local data = { url = url, message_id = message_id, message = message }
|
||||||
|
history[#history + 1] = data
|
||||||
|
local recipient = get_recipient(url)
|
||||||
|
recipient[#recipient + 1] = data
|
||||||
|
msg.post.original(url, message_id, message or {})
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.mock()
|
||||||
|
recipients = {}
|
||||||
|
history = {}
|
||||||
|
mock.mock(msg)
|
||||||
|
msg.post.replace(post)
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.unmock()
|
||||||
|
mock.unmock(msg)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function M.messages(url)
|
||||||
|
return url and get_recipient(url) or history
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.first(url)
|
||||||
|
local messages = url and get_recipient(url) or history
|
||||||
|
return messages[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.last(url)
|
||||||
|
local messages = url and get_recipient(url) or history
|
||||||
|
return messages[#messages]
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return M
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
local cowait = require "test.cowait"
|
local cowait = require "test.cowait"
|
||||||
|
local mock_msg = require "test.msg"
|
||||||
|
local unload = require "deftest.util.unload"
|
||||||
local monarch = require "monarch.monarch"
|
local monarch = require "monarch.monarch"
|
||||||
|
|
||||||
local SCREEN1_STR = hash("screen1")
|
local SCREEN1_STR = hash("screen1")
|
||||||
@@ -7,6 +9,7 @@ local SCREEN2 = hash("screen2")
|
|||||||
local POPUP1 = hash("popup1")
|
local POPUP1 = hash("popup1")
|
||||||
local POPUP2 = hash("popup2")
|
local POPUP2 = hash("popup2")
|
||||||
local FOOBAR = hash("foobar")
|
local FOOBAR = hash("foobar")
|
||||||
|
local TRANSITION1 = hash("transition1")
|
||||||
|
|
||||||
return function()
|
return function()
|
||||||
|
|
||||||
@@ -35,6 +38,9 @@ return function()
|
|||||||
local function wait_until_hidden(screen_id)
|
local function wait_until_hidden(screen_id)
|
||||||
return wait_timeout(is_hidden, screen_id)
|
return wait_timeout(is_hidden, screen_id)
|
||||||
end
|
end
|
||||||
|
local function wait_until_not_busy()
|
||||||
|
return wait_timeout(function() return not monarch.is_busy() end)
|
||||||
|
end
|
||||||
|
|
||||||
local function assert_stack(expected_screens)
|
local function assert_stack(expected_screens)
|
||||||
local actual_screens = monarch.get_stack()
|
local actual_screens = monarch.get_stack()
|
||||||
@@ -51,12 +57,14 @@ return function()
|
|||||||
|
|
||||||
describe("monarch", function()
|
describe("monarch", function()
|
||||||
before(function()
|
before(function()
|
||||||
|
mock_msg.mock()
|
||||||
monarch = require "monarch.monarch"
|
monarch = require "monarch.monarch"
|
||||||
screens_instances = collectionfactory.create("#screensfactory")
|
screens_instances = collectionfactory.create("#screensfactory")
|
||||||
end)
|
end)
|
||||||
|
|
||||||
after(function()
|
after(function()
|
||||||
package.loaded["monarch.monarch"] = nil
|
mock_msg.unmock()
|
||||||
|
unload.unload("monarch%..*")
|
||||||
for id,instance_id in pairs(screens_instances) do
|
for id,instance_id in pairs(screens_instances) do
|
||||||
go.delete(instance_id)
|
go.delete(instance_id)
|
||||||
end
|
end
|
||||||
@@ -148,6 +156,23 @@ return function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
it("should prevent further operations while hiding/showing a screen", function()
|
||||||
|
assert(monarch.show(SCREEN1) == true)
|
||||||
|
assert(monarch.show(SCREEN2) == false)
|
||||||
|
assert(wait_until_shown(SCREEN1), "Screen1 was never shown")
|
||||||
|
assert_stack({ SCREEN1 })
|
||||||
|
|
||||||
|
assert(monarch.show(SCREEN2) == true)
|
||||||
|
assert(wait_until_shown(SCREEN2), "Screen2 was never shown")
|
||||||
|
assert_stack({ SCREEN1, SCREEN2 })
|
||||||
|
|
||||||
|
assert(monarch.back() == true)
|
||||||
|
assert(monarch.back() == false)
|
||||||
|
assert(wait_until_shown(SCREEN1), "Screen1 was never shown")
|
||||||
|
assert_stack({ SCREEN1 })
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
it("should close any open popups when showing a popup without the Popup On Popup flag", function()
|
it("should close any open popups when showing a popup without the Popup On Popup flag", function()
|
||||||
monarch.show(SCREEN1)
|
monarch.show(SCREEN1)
|
||||||
assert(wait_until_shown(SCREEN1), "Screen1 was never shown")
|
assert(wait_until_shown(SCREEN1), "Screen1 was never shown")
|
||||||
@@ -175,6 +200,67 @@ return function()
|
|||||||
assert(wait_until_shown(SCREEN2), "Popup2 was never shown")
|
assert(wait_until_shown(SCREEN2), "Popup2 was never shown")
|
||||||
assert_stack({ SCREEN1, SCREEN2 })
|
assert_stack({ SCREEN1, SCREEN2 })
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
it("should be able to get the id of the screen at the top and bottom of the stack", function()
|
||||||
|
assert(monarch.top() == nil)
|
||||||
|
assert(monarch.bottom() == nil)
|
||||||
|
assert(monarch.top(1) == nil)
|
||||||
|
assert(monarch.bottom(-1) == nil)
|
||||||
|
|
||||||
|
monarch.show(SCREEN1)
|
||||||
|
assert(wait_until_shown(SCREEN1), "Screen1 was never shown")
|
||||||
|
assert(monarch.top() == SCREEN1)
|
||||||
|
assert(monarch.top(0) == SCREEN1)
|
||||||
|
assert(monarch.top(1) == nil)
|
||||||
|
assert(monarch.bottom() == SCREEN1)
|
||||||
|
assert(monarch.bottom(0) == SCREEN1)
|
||||||
|
assert(monarch.bottom(-1) == nil)
|
||||||
|
|
||||||
|
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 })
|
||||||
|
assert(monarch.top(0) == SCREEN2)
|
||||||
|
assert(monarch.top(-1) == SCREEN1)
|
||||||
|
assert(monarch.bottom(0) == SCREEN1)
|
||||||
|
assert(monarch.bottom(1) == SCREEN2)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("should be busy while transition is running", function()
|
||||||
|
monarch.show(TRANSITION1)
|
||||||
|
assert(wait_until_shown(TRANSITION1), "Transition1 was never shown")
|
||||||
|
assert(monarch.is_busy())
|
||||||
|
assert(wait_until_not_busy())
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("should be able to notify listeners of navigation events", function()
|
||||||
|
local URL1 = msg.url(screens_instances[hash("/listener1")])
|
||||||
|
local URL2 = msg.url(screens_instances[hash("/listener2")])
|
||||||
|
monarch.add_listener(URL1)
|
||||||
|
monarch.add_listener(URL2)
|
||||||
|
|
||||||
|
monarch.show(SCREEN1)
|
||||||
|
assert(wait_until_not_busy())
|
||||||
|
|
||||||
|
monarch.remove_listener(URL2)
|
||||||
|
monarch.show(SCREEN2)
|
||||||
|
assert(wait_until_not_busy())
|
||||||
|
|
||||||
|
monarch.back()
|
||||||
|
assert(wait_until_not_busy())
|
||||||
|
|
||||||
|
local messages_1 = mock_msg.messages(URL1)
|
||||||
|
local messages_2 = mock_msg.messages(URL2)
|
||||||
|
assert(#messages_1 == 5)
|
||||||
|
assert(#messages_2 == 1)
|
||||||
|
assert(messages_2[1].message_id == monarch.SCREEN_VISIBLE and messages_1[1].message.screen == SCREEN1)
|
||||||
|
|
||||||
|
assert(messages_1[1].message_id == monarch.SCREEN_VISIBLE and messages_1[1].message.screen == SCREEN1)
|
||||||
|
assert(messages_1[2].message_id == monarch.SCREEN_HIDDEN and messages_1[2].message.screen == SCREEN1)
|
||||||
|
assert(messages_1[3].message_id == monarch.SCREEN_VISIBLE and messages_1[3].message.screen == SCREEN2)
|
||||||
|
assert(messages_1[4].message_id == monarch.SCREEN_HIDDEN and messages_1[4].message.screen == SCREEN2)
|
||||||
|
assert(messages_1[5].message_id == monarch.SCREEN_VISIBLE and messages_1[5].message.screen == SCREEN1)
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user