| 1 | -- Prosody IM |
| 2 | -- Copyright (C) 2008-2010 Matthew Wild |
| 3 | -- Copyright (C) 2008-2010 Waqas Hussain |
| 4 | -- |
| 5 | -- This project is MIT/X11 licensed. Please see the |
| 6 | -- COPYING file in the source package for more information. |
| 7 | -- |
| 8 | |
| 9 | |
| 10 | local pairs = pairs; |
| 11 | local t_insert = table.insert; |
| 12 | local t_sort = table.sort; |
| 13 | local setmetatable = setmetatable; |
| 14 | local next = next; |
| 15 | |
| 16 | module "events" |
| 17 | |
| 18 | function new() |
| 19 | local handlers = {}; |
| 20 | local event_map = {}; |
| 21 | local function _rebuild_index(handlers, event) |
| 22 | local _handlers = event_map[event]; |
| 23 | if not _handlers or next(_handlers) == nil then return; end |
| 24 | local index = {}; |
| 25 | for handler in pairs(_handlers) do |
| 26 | t_insert(index, handler); |
| 27 | end |
| 28 | t_sort(index, function(a, b) return _handlers[a] > _handlers[b]; end); |
| 29 | handlers[event] = index; |
| 30 | return index; |
| 31 | end; |
| 32 | setmetatable(handlers, { __index = _rebuild_index }); |
| 33 | local function add_handler(event, handler, priority) |
| 34 | local map = event_map[event]; |
| 35 | if map then |
| 36 | map[handler] = priority or 0; |
| 37 | else |
| 38 | map = {[handler] = priority or 0}; |
| 39 | event_map[event] = map; |
| 40 | end |
| 41 | handlers[event] = nil; |
| 42 | end; |
| 43 | local function remove_handler(event, handler) |
| 44 | local map = event_map[event]; |
| 45 | if map then |
| 46 | map[handler] = nil; |
| 47 | handlers[event] = nil; |
| 48 | if next(map) == nil then |
| 49 | event_map[event] = nil; |
| 50 | end |
| 51 | end |
| 52 | end; |
| 53 | local function add_handlers(handlers) |
| 54 | for event, handler in pairs(handlers) do |
| 55 | add_handler(event, handler); |
| 56 | end |
| 57 | end; |
| 58 | local function remove_handlers(handlers) |
| 59 | for event, handler in pairs(handlers) do |
| 60 | remove_handler(event, handler); |
| 61 | end |
| 62 | end; |
| 63 | local function fire_event(event, ...) |
| 64 | local h = handlers[event]; |
| 65 | if h then |
| 66 | for i=1,#h do |
| 67 | local ret = h[i](...); |
| 68 | if ret ~= nil then return ret; end |
| 69 | end |
| 70 | end |
| 71 | end; |
| 72 | return { |
| 73 | add_handler = add_handler; |
| 74 | remove_handler = remove_handler; |
| 75 | add_handlers = add_handlers; |
| 76 | remove_handlers = remove_handlers; |
| 77 | fire_event = fire_event; |
| 78 | _handlers = handlers; |
| 79 | _event_map = event_map; |
| 80 | }; |
| 81 | end |
| 82 | |
| 83 | return _M; |