diff options
Diffstat (limited to 'util/events.lua')
-rw-r--r-- | util/events.lua | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/util/events.lua b/util/events.lua new file mode 100644 index 00000000..412acccd --- /dev/null +++ b/util/events.lua @@ -0,0 +1,83 @@ +-- Prosody IM +-- Copyright (C) 2008-2010 Matthew Wild +-- Copyright (C) 2008-2010 Waqas Hussain +-- +-- This project is MIT/X11 licensed. Please see the +-- COPYING file in the source package for more information. +-- + + +local pairs = pairs; +local t_insert = table.insert; +local t_sort = table.sort; +local setmetatable = setmetatable; +local next = next; + +module "events" + +function new() + local handlers = {}; + local event_map = {}; + local function _rebuild_index(handlers, event) + local _handlers = event_map[event]; + if not _handlers or next(_handlers) == nil then return; end + local index = {}; + for handler in pairs(_handlers) do + t_insert(index, handler); + end + t_sort(index, function(a, b) return _handlers[a] > _handlers[b]; end); + handlers[event] = index; + return index; + end; + setmetatable(handlers, { __index = _rebuild_index }); + local function add_handler(event, handler, priority) + local map = event_map[event]; + if map then + map[handler] = priority or 0; + else + map = {[handler] = priority or 0}; + event_map[event] = map; + end + handlers[event] = nil; + end; + local function remove_handler(event, handler) + local map = event_map[event]; + if map then + map[handler] = nil; + handlers[event] = nil; + if next(map) == nil then + event_map[event] = nil; + end + end + end; + local function add_handlers(handlers) + for event, handler in pairs(handlers) do + add_handler(event, handler); + end + end; + local function remove_handlers(handlers) + for event, handler in pairs(handlers) do + remove_handler(event, handler); + end + end; + local function fire_event(event, ...) + local h = handlers[event]; + if h then + for i=1,#h do + local ret = h[i](...); + if ret ~= nil then return ret; end + end + end + end; + return { + add_handler = add_handler; + remove_handler = remove_handler; + add_handlers = add_handlers; + remove_handlers = remove_handlers; + fire_event = fire_event; + _handlers = handlers; + _event_map = event_map; + }; +end + +return _M; |