From 07eacc7a5f1c1088307c608713203c526bec2d2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ritzl?= Date: Thu, 21 Jun 2018 11:33:20 +0200 Subject: [PATCH] Track when callbacks are invoked so that we can ensure that all screens are shown/hidden before invoking callbacks --- monarch/monarch.lua | 23 ++++++++++++------ monarch/utils/callback_tracker.lua | 39 ++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 7 deletions(-) create mode 100644 monarch/utils/callback_tracker.lua diff --git a/monarch/monarch.lua b/monarch/monarch.lua index 30fffe1..7f4b2ec 100644 --- a/monarch/monarch.lua +++ b/monarch/monarch.lua @@ -1,3 +1,5 @@ +local callback_tracker = require "monarch.utils.callback_tracker" + local M = {} local CONTEXT = hash("monarch_context") @@ -402,6 +404,8 @@ function M.show(id, options, data, cb) log("show() monarch is busy, ignoring request") return false end + + local callbacks = callback_tracker() id = tohash(id) assert(screens[id], ("There is no screen registered with id %s"):format(tostring(id))) @@ -423,13 +427,13 @@ function M.show(id, options, data, cb) -- close all popups while top.popup do stack[#stack] = nil - show_out(top, screen) + show_out(top, screen, callbacks.track()) top = stack[#stack] end -- unload and transition out from top -- unless we're showing the same screen as is already visible if top and top.id ~= screen.id then - show_out(top, screen) + show_out(top, screen, callbacks.track()) end end end @@ -446,7 +450,9 @@ function M.show(id, options, data, cb) end -- show screen - show_in(screen, top, options and options.reload, cb) + show_in(screen, top, options and options.reload, callbacks.track()) + + if cb then callbacks.when_done(cb) end return true end @@ -462,6 +468,8 @@ function M.back(data, cb) return false end + local callbacks = callback_tracker() + local screen = table.remove(stack) if screen then log("back()", screen.id) @@ -473,7 +481,7 @@ function M.back(data, cb) if data then top.data = data end - back_in(top, screen, cb) + back_in(top, screen, callbacks.track()) end) else back_out(screen, top) @@ -481,12 +489,13 @@ function M.back(data, cb) if data then top.data = data end - back_in(top, screen, cb) + back_in(top, screen, callbacks.track()) end end - elseif cb then - cb() end + + if cb then callbacks.when_done(cb) end + return true end diff --git a/monarch/utils/callback_tracker.lua b/monarch/utils/callback_tracker.lua new file mode 100644 index 0000000..3153c80 --- /dev/null +++ b/monarch/utils/callback_tracker.lua @@ -0,0 +1,39 @@ +local M = {} + + +function M.create() + local instance = {} + + local callback = nil + local callback_count = 0 + + --- Create a callback function and track when it is done + -- @return Callback function + function instance.track() + callback_count = callback_count + 1 + return function() + callback_count = callback_count - 1 + if callback_count == 0 and callback then + callback() + end + end + end + + --- Call a function when all callbacks have been triggered + -- @param cb Function to call when all + function instance.when_done(cb) + callback = cb + if callback_count == 0 then + callback() + end + end + + return instance +end + + +return setmetatable(M, { + __call = function(_, ...) + return M.create(...) + end +}) \ No newline at end of file