util.events: Fixed the exposed API for adding/removing sets of event handlers.
[prosody.git] / util / events.lua
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
14 module "events"
15
16 function new()
17         local handlers = {};
18         local event_map = {};
19         local function _rebuild_index(event) -- TODO optimize index rebuilding
20                 local _handlers = event_map[event];
21                 local index = handlers[event];
22                 if index then
23                         for i=#index,1,-1 do index[i] = nil; end
24                 else index = {}; handlers[event] = index; end
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         end;
30         local function add_handler(event, handler, priority)
31                 local map = event_map[event];
32                 if map then
33                         map[handler] = priority or 0;
34                 else
35                         map = {[handler] = priority or 0};
36                         event_map[event] = map;
37                 end
38                 _rebuild_index(event);
39         end;
40         local function remove_handler(event, handler)
41                 local map = event_map[event];
42                 if map then
43                         map[handler] = nil;
44                         _rebuild_index(event);
45                 end
46         end;
47         local function add_handlers(handlers)
48                 for event, handler in pairs(handlers) do
49                         add_handler(event, handler);
50                 end
51         end;
52         local function remove_handlers(handlers)
53                 for event, handler in pairs(handlers) do
54                         remove_handler(event, handler);
55                 end
56         end;
57         local function fire_event(event, ...)
58                 local h = handlers[event];
59                 if h then
60                         for i=1,#h do
61                                 local ret = h[i](...);
62                                 if ret ~= nil then return ret; end
63                         end
64                 end
65         end;
66         return {
67                 add_handler = add_handler;
68                 remove_handler = remove_handler;
69                 add_handlers = add_handlers;
70                 remove_handlers = remove_handlers;
71                 fire_event = fire_event;
72                 _handlers = handlers;
73                 _event_map = event_map;
74         };
75 end
76
77 return _M;