aboutsummaryrefslogtreecommitdiffstats
path: root/util/events.lua
diff options
context:
space:
mode:
Diffstat (limited to 'util/events.lua')
-rw-r--r--util/events.lua87
1 files changed, 80 insertions, 7 deletions
diff --git a/util/events.lua b/util/events.lua
index 412acccd..825ffb19 100644
--- a/util/events.lua
+++ b/util/events.lua
@@ -1,7 +1,7 @@
-- Prosody IM
-- Copyright (C) 2008-2010 Matthew Wild
-- Copyright (C) 2008-2010 Waqas Hussain
---
+--
-- This project is MIT/X11 licensed. Please see the
-- COPYING file in the source package for more information.
--
@@ -9,14 +9,17 @@
local pairs = pairs;
local t_insert = table.insert;
+local t_remove = table.remove;
local t_sort = table.sort;
local setmetatable = setmetatable;
local next = next;
-module "events"
+local _ENV = nil;
-function new()
+local function new()
local handlers = {};
+ local global_wrappers;
+ local wrappers = {};
local event_map = {};
local function _rebuild_index(handlers, event)
local _handlers = event_map[event];
@@ -50,6 +53,9 @@ function new()
end
end
end;
+ local function get_handlers(event)
+ return handlers[event];
+ end;
local function add_handlers(handlers)
for event, handler in pairs(handlers) do
add_handler(event, handler);
@@ -60,24 +66,91 @@ function new()
remove_handler(event, handler);
end
end;
- local function fire_event(event, ...)
- local h = handlers[event];
+ local function _fire_event(event_name, event_data)
+ local h = handlers[event_name];
if h then
for i=1,#h do
- local ret = h[i](...);
+ local ret = h[i](event_data);
if ret ~= nil then return ret; end
end
end
end;
+ local function fire_event(event_name, event_data)
+ local w = wrappers[event_name] or global_wrappers;
+ if w then
+ local curr_wrapper = #w;
+ local function c(event_name, event_data)
+ curr_wrapper = curr_wrapper - 1;
+ if curr_wrapper == 0 then
+ if global_wrappers == nil or w == global_wrappers then
+ return _fire_event(event_name, event_data);
+ end
+ w, curr_wrapper = global_wrappers, #global_wrappers;
+ return w[curr_wrapper](c, event_name, event_data);
+ else
+ return w[curr_wrapper](c, event_name, event_data);
+ end
+ end
+ return w[curr_wrapper](c, event_name, event_data);
+ end
+ return _fire_event(event_name, event_data);
+ end
+ local function add_wrapper(event_name, wrapper)
+ local w;
+ if event_name == false then
+ w = global_wrappers;
+ if not w then
+ w = {};
+ global_wrappers = w;
+ end
+ else
+ w = wrappers[event_name];
+ if not w then
+ w = {};
+ wrappers[event_name] = w;
+ end
+ end
+ w[#w+1] = wrapper;
+ end
+ local function remove_wrapper(event_name, wrapper)
+ local w;
+ if event_name == false then
+ w = global_wrappers;
+ else
+ w = wrappers[event_name];
+ end
+ if not w then return; end
+ for i = #w, 1 do
+ if w[i] == wrapper then
+ t_remove(w, i);
+ end
+ end
+ if #w == 0 then
+ if event_name == nil then
+ global_wrappers = nil;
+ else
+ wrappers[event_name] = nil;
+ end
+ end
+ end
return {
add_handler = add_handler;
remove_handler = remove_handler;
add_handlers = add_handlers;
remove_handlers = remove_handlers;
+ get_handlers = get_handlers;
+ wrappers = {
+ add_handler = add_wrapper;
+ remove_handler = remove_wrapper;
+ };
+ add_wrapper = add_wrapper;
+ remove_wrapper = remove_wrapper;
fire_event = fire_event;
_handlers = handlers;
_event_map = event_map;
};
end
-return _M;
+return {
+ new = new;
+};