util/events.lua
author Waqas Hussain <waqas20@gmail.com>
Sun, 17 May 2009 02:06:35 +0500
changeset 1180 8c5d945c1f35
parent 1175 edef0c10e076
child 1181 dffbb7d1da4b
permissions -rw-r--r--
util.events: Much more efficient index building
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
936
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     1
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     2
local ipairs = ipairs;
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     3
local pairs = pairs;
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     4
local t_insert = table.insert;
1175
edef0c10e076 util.events: handler priorities
Waqas Hussain <waqas20@gmail.com>
parents: 1146
diff changeset
     5
local t_sort = table.sort;
936
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     6
local select = select;
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     7
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     8
module "events"
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     9
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    10
function new()
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    11
	local dispatchers = {};
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    12
	local handlers = {};
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    13
	local event_map = {};
1180
8c5d945c1f35 util.events: Much more efficient index building
Waqas Hussain <waqas20@gmail.com>
parents: 1175
diff changeset
    14
	local function _rebuild_index(event) -- TODO optimize index rebuilding
8c5d945c1f35 util.events: Much more efficient index building
Waqas Hussain <waqas20@gmail.com>
parents: 1175
diff changeset
    15
		local _handlers = event_map[event];
8c5d945c1f35 util.events: Much more efficient index building
Waqas Hussain <waqas20@gmail.com>
parents: 1175
diff changeset
    16
		local index = handlers[event];
8c5d945c1f35 util.events: Much more efficient index building
Waqas Hussain <waqas20@gmail.com>
parents: 1175
diff changeset
    17
		if index then
8c5d945c1f35 util.events: Much more efficient index building
Waqas Hussain <waqas20@gmail.com>
parents: 1175
diff changeset
    18
			for i=#index,1,-1 do index[i] = nil; end
8c5d945c1f35 util.events: Much more efficient index building
Waqas Hussain <waqas20@gmail.com>
parents: 1175
diff changeset
    19
		else index = {}; handlers[event] = index; end
8c5d945c1f35 util.events: Much more efficient index building
Waqas Hussain <waqas20@gmail.com>
parents: 1175
diff changeset
    20
		for handler in pairs(_handlers) do
8c5d945c1f35 util.events: Much more efficient index building
Waqas Hussain <waqas20@gmail.com>
parents: 1175
diff changeset
    21
			t_insert(index, handler);
936
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    22
		end
1180
8c5d945c1f35 util.events: Much more efficient index building
Waqas Hussain <waqas20@gmail.com>
parents: 1175
diff changeset
    23
		t_sort(index, function(a, b) return _handlers[a] > _handlers[b]; end);
936
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    24
	end;
1175
edef0c10e076 util.events: handler priorities
Waqas Hussain <waqas20@gmail.com>
parents: 1146
diff changeset
    25
	local function add_handler(event, handler, priority)
936
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    26
		local map = event_map[event];
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    27
		if map then
1175
edef0c10e076 util.events: handler priorities
Waqas Hussain <waqas20@gmail.com>
parents: 1146
diff changeset
    28
			map[handler] = priority or 0;
936
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    29
		else
1175
edef0c10e076 util.events: handler priorities
Waqas Hussain <waqas20@gmail.com>
parents: 1146
diff changeset
    30
			map = {[handler] = priority or 0};
936
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    31
			event_map[event] = map;
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    32
		end
1180
8c5d945c1f35 util.events: Much more efficient index building
Waqas Hussain <waqas20@gmail.com>
parents: 1175
diff changeset
    33
		_rebuild_index(event);
936
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    34
	end;
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    35
	local function remove_handler(event, handler)
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    36
		local map = event_map[event];
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    37
		if map then
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    38
			map[handler] = nil;
1180
8c5d945c1f35 util.events: Much more efficient index building
Waqas Hussain <waqas20@gmail.com>
parents: 1175
diff changeset
    39
			_rebuild_index(event);
936
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    40
		end
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    41
	end;
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    42
	local function add_plugin(plugin)
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    43
		for event, handler in pairs(plugin) do
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    44
			add_handler(event, handler);
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    45
		end
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    46
	end;
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    47
	local function remove_plugin(plugin)
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    48
		for event, handler in pairs(plugin) do
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    49
			remove_handler(event, handler);
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    50
		end
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    51
	end;
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    52
	local function _create_dispatcher(event) -- FIXME duplicate code in fire_event
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    53
		local h = handlers[event];
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    54
		if not h then h = {}; handlers[event] = h; end
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    55
		local dispatcher = function(data)
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    56
			for _, handler in ipairs(h) do
1146
542d49518d3a util.events: event handlers can now return a result, which also interrupts further handling of the event
Waqas Hussain <waqas20@gmail.com>
parents: 936
diff changeset
    57
				local ret = handler(data);
542d49518d3a util.events: event handlers can now return a result, which also interrupts further handling of the event
Waqas Hussain <waqas20@gmail.com>
parents: 936
diff changeset
    58
				if ret ~= nil then return ret; end
936
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    59
			end
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    60
		end;
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    61
		dispatchers[event] = dispatcher;
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    62
		return dispatcher;
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    63
	end;
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    64
	local function get_dispatcher(event)
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    65
		return dispatchers[event] or _create_dispatcher(event);
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    66
	end;
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    67
	local function fire_event(event, data) -- FIXME duplicates dispatcher code
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    68
		local h = handlers[event];
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    69
		if h then
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    70
			for _, handler in ipairs(h) do
1146
542d49518d3a util.events: event handlers can now return a result, which also interrupts further handling of the event
Waqas Hussain <waqas20@gmail.com>
parents: 936
diff changeset
    71
				local ret = handler(data);
542d49518d3a util.events: event handlers can now return a result, which also interrupts further handling of the event
Waqas Hussain <waqas20@gmail.com>
parents: 936
diff changeset
    72
				if ret ~= nil then return ret; end
936
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    73
			end
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    74
		end
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    75
	end;
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    76
	local function get_named_arg_dispatcher(event, ...)
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    77
		local dispatcher = get_dispatcher(event);
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    78
		local keys = {...};
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    79
		local data = {};
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    80
		return function(...)
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    81
			for i, key in ipairs(keys) do data[key] = select(i, ...); end
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    82
			dispatcher(data);
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    83
		end;
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    84
	end;
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    85
	return {
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    86
		add_handler = add_handler;
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    87
		remove_handler = remove_handler;
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    88
		add_plugin = add_plugin;
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    89
		remove_plugin = remove_plugin;
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    90
		get_dispatcher = get_dispatcher;
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    91
		fire_event = fire_event;
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    92
		get_named_arg_dispatcher = get_named_arg_dispatcher;
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    93
		_dispatchers = dispatchers;
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    94
		_handlers = handlers;
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    95
		_event_map = event_map;
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    96
	};
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    97
end
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    98
5663db788fdf Added: util/events.lua: An event handling library
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    99
return _M;