2 -- Copyright (C) 2008-2010 Matthew Wild
3 -- Copyright (C) 2008-2010 Waqas Hussain
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
11 local t_insert
= table.insert
;
12 local t_remove
= table.remove;
13 local t_sort
= table.sort;
14 local setmetatable
= setmetatable
;
21 -- Map event name to ordered list of handlers (lazily built): handlers[event_name] = array_of_handler_functions
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
27 -- Event map: event_map[handler_function] = priority_number
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
34 for handler
in pairs(_handlers
) do
35 t_insert(index
, handler
);
37 t_sort(index
, function(a
, b
) return _handlers
[a
] > _handlers
[b
]; end);
41 setmetatable(handlers
, { __index
= _rebuild_index
});
42 local function add_handler(event
, handler
, priority
)
43 local map
= event_map
[event
];
45 map
[handler
] = priority
or 0;
47 map
= {[handler
] = priority
or 0};
48 event_map
[event
] = map
;
50 handlers
[event
] = nil;
52 local function remove_handler(event
, handler
)
53 local map
= event_map
[event
];
56 handlers
[event
] = nil;
57 if next(map
) == nil then
58 event_map
[event
] = nil;
62 local function get_handlers(event
)
63 return handlers
[event
];
65 local function add_handlers(self
)
66 for event
, handler
in pairs(self
) do
67 add_handler(event
, handler
);
70 local function remove_handlers(self
)
71 for event
, handler
in pairs(self
) do
72 remove_handler(event
, handler
);
75 local function _fire_event(event_name
, event_data
)
76 local h
= handlers
[event_name
];
79 local ret
= h
[i
](event_data
);
80 if ret
~= nil then return ret
; 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
;
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
);
95 w
, curr_wrapper
= global_wrappers
, #global_wrappers
;
96 return w
[curr_wrapper
](c
, event_name
, event_data
);
98 return w
[curr_wrapper
](c
, event_name
, event_data
);
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
)
107 if event_name
== false then
114 w
= wrappers
[event_name
];
117 wrappers
[event_name
] = w
;
122 local function remove_wrapper(event_name
, wrapper
)
124 if event_name
== false then
127 w
= wrappers
[event_name
];
129 if not w
then return; end
131 if w
[i
] == wrapper
then
136 if event_name
== false then
137 global_wrappers
= nil;
139 wrappers
[event_name
] = nil;
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
;
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
;