luajitos

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

Hook.lua (5083B)


      1 -- Hook.lua - Event hook system for LuajitOS
      2 -- Allows registering and running event callbacks with priority and control flow
      3 
      4 local Hook = {
      5     instances = {}
      6 }
      7 
      8 -- Create a new hook instance
      9 -- Returns a new hook object with add, remove, and run methods
     10 function Hook.newInstance()
     11     local instance = {
     12         hooks = {}  -- Structure: { [eventName] = { {name=hookName, func=callback}, ... } }
     13     }
     14 
     15     -- Add a hook for an event
     16     -- @param eventName: The name of the event to hook into
     17     -- @param hookName: Unique identifier for this hook
     18     -- @param callback: Function to call when event is triggered
     19     function instance:add(eventName, hookName, callback)
     20         if type(eventName) ~= "string" or eventName == "" then
     21             error("Hook.add: eventName must be a non-empty string")
     22         end
     23 
     24         if type(hookName) ~= "string" or hookName == "" then
     25             error("Hook.add: hookName must be a non-empty string")
     26         end
     27 
     28         if type(callback) ~= "function" then
     29             error("Hook.add: callback must be a function")
     30         end
     31 
     32         -- Initialize event hook list if it doesn't exist
     33         if not self.hooks[eventName] then
     34             self.hooks[eventName] = {}
     35         end
     36 
     37         -- Check if hook with this name already exists for this event
     38         for i, hook in ipairs(self.hooks[eventName]) do
     39             if hook.name == hookName then
     40                 -- Replace existing hook
     41                 hook.func = callback
     42                 return
     43             end
     44         end
     45 
     46         -- Add new hook
     47         table.insert(self.hooks[eventName], {
     48             name = hookName,
     49             func = callback
     50         })
     51     end
     52 
     53     -- Remove hook(s) from an event
     54     -- @param eventName: The name of the event
     55     -- @param hookName: (optional) Specific hook name to remove. If nil, removes all hooks for the event
     56     function instance:remove(eventName, hookName)
     57         if type(eventName) ~= "string" or eventName == "" then
     58             error("Hook.remove: eventName must be a non-empty string")
     59         end
     60 
     61         if not self.hooks[eventName] then
     62             return  -- No hooks for this event
     63         end
     64 
     65         if hookName == nil then
     66             -- Remove all hooks for this event
     67             self.hooks[eventName] = nil
     68         else
     69             -- Remove specific hook
     70             if type(hookName) ~= "string" then
     71                 error("Hook.remove: hookName must be a string or nil")
     72             end
     73 
     74             for i = #self.hooks[eventName], 1, -1 do
     75                 if self.hooks[eventName][i].name == hookName then
     76                     table.remove(self.hooks[eventName], i)
     77                     break
     78                 end
     79             end
     80 
     81             -- Clean up empty event table
     82             if #self.hooks[eventName] == 0 then
     83                 self.hooks[eventName] = nil
     84             end
     85         end
     86     end
     87 
     88     -- Run all hooks for an event
     89     -- @param eventName: The name of the event to trigger
     90     -- @param ...: Arguments to pass to each hook callback
     91     -- @return: true if any hook returned true (stopping execution), false otherwise
     92     function instance:run(eventName, ...)
     93         if type(eventName) ~= "string" or eventName == "" then
     94             error("Hook.run: eventName must be a non-empty string")
     95         end
     96 
     97         if not self.hooks[eventName] then
     98             return false  -- No hooks for this event
     99         end
    100 
    101         -- Run each hook in order
    102         for i, hook in ipairs(self.hooks[eventName]) do
    103             local success, result = pcall(hook.func, ...)
    104 
    105             if not success then
    106                 -- Hook threw an error - log it but continue
    107                 if osprint then
    108                     osprint("Hook error in '" .. eventName .. "' hook '" .. hook.name .. "': " .. tostring(result))
    109                 end
    110             elseif result == true then
    111                 -- Hook returned true - stop executing remaining hooks
    112                 return true
    113             end
    114         end
    115 
    116         return false
    117     end
    118 
    119     -- Get all hook names for an event
    120     -- @param eventName: The name of the event
    121     -- @return: Array of hook names, or empty array if no hooks
    122     function instance:getHooks(eventName)
    123         if type(eventName) ~= "string" or eventName == "" then
    124             error("Hook.getHooks: eventName must be a non-empty string")
    125         end
    126 
    127         if not self.hooks[eventName] then
    128             return {}
    129         end
    130 
    131         local names = {}
    132         for i, hook in ipairs(self.hooks[eventName]) do
    133             table.insert(names, hook.name)
    134         end
    135 
    136         return names
    137     end
    138 
    139     -- Get all event names that have hooks
    140     -- @return: Array of event names
    141     function instance:getEvents()
    142         local events = {}
    143         for eventName, _ in pairs(self.hooks) do
    144             table.insert(events, eventName)
    145         end
    146         return events
    147     end
    148 
    149     -- Clear all hooks from this instance
    150     function instance:clear()
    151         self.hooks = {}
    152     end
    153 
    154     -- Store instance
    155     table.insert(Hook.instances, instance)
    156 
    157     return instance
    158 end
    159 
    160 return Hook