Merge 0.9->0.10
[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 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_name, event_data)
64                 local h = handlers[event_name];
65                 if h then
66                         for i=1,#h do
67                                 local ret = h[i](event_data);
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;