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, ...)
64
		local h = handlers[event];
65
		if h then
66
			for i=1,#h do
67
				local ret = h[i](...);
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;