Hooks
A custom hooks system for your LUA script
Do Action / Add Action
Definitions
doAction(name: string, context: any [, context2 ...]) -> nil
addAction(name: string, callback: function, opt priority: integer) -> nil
Usage example
init.lua
registerForEvent('oninit', function()
-- execute all addAction() using this name
doAction('my_action', 'init', 'something')
end)
my_script.lua
addAction('my_action', function(context, context2)
-- context = 'init'
-- context2 = 'something'
-- do something
end, 10)
my_script_2.lua
addAction('my_action', function(context, context2)
-- context = 'init'
-- context2 = 'something'
-- do something before (note the priority: 5)
end, 5)
Apply Filters / Add Filter
Definitions
applyFilters(name: string, value: any, context: any [, context2 ...]) -> nil
addFilter(name: string, callback: function, opt priority: integer) -> nil
Usage example
init.lua
registerForEvent('oninit', function()
local myVar = 'yes'
myVar = applyFilters('my_filter', myVar, 'init', 'something')
print(myVar)
-- no
end)
my_script.lua
addFilter('my_filter', function(myVar, context, context2)
-- myVar = 'maybe' (set by the other filter with priortiy: 5)
-- context = 'init'
-- context2 = 'something'
-- update myVar to 'no'
return 'no'
end, 10)
my_script_2.lua
addFilter('my_filter', function(myVar, context, context2)
-- myVar = 'yes' (set by initial applyFilters())
-- context = 'init'
-- context2 = 'something'
-- update myVar to 'maybe' (note the priority: 5)
return 'maybe'
end, 5)
Source Code
local this
this = {
storage = {
actions = {},
filters = {}
},
addAction = function(action, callback, priority, context)
if type(action) == 'string' and type(callback) == 'function' then
priority = tonumber(priority or 10)
this._addHook('actions', action, callback, priority, context)
end
return this
end,
doAction = function(...)
local args = { ... }
local action = table.remove(args, 1)
if type(action) == 'string' then
this._runHook('actions', action, args)
end
return this
end,
removeAction = function(action, callback)
if type(action) == 'string' then
this._removeHook('actions', action, callback)
end
return this
end,
addFilter = function(filter, callback, priority, context)
if type(filter) == 'string' and type(callback) == 'function' then
priority = tonumber(priority or 10)
this._addHook('filters', filter, callback, priority, context)
end
return this
end,
applyFilters = function(...)
local args = { ... }
local filter = table.remove(args, 1)
if type(filter) == 'string' then
return this._runHook('filters', filter, args)
end
return this
end,
removeFilter = function(filter, callback)
if type(filter) == 'string' then
this._removeHook('filters', filter, callback)
end
return this
end,
_removeHook = function(type, hook, callback, context)
if not this.storage[type][hook] then
return
end
if not callback then
this.storage[type][hook] = {}
else
local handlers = this.storage[type][hook]
--local i
if not context then
for i = #handlers, 1, -1 do
if handlers[i].callback == callback then
table.remove(handlers, i)
end
end
else
for i = #handlers, 1, -1 do
local handler = handlers[i]
if handler.callback == callback and handler.context == context then
table.remove(handlers, i)
end
end
end
end
end,
_addHook = function(type, hook, callback, priority, context)
local hookObject = {
callback = callback,
priority = priority,
context = context
}
local hooks = this.storage[type][hook]
if hooks then
table.insert(hooks, hookObject)
hooks = this._hookInsertSort(hooks)
else
hooks = { hookObject }
end
this.storage[type][hook] = hooks
end,
_hookInsertSort = function(hooks)
local tmpHook, j, prevHook
for i = 2, #hooks do
tmpHook = hooks[i]
j = i
prevHook = hooks[j - 1]
while prevHook and prevHook.priority > tmpHook.priority do
hooks[j] = hooks[j - 1]
j = j - 1
prevHook = hooks[j - 1]
end
hooks[j] = tmpHook
end
return hooks
end,
_runHook = function(type, hook, args)
local handlers = this.storage[type][hook]
if not handlers then
return type == 'filters' and args[1] or false
end
local i = 1
local len = #handlers
if type == 'filters' then
for i = 1, len do
args[1] = handlers[i].callback(unpack(args))
end
else
for i = 1, len do
handlers[i].callback(unpack(args))
end
end
return type == 'filters' and args[1] or true
end
}
-- history storage
local actionHistory = {}
addAction = function(...)
this.addAction(...)
return this
end
removeAction = function(...)
this.removeAction(...)
return this
end
doAction = function(...)
local args = {...}
local action = args[1]
actionHistory[action] = 1
this.doAction(...)
actionHistory[action] = 0
return this
end
doingAction = function(action)
return actionHistory[action] == 1
end
didAction = function(action)
return actionHistory[action] ~= nil
end
currentAction = function()
for k in pairs(actionHistory) do
if actionHistory[k] then
return k
end
end
return false
end
addFilter = function(...)
this.addFilter(...)
return this
end
removeFilter = function(...)
this.removeFilter(...)
return this
end
applyFilters = function(...)
return this.applyFilters(...)
end
Last updated