97 lines
1.8 KiB
Lua
97 lines
1.8 KiB
Lua
|
|
local action_mt = {}
|
|
|
|
action_mt.create = function(mod)
|
|
local mt = {
|
|
__call = function(t, ...)
|
|
local values = {}
|
|
for _, v in ipairs(t) do
|
|
local func = t._replacements[v] or mod[v]
|
|
|
|
if t._pre[v] then
|
|
t._pre[v](...)
|
|
end
|
|
|
|
local result = {func(...)}
|
|
for _, res in ipairs(result) do
|
|
table.insert(values, res)
|
|
end
|
|
|
|
if t._post[v] then
|
|
t._post[v](...)
|
|
end
|
|
end
|
|
|
|
return unpack(values)
|
|
end,
|
|
|
|
__add = function(lhs, rhs)
|
|
local new_actions = {}
|
|
for _, v in ipairs(lhs) do
|
|
table.insert(new_actions, v)
|
|
end
|
|
|
|
for _, v in ipairs(rhs) do
|
|
table.insert(new_actions, v)
|
|
end
|
|
|
|
return setmetatable(new_actions, getmetatable(lhs))
|
|
end,
|
|
|
|
_pre = {},
|
|
_replacements = {},
|
|
_post = {},
|
|
}
|
|
|
|
mt.__index = mt
|
|
|
|
mt.clear = function()
|
|
mt._pre = {}
|
|
mt._replacements = {}
|
|
mt._post = {}
|
|
end
|
|
|
|
--- Replace the reference to the function with a new one temporarily
|
|
function mt:replace(v)
|
|
assert(#self == 1, "Cannot replace an already combined action")
|
|
|
|
local action_name = self[1]
|
|
mt._replacements[action_name] = v
|
|
end
|
|
|
|
function mt:enhance(opts)
|
|
assert(#self == 1, "Cannot enhance already combined actions")
|
|
|
|
local action_name = self[1]
|
|
if opts.pre then
|
|
mt._pre[action_name] = opts.pre
|
|
end
|
|
|
|
if opts.post then
|
|
mt._post[action_name] = opts.post
|
|
end
|
|
end
|
|
|
|
return mt
|
|
end
|
|
|
|
action_mt.transform = function(k, mt)
|
|
return setmetatable({k}, mt)
|
|
end
|
|
|
|
action_mt.transform_mod = function(mod)
|
|
local mt = action_mt.create(mod)
|
|
|
|
local redirect = {}
|
|
|
|
for k, _ in pairs(mod) do
|
|
redirect[k] = action_mt.transform(k, mt)
|
|
end
|
|
|
|
redirect._clear = mt.clear
|
|
|
|
return redirect
|
|
end
|
|
|
|
return action_mt
|