summaryrefslogtreecommitdiff
path: root/lua/clever_f/action_facade.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lua/clever_f/action_facade.lua')
-rw-r--r--lua/clever_f/action_facade.lua67
1 files changed, 67 insertions, 0 deletions
diff --git a/lua/clever_f/action_facade.lua b/lua/clever_f/action_facade.lua
new file mode 100644
index 0000000..5d8da67
--- /dev/null
+++ b/lua/clever_f/action_facade.lua
@@ -0,0 +1,67 @@
+local domain = require("clever_f.domain")
+local sequence_coordinator = require("clever_f.sequence_coordinator")
+
+local M = {}
+local ActionFacade = {}
+ActionFacade.__index = ActionFacade
+M.ActionFacade = ActionFacade
+
+local facade_records = setmetatable({}, { __mode = "k" })
+
+local function fail(message, level)
+ error(message, (level or 1) + 1)
+end
+
+function ActionFacade.new(options)
+ if ActionFacade.is(options) then
+ return options
+ end
+ local coordinator
+ if sequence_coordinator.SequenceCoordinator.is(options) then
+ coordinator = options
+ elseif type(options) == "table" then
+ coordinator = options.coordinator
+ or options.sequence_coordinator
+ or sequence_coordinator.new(options)
+ else
+ fail("ActionFacade options must be a table", 2)
+ end
+ if not sequence_coordinator.SequenceCoordinator.is(coordinator) then
+ fail("ActionFacade requires a SequenceCoordinator", 2)
+ end
+
+ local facade = setmetatable({}, ActionFacade)
+ facade_records[facade] = { coordinator = coordinator }
+ return facade
+end
+
+function ActionFacade.is(value)
+ return type(value) == "table" and facade_records[value] ~= nil
+end
+
+function ActionFacade:coordinator()
+ return facade_records[self].coordinator
+end
+
+function ActionFacade:primary(descriptor)
+ local outcome = self:coordinator():primary(descriptor)
+ if not domain.ActionOutcome.is(outcome) then
+ fail("SequenceCoordinator must return an ActionOutcome", 2)
+ end
+ return outcome
+end
+
+ActionFacade.invoke_primary = ActionFacade.primary
+ActionFacade.start = ActionFacade.primary
+
+function M.new(options)
+ return ActionFacade.new(options)
+end
+
+setmetatable(M, {
+ __call = function(_, options)
+ return ActionFacade.new(options)
+ end,
+})
+
+return M