util.events: Add set_debug_hook() method
authorMatthew Wild <mwild1@gmail.com>
Thu, 03 Sep 2020 12:59:43 +0100
changeset 11062 c99afee1c548
parent 11061 13eee48071c8
child 11063 ad89e3cc67b6
util.events: Add set_debug_hook() method Hook signature: ret = debug_hook(handler, event_name, event_data)
spec/util_events_spec.lua
util/events.lua
--- a/spec/util_events_spec.lua	Sat Aug 29 18:51:13 2020 +0200
+++ b/spec/util_events_spec.lua	Thu Sep 03 12:59:43 2020 +0100
@@ -208,5 +208,43 @@
 				assert.spy(h).was_called(2);
 			end);
 		end);
+
+		describe("debug hooks", function ()
+			it("should get called", function ()
+				local d = spy.new(function (handler, event_name, event_data)
+					return handler(event_data);
+				end);
+
+				e.add_handler("myevent", h);
+				e.fire_event("myevent");
+
+				assert.spy(h).was_called(1);
+				assert.spy(d).was_called(0);
+
+				assert.is_nil(e.set_debug_hook(d));
+
+				e.fire_event("myevent", { mydata = true });
+
+				assert.spy(h).was_called(2);
+				assert.spy(d).was_called(1);
+				assert.spy(d).was_called_with(h, "myevent", { mydata = true });
+
+				assert.equal(d, e.set_debug_hook(nil));
+
+				e.fire_event("myevent", { mydata = false });
+
+				assert.spy(h).was_called(3);
+				assert.spy(d).was_called(1);
+			end);
+			it("setting should return any existing debug hook", function ()
+				local function f() end
+				local function g() end
+				assert.is_nil(e.set_debug_hook(f));
+				assert.is_equal(f, e.set_debug_hook(g));
+				assert.is_equal(g, e.set_debug_hook(f));
+				assert.is_equal(f, e.set_debug_hook(nil));
+				assert.is_nil(e.set_debug_hook(f));
+			end);
+		end);
 	end);
 end);
--- a/util/events.lua	Sat Aug 29 18:51:13 2020 +0200
+++ b/util/events.lua	Thu Sep 03 12:59:43 2020 +0100
@@ -26,6 +26,8 @@
 	local wrappers = {};
 	-- Event map: event_map[handler_function] = priority_number
 	local event_map = {};
+	-- Debug hook, if any
+	local active_debug_hook = nil;
 	-- Called on-demand to build handlers entries
 	local function _rebuild_index(self, event)
 		local _handlers = event_map[event];
@@ -74,11 +76,16 @@
 	end;
 	local function _fire_event(event_name, event_data)
 		local h = handlers[event_name];
-		if h then
+		if h and not active_debug_hook then
 			for i=1,#h do
 				local ret = h[i](event_data);
 				if ret ~= nil then return ret; end
 			end
+		elseif h and active_debug_hook then
+			for i=1,#h do
+				local ret = active_debug_hook(h[i], event_name, event_data);
+				if ret ~= nil then return ret; end
+			end
 		end
 	end;
 	local function fire_event(event_name, event_data)
@@ -140,6 +147,13 @@
 			end
 		end
 	end
+
+	local function set_debug_hook(new_hook)
+		local old_hook = active_debug_hook;
+		active_debug_hook = new_hook;
+		return old_hook;
+	end
+
 	return {
 		add_handler = add_handler;
 		remove_handler = remove_handler;
@@ -150,8 +164,12 @@
 			add_handler = add_wrapper;
 			remove_handler = remove_wrapper;
 		};
+
 		add_wrapper = add_wrapper;
 		remove_wrapper = remove_wrapper;
+
+		set_debug_hook = set_debug_hook;
+
 		fire_event = fire_event;
 		_handlers = handlers;
 		_event_map = event_map;