Software /
code /
prosody
File
util/events.lua @ 4651:d1739d72100a
moduleapi: Have modules internally store a reference to shared tables they use, to ensure they don't get collected while any module that had access to that table is still loaded (thanks Zash)
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Sat, 21 Apr 2012 22:52:15 +0100 |
parent | 3776:bc4f67a0658d |
child | 5749:60b3b6d27364 |
line wrap: on
line source
-- 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. -- local pairs = pairs; local t_insert = table.insert; local t_sort = table.sort; local setmetatable = setmetatable; local next = next; module "events" function new() local handlers = {}; local event_map = {}; local function _rebuild_index(handlers, event) local _handlers = event_map[event]; if not _handlers or next(_handlers) == nil then return; end local index = {}; for handler in pairs(_handlers) do t_insert(index, handler); end t_sort(index, function(a, b) return _handlers[a] > _handlers[b]; end); handlers[event] = index; return index; end; setmetatable(handlers, { __index = _rebuild_index }); local function add_handler(event, handler, priority) local map = event_map[event]; if map then map[handler] = priority or 0; else map = {[handler] = priority or 0}; event_map[event] = map; end handlers[event] = nil; end; local function remove_handler(event, handler) local map = event_map[event]; if map then map[handler] = nil; handlers[event] = nil; if next(map) == nil then event_map[event] = nil; end end end; local function add_handlers(handlers) for event, handler in pairs(handlers) do add_handler(event, handler); end end; local function remove_handlers(handlers) for event, handler in pairs(handlers) do remove_handler(event, handler); end end; local function fire_event(event, ...) local h = handlers[event]; if h then for i=1,#h do local ret = h[i](...); if ret ~= nil then return ret; end end end end; return { add_handler = add_handler; remove_handler = remove_handler; add_handlers = add_handlers; remove_handlers = remove_handlers; fire_event = fire_event; _handlers = handlers; _event_map = event_map; }; end return _M;