From d0dda9399e25a04887699878060ef86b5b58530d Mon Sep 17 00:00:00 2001 From: Aire-One Date: Tue, 26 Nov 2024 01:46:41 +0100 Subject: [PATCH] feat: slot are always HOF The slot's`slot` function callback needs to be a Higher-Order function to manage correctly and consistently the signal parameters. Before this change, the API was broken when the user wanted to pass `slot_params` to a signal with parameters. (e.g., the `screen` `"request::desktop_decoration"` signal passes the screen instance as a parameter; when used in combination with `slot_params`, `slot_param` overwrites the parameter.) Bonus point: every slot is by default a pseudo constructor function that has to return the actual signal callback. It makes it obvious to the user how to use the `slot_params` to manage external dependencies and configurations for the actual signal callback implementation. --- spec/slot_spec.lua | 55 +++++++++++++++++++++++++++++++++++++-- src/awesome-slot/init.lua | 10 ++----- 2 files changed, 55 insertions(+), 10 deletions(-) diff --git a/spec/slot_spec.lua b/spec/slot_spec.lua index a9a555d..2b54a75 100644 --- a/spec/slot_spec.lua +++ b/spec/slot_spec.lua @@ -2,8 +2,16 @@ local slot = require "awesome-slot" local function new_target() return { - connect_signal = spy.new(function() end), - disconnect_signal = spy.new(function() end), + signal = nil, -- Only need to bind 1 signal in the tests + connect_signal = function(self, _signal_name, signal_callback) + self.signal = signal_callback + end, + disconnect_signal = function() + -- Unimplemented + end, + emit_signal = function(self, _signal_name, ...) + self.signal(...) + end, } end @@ -121,4 +129,47 @@ describe("Awesome-slot", function() assert.is_not_nil(s.id) end) + + it("should manage slot parameters", function() + local target = new_target() + local signal_name = "signal" + local params = { key = "value" } + local callback = spy.new(function(p) + return function() + assert.same(params, p) + end + end) + + slot { + target = target, + signal = signal_name, + slot = callback, + slot_params = params, + connect = true, + } + + target:emit_signal(signal_name) + assert.spy(callback).called() + end) + + it("should retrieve signal parameters", function() + local target = new_target() + local signal_name = "signal" + local callback = spy.new(function() + return function(a, b, c) + assert.equal(a, 1) + assert.equal(b, 2) + assert.equal(c, 3) + end + end) + + slot { + target = target, + signal = signal_name, + slot = callback, + connect = true, + } + + target:emit_signal(signal_name, 1, 2, 3) + end) end) diff --git a/src/awesome-slot/init.lua b/src/awesome-slot/init.lua index 17f35fd..52f5fdf 100644 --- a/src/awesome-slot/init.lua +++ b/src/awesome-slot/init.lua @@ -120,14 +120,8 @@ function awesome_slot.create(params) slot.target = params.target slot.signal = params.signal slot.connected = false - - if params.slot_params then - slot.params = params.slot_params - slot.callback = function() - params.slot(slot.params) - end - else - slot.callback = params.slot + slot.callback = function(...) + params.slot(params.slot_params)(...) end -- Insert the new slot into the slots list