Mercurial > prosody-hg
comparison util/events.lua @ 6638:9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Tue, 28 Apr 2015 13:42:59 +0100 |
| parents | bd0ff8ae98a8 |
| children | b44ebfe81c73 |
comparison
equal
deleted
inserted
replaced
| 6637:ecc039288edc | 6638:9d2b56fd6b47 |
|---|---|
| 15 | 15 |
| 16 module "events" | 16 module "events" |
| 17 | 17 |
| 18 function new() | 18 function new() |
| 19 local handlers = {}; | 19 local handlers = {}; |
| 20 local global_wrappers; | |
| 21 local wrappers = {}; | |
| 20 local event_map = {}; | 22 local event_map = {}; |
| 21 local function _rebuild_index(handlers, event) | 23 local function _rebuild_index(handlers, event) |
| 22 local _handlers = event_map[event]; | 24 local _handlers = event_map[event]; |
| 23 if not _handlers or next(_handlers) == nil then return; end | 25 if not _handlers or next(_handlers) == nil then return; end |
| 24 local index = {}; | 26 local index = {}; |
| 58 local function remove_handlers(handlers) | 60 local function remove_handlers(handlers) |
| 59 for event, handler in pairs(handlers) do | 61 for event, handler in pairs(handlers) do |
| 60 remove_handler(event, handler); | 62 remove_handler(event, handler); |
| 61 end | 63 end |
| 62 end; | 64 end; |
| 63 local function fire_event(event_name, event_data) | 65 local function _fire_event(event_name, event_data) |
| 64 local h = handlers[event_name]; | 66 local h = handlers[event_name]; |
| 65 if h then | 67 if h then |
| 66 for i=1,#h do | 68 for i=1,#h do |
| 67 local ret = h[i](event_data); | 69 local ret = h[i](event_data); |
| 68 if ret ~= nil then return ret; end | 70 if ret ~= nil then return ret; end |
| 69 end | 71 end |
| 70 end | 72 end |
| 71 end; | 73 end; |
| 74 local function fire_event(event_name, event_data) | |
| 75 local w = wrappers[event_name] or global_wrappers; | |
| 76 if w then | |
| 77 local curr_wrapper = #w; | |
| 78 local function c(event_name, event_data) | |
| 79 curr_wrapper = curr_wrapper - 1; | |
| 80 if curr_wrapper == 0 then | |
| 81 if global_wrappers == nil or w == global_wrappers then | |
| 82 return _fire_event(event_name, event_data); | |
| 83 end | |
| 84 w, curr_wrapper = global_wrappers, #global_wrappers; | |
| 85 return w[curr_wrapper](c, event_name, event_data); | |
| 86 else | |
| 87 return w[curr_wrapper](c, event_name, event_data); | |
| 88 end | |
| 89 end | |
| 90 return w[curr_wrapper](c, event_name, event_data); | |
| 91 end | |
| 92 return _fire_event(event_name, event_data); | |
| 93 end | |
| 94 local function add_wrapper(event_name, wrapper) | |
| 95 local w; | |
| 96 if event_name == nil then | |
| 97 w = global_wrappers; | |
| 98 if not w then | |
| 99 w = {}; | |
| 100 global_wrappers = w; | |
| 101 end | |
| 102 else | |
| 103 w = wrappers[event_name]; | |
| 104 if not w then | |
| 105 w = {}; | |
| 106 wrappers[event_name] = w; | |
| 107 end | |
| 108 end | |
| 109 w[#w+1] = wrapper; | |
| 110 end | |
| 111 local function remove_wrapper(event_name, wrapper) | |
| 112 local w; | |
| 113 if event_name == nil then | |
| 114 w = global_wrappers; | |
| 115 else | |
| 116 w = wrappers[event_name]; | |
| 117 end | |
| 118 if not w then return; end | |
| 119 for i = #w, 1 do | |
| 120 if w[i] == wrapper then | |
| 121 table.remove(w, i); | |
| 122 end | |
| 123 end | |
| 124 if #w == 0 then | |
| 125 if event_name == nil then | |
| 126 global_wrappers = nil; | |
| 127 else | |
| 128 wrappers[event_name] = nil; | |
| 129 end | |
| 130 end | |
| 131 end | |
| 72 return { | 132 return { |
| 73 add_handler = add_handler; | 133 add_handler = add_handler; |
| 74 remove_handler = remove_handler; | 134 remove_handler = remove_handler; |
| 75 add_handlers = add_handlers; | 135 add_handlers = add_handlers; |
| 76 remove_handlers = remove_handlers; | 136 remove_handlers = remove_handlers; |
| 137 wrappers = { | |
| 138 add_handler = add_wrapper; | |
| 139 remove_handler = remove_wrapper; | |
| 140 }; | |
| 141 add_wrapper = add_wrapper; | |
| 142 remove_wrapper = remove_wrapper; | |
| 77 fire_event = fire_event; | 143 fire_event = fire_event; |
| 78 _handlers = handlers; | 144 _handlers = handlers; |
| 79 _event_map = event_map; | 145 _event_map = event_map; |
| 80 }; | 146 }; |
| 81 end | 147 end |
