4 local t_insert = table.insert;
5 local t_sort = table.sort;
11 local dispatchers = {};
14 local function _rebuild_index(event) -- TODO optimize index rebuilding
15 local _handlers = event_map[event];
16 local index = handlers[event];
18 for i=#index,1,-1 do index[i] = nil; end
19 else index = {}; handlers[event] = index; end
20 for handler in pairs(_handlers) do
21 t_insert(index, handler);
23 t_sort(index, function(a, b) return _handlers[a] > _handlers[b]; end);
25 local function add_handler(event, handler, priority)
26 local map = event_map[event];
28 map[handler] = priority or 0;
30 map = {[handler] = priority or 0};
31 event_map[event] = map;
33 _rebuild_index(event);
35 local function remove_handler(event, handler)
36 local map = event_map[event];
39 _rebuild_index(event);
42 local function add_plugin(plugin)
43 for event, handler in pairs(plugin) do
44 add_handler(event, handler);
47 local function remove_plugin(plugin)
48 for event, handler in pairs(plugin) do
49 remove_handler(event, handler);
52 local function _create_dispatcher(event) -- FIXME duplicate code in fire_event
53 local h = handlers[event];
54 if not h then h = {}; handlers[event] = h; end
55 local dispatcher = function(...)
57 local ret = h[i](...);
58 if ret ~= nil then return ret; end
61 dispatchers[event] = dispatcher;
64 local function get_dispatcher(event)
65 return dispatchers[event] or _create_dispatcher(event);
67 local function fire_event(event, ...) -- FIXME duplicates dispatcher code
68 local h = handlers[event];
71 local ret = h[i](...);
72 if ret ~= nil then return ret; end
76 local function get_named_arg_dispatcher(event, ...)
77 local dispatcher = get_dispatcher(event);
81 for i, key in ipairs(keys) do data[key] = select(i, ...); end
86 add_handler = add_handler;
87 remove_handler = remove_handler;
88 add_plugin = add_plugin;
89 remove_plugin = remove_plugin;
90 get_dispatcher = get_dispatcher;
91 fire_event = fire_event;
92 get_named_arg_dispatcher = get_named_arg_dispatcher;
93 _dispatchers = dispatchers;
95 _event_map = event_map;