Prepare required data folder for integration tests
[prosody.git] / util / events.lua
blob0bf0ddcb3cbd147c65cc7432f50e3df34b40cefd
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 --
10 local pairs = pairs;
11 local t_insert = table.insert;
12 local t_remove = table.remove;
13 local t_sort = table.sort;
14 local setmetatable = setmetatable;
15 local next = next;
17 local _ENV = nil;
18 -- luacheck: std none
20 local function new()
21 -- Map event name to ordered list of handlers (lazily built): handlers[event_name] = array_of_handler_functions
22 local handlers = {};
23 -- Array of wrapper functions that wrap all events (nil if empty)
24 local global_wrappers;
25 -- Per-event wrappers: wrappers[event_name] = wrapper_function
26 local wrappers = {};
27 -- Event map: event_map[handler_function] = priority_number
28 local event_map = {};
29 -- Called on-demand to build handlers entries
30 local function _rebuild_index(self, event)
31 local _handlers = event_map[event];
32 if not _handlers or next(_handlers) == nil then return; end
33 local index = {};
34 for handler in pairs(_handlers) do
35 t_insert(index, handler);
36 end
37 t_sort(index, function(a, b) return _handlers[a] > _handlers[b]; end);
38 self[event] = index;
39 return index;
40 end;
41 setmetatable(handlers, { __index = _rebuild_index });
42 local function add_handler(event, handler, priority)
43 local map = event_map[event];
44 if map then
45 map[handler] = priority or 0;
46 else
47 map = {[handler] = priority or 0};
48 event_map[event] = map;
49 end
50 handlers[event] = nil;
51 end;
52 local function remove_handler(event, handler)
53 local map = event_map[event];
54 if map then
55 map[handler] = nil;
56 handlers[event] = nil;
57 if next(map) == nil then
58 event_map[event] = nil;
59 end
60 end
61 end;
62 local function get_handlers(event)
63 return handlers[event];
64 end;
65 local function add_handlers(self)
66 for event, handler in pairs(self) do
67 add_handler(event, handler);
68 end
69 end;
70 local function remove_handlers(self)
71 for event, handler in pairs(self) do
72 remove_handler(event, handler);
73 end
74 end;
75 local function _fire_event(event_name, event_data)
76 local h = handlers[event_name];
77 if h then
78 for i=1,#h do
79 local ret = h[i](event_data);
80 if ret ~= nil then return ret; end
81 end
82 end
83 end;
84 local function fire_event(event_name, event_data)
85 -- luacheck: ignore 432/event_name 432/event_data
86 local w = wrappers[event_name] or global_wrappers;
87 if w then
88 local curr_wrapper = #w;
89 local function c(event_name, event_data)
90 curr_wrapper = curr_wrapper - 1;
91 if curr_wrapper == 0 then
92 if global_wrappers == nil or w == global_wrappers then
93 return _fire_event(event_name, event_data);
94 end
95 w, curr_wrapper = global_wrappers, #global_wrappers;
96 return w[curr_wrapper](c, event_name, event_data);
97 else
98 return w[curr_wrapper](c, event_name, event_data);
99 end
101 return w[curr_wrapper](c, event_name, event_data);
103 return _fire_event(event_name, event_data);
105 local function add_wrapper(event_name, wrapper)
106 local w;
107 if event_name == false then
108 w = global_wrappers;
109 if not w then
110 w = {};
111 global_wrappers = w;
113 else
114 w = wrappers[event_name];
115 if not w then
116 w = {};
117 wrappers[event_name] = w;
120 w[#w+1] = wrapper;
122 local function remove_wrapper(event_name, wrapper)
123 local w;
124 if event_name == false then
125 w = global_wrappers;
126 else
127 w = wrappers[event_name];
129 if not w then return; end
130 for i = #w, 1, -1 do
131 if w[i] == wrapper then
132 t_remove(w, i);
135 if #w == 0 then
136 if event_name == false then
137 global_wrappers = nil;
138 else
139 wrappers[event_name] = nil;
143 return {
144 add_handler = add_handler;
145 remove_handler = remove_handler;
146 add_handlers = add_handlers;
147 remove_handlers = remove_handlers;
148 get_handlers = get_handlers;
149 wrappers = {
150 add_handler = add_wrapper;
151 remove_handler = remove_wrapper;
153 add_wrapper = add_wrapper;
154 remove_wrapper = remove_wrapper;
155 fire_event = fire_event;
156 _handlers = handlers;
157 _event_map = event_map;
161 return {
162 new = new;