mirror of
https://github.com/britzl/monarch.git
synced 2025-11-26 19:00:53 +01:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d3799a93ff | ||
|
|
76d4ca2927 |
@@ -33,6 +33,13 @@ Hide a screen that has been shown using the `no_stack` option. If used on a scre
|
|||||||
* `success` (boolean) - True if the process of hiding the screen was started successfully.
|
* `success` (boolean) - True if the process of hiding the screen was started successfully.
|
||||||
|
|
||||||
|
|
||||||
|
## monarch.clear([callback])
|
||||||
|
Clear the stack of screens completely. Any visible screen will be hidden by navigating back out from them. This operation will be added to the queue if Monarch is busy.
|
||||||
|
|
||||||
|
**PARAMETERS**
|
||||||
|
* `callback` (function) - Optional function to call when the stack has been cleared.
|
||||||
|
|
||||||
|
|
||||||
## monarch.back([data], [callback])
|
## monarch.back([data], [callback])
|
||||||
Go back to a previous Monarch screen. This operation will be added to the queue if Monarch is busy.
|
Go back to a previous Monarch screen. This operation will be added to the queue if Monarch is busy.
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[project]
|
[project]
|
||||||
title = Monarch
|
title = Monarch
|
||||||
version = 0.9
|
version = 0.9
|
||||||
dependencies = https://github.com/britzl/deftest/archive/2.7.0.zip
|
dependencies#0 = https://github.com/britzl/deftest/archive/2.7.0.zip
|
||||||
|
|
||||||
[bootstrap]
|
[bootstrap]
|
||||||
main_collection = /example/advanced/advanced.collectionc
|
main_collection = /example/advanced/advanced.collectionc
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
local callback_tracker = require "monarch.utils.callback_tracker"
|
local callback_tracker = require "monarch.utils.callback_tracker"
|
||||||
|
local async = require "monarch.utils.async"
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
@@ -744,8 +745,9 @@ function M.show(id, options, data, cb)
|
|||||||
pop = pop - 1
|
pop = pop - 1
|
||||||
end
|
end
|
||||||
stack[#stack] = nil
|
stack[#stack] = nil
|
||||||
show_out(top, screen, WAIT_FOR_TRANSITION, callbacks.track())
|
async(function(await, resume)
|
||||||
callbacks.yield_until_done()
|
await(show_out, top, screen, WAIT_FOR_TRANSITION, resume)
|
||||||
|
end)
|
||||||
top = stack[#stack]
|
top = stack[#stack]
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -784,8 +786,9 @@ function M.show(id, options, data, cb)
|
|||||||
local same_screen = top and top.id == screen.id
|
local same_screen = top and top.id == screen.id
|
||||||
if same_screen or (options and options.sequential) then
|
if same_screen or (options and options.sequential) then
|
||||||
if top then
|
if top then
|
||||||
show_out(top, screen, WAIT_FOR_TRANSITION, callbacks.track())
|
async(function(await, resume)
|
||||||
callbacks.yield_until_done()
|
await(show_out, top, screen, WAIT_FOR_TRANSITION, resume)
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
show_in(screen, top, options and options.reload, add_to_stack, WAIT_FOR_TRANSITION, callbacks.track())
|
show_in(screen, top, options and options.reload, add_to_stack, WAIT_FOR_TRANSITION, callbacks.track())
|
||||||
else
|
else
|
||||||
@@ -826,7 +829,7 @@ end
|
|||||||
|
|
||||||
-- Hide a screen. The screen must either be at the top of the stack or
|
-- Hide a screen. The screen must either be at the top of the stack or
|
||||||
-- visible but not added to the stack (through the no_stack option)
|
-- visible but not added to the stack (through the no_stack option)
|
||||||
-- @param id (string|hash) - Id of the screen to show
|
-- @param id (string|hash) - Id of the screen to .hide
|
||||||
-- @param cb (function) - Optional callback to invoke when the screen is hidden
|
-- @param cb (function) - Optional callback to invoke when the screen is hidden
|
||||||
-- @return true if successfully hiding, false if busy or for some other reason unable to hide the screen
|
-- @return true if successfully hiding, false if busy or for some other reason unable to hide the screen
|
||||||
function M.hide(id, cb)
|
function M.hide(id, cb)
|
||||||
@@ -863,6 +866,34 @@ function M.hide(id, cb)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- Clear stack completely. Any visible screens will be hidden by navigating back out
|
||||||
|
-- from them.
|
||||||
|
-- @param cb (function) - Optional callback to invoke when the stack has been cleared
|
||||||
|
function M.clear(cb)
|
||||||
|
log("clear() queuing action")
|
||||||
|
|
||||||
|
queue_action(function(action_done, action_error)
|
||||||
|
async(function(await, resume)
|
||||||
|
local top = stack[#stack]
|
||||||
|
while top and top.visible do
|
||||||
|
stack[#stack] = nil
|
||||||
|
await(back_out, top, screen, WAIT_FOR_TRANSITION, resume)
|
||||||
|
top = stack[#stack]
|
||||||
|
end
|
||||||
|
|
||||||
|
while stack[#stack] do
|
||||||
|
table.remove(stack)
|
||||||
|
end
|
||||||
|
|
||||||
|
pcallfn(cb)
|
||||||
|
pcallfn(action_done)
|
||||||
|
end)
|
||||||
|
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
|
||||||
@@ -871,6 +902,7 @@ function M.back(data, cb)
|
|||||||
|
|
||||||
queue_action(function(action_done)
|
queue_action(function(action_done)
|
||||||
local callbacks = callback_tracker()
|
local callbacks = callback_tracker()
|
||||||
|
local back_cb = callbacks.track()
|
||||||
local screen = table.remove(stack)
|
local screen = table.remove(stack)
|
||||||
if screen then
|
if screen then
|
||||||
log("back()", screen.id)
|
log("back()", screen.id)
|
||||||
@@ -882,7 +914,7 @@ function M.back(data, cb)
|
|||||||
if data then
|
if data then
|
||||||
top.data = data
|
top.data = data
|
||||||
end
|
end
|
||||||
back_in(top, screen, WAIT_FOR_TRANSITION, callbacks.track())
|
back_in(top, screen, WAIT_FOR_TRANSITION, back_cb)
|
||||||
end)
|
end)
|
||||||
else
|
else
|
||||||
if top then
|
if top then
|
||||||
@@ -890,10 +922,10 @@ function M.back(data, cb)
|
|||||||
top.data = data
|
top.data = data
|
||||||
end
|
end
|
||||||
back_in(top, screen, DO_NOT_WAIT_FOR_TRANSITION, function()
|
back_in(top, screen, DO_NOT_WAIT_FOR_TRANSITION, function()
|
||||||
back_out(screen, top, WAIT_FOR_TRANSITION, callbacks.track())
|
back_out(screen, top, WAIT_FOR_TRANSITION, back_cb)
|
||||||
end)
|
end)
|
||||||
else
|
else
|
||||||
back_out(screen, top, WAIT_FOR_TRANSITION, callbacks.track())
|
back_out(screen, top, WAIT_FOR_TRANSITION, back_cb)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
47
monarch/utils/async.lua
Normal file
47
monarch/utils/async.lua
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
local M = {}
|
||||||
|
|
||||||
|
local NOT_STARTED = "not_started"
|
||||||
|
local YIELDED = "yielded"
|
||||||
|
local RESUMED = "resumed"
|
||||||
|
local RUNNING = "running"
|
||||||
|
|
||||||
|
function M.async(fn)
|
||||||
|
local co = coroutine.running()
|
||||||
|
|
||||||
|
local state = NOT_STARTED
|
||||||
|
|
||||||
|
local function await(fn, ...)
|
||||||
|
state = RUNNING
|
||||||
|
fn(...)
|
||||||
|
if state ~= RUNNING then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
state = YIELDED
|
||||||
|
local r = { coroutine.yield() }
|
||||||
|
return unpack(r)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function resume(...)
|
||||||
|
if state ~= RUNNING then
|
||||||
|
state = RUNNING
|
||||||
|
local ok, err = coroutine.resume(co, ...)
|
||||||
|
if not ok then
|
||||||
|
print(err)
|
||||||
|
print(debug.traceback())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if co then
|
||||||
|
return fn(await, resume)
|
||||||
|
else
|
||||||
|
co = coroutine.create(fn)
|
||||||
|
return resume(await, resume)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return setmetatable(M, {
|
||||||
|
__call = function(t, ...)
|
||||||
|
return M.async(...)
|
||||||
|
end
|
||||||
|
})
|
||||||
@@ -6,13 +6,18 @@ function M.create()
|
|||||||
|
|
||||||
local callback = nil
|
local callback = nil
|
||||||
local callback_count = 0
|
local callback_count = 0
|
||||||
|
local all_callbacks_done = false
|
||||||
|
|
||||||
local function is_done()
|
local function is_done()
|
||||||
return callback_count == 0
|
return callback_count == 0
|
||||||
end
|
end
|
||||||
|
|
||||||
local function invoke_if_done()
|
local function invoke_if_done()
|
||||||
|
if all_callbacks_done then
|
||||||
|
print("Warning: The same callback will be invoked twice from the callback tracker!", id or "")
|
||||||
|
end
|
||||||
if callback_count == 0 and callback then
|
if callback_count == 0 and callback then
|
||||||
|
all_callbacks_done = true
|
||||||
local ok, err = pcall(callback)
|
local ok, err = pcall(callback)
|
||||||
if not ok then print(err) end
|
if not ok then print(err) end
|
||||||
end
|
end
|
||||||
@@ -41,20 +46,6 @@ function M.create()
|
|||||||
invoke_if_done()
|
invoke_if_done()
|
||||||
end
|
end
|
||||||
|
|
||||||
function instance.yield_until_done()
|
|
||||||
local co = coroutine.running()
|
|
||||||
callback = function()
|
|
||||||
local ok, err = coroutine.resume(co)
|
|
||||||
if not ok then
|
|
||||||
print(err)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
invoke_if_done()
|
|
||||||
if not is_done() then
|
|
||||||
coroutine.yield()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return instance
|
return instance
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user