diff --git a/data/lua/core.lua b/data/lua/core.lua index 4e171ef3f4bc..246174a6de59 100644 --- a/data/lua/core.lua +++ b/data/lua/core.lua @@ -372,6 +372,56 @@ if wesnoth.kernel_type() == "Game Lua Kernel" then wml.array_access.set(key, value) end }) + + -- Facility to register hooks without interfering with other hooks + -- Based on on_event() + local hooks = {} + local hooks_mt = { + __metatable = "Wesnoth hooks registry", + __newindex = function(_, k, v) + wesnoth.hooks.register(k, v) + end, + __index = function(_, k) + -- Return a COPY of the hooks list + local matching = {} + for i = 1, #hooks[k] do + table.insert(matching, hooks[k][i]) + end + return matching + end + } + + wesnoth.hooks = setmetatable({}, hooks_mt) + + function wesnoth.hooks.register(name, arg1, arg2) + local priority = 0 + local handler + if type(arg1) == "function" then + handler = arg1 + else + priority = arg1 + handler = arg2 + end + if hooks[name] == nil then + -- Register the handler in the old way + hooks[name] = {} + local old_hook = wesnoth.game_events[name] or function(...) end + wesnoth.game_events[name] = function(...) + local ret = old_hook(...) + for k,v in pairs(hooks[name] or {}) do + v.h(...) + end + end + end + local hl = hooks[name] + table.insert(hooks[hl], {h = handler, p = priority}) + -- sort it. + for i = #hl - 1, 1, -1 do + if hl[i].p < hl[i + 1].p then + hl[i], hl[i + 1] = hl[i + 1], hl[i] + end + end + end end -- Some C++ functions are deprecated; apply the messages here.