From cf0ff60d31c64a639d832b6c1f0b5602ef255659 Mon Sep 17 00:00:00 2001 From: Lucien Greathouse Date: Wed, 18 Mar 2020 23:31:22 -0700 Subject: [PATCH] plugin: Add simple signal implementation for future work --- plugin/src/createSignal.lua | 53 +++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 plugin/src/createSignal.lua diff --git a/plugin/src/createSignal.lua b/plugin/src/createSignal.lua new file mode 100644 index 00000000..965a452d --- /dev/null +++ b/plugin/src/createSignal.lua @@ -0,0 +1,53 @@ +--[[ + Create a new signal that can be connected to, disconnected from, and fired. + + Usage: + + local signal = createSignal() + local disconnect = signal:connect(function(...) + print("fired:", ...) + end) + + signal:fire("a", "b", "c") + disconnect() + + Avoids mutating listeners list directly to prevent iterator invalidation if + a listener is disconnected while the signal is firing. +]] +local function createSignal() + local listeners = {} + + local function connect(newListener) + local nextListeners = {} + for listener in pairs(listeners) do + nextListeners[listener] = true + end + + nextListeners[newListener] = true + listeners = nextListeners + + return function() + local nextListeners = {} + for listener in pairs(listeners) do + if listener ~= newListener then + nextListeners[listener] = true + end + end + + listeners = nextListeners + end + end + + local function fire(...) + for listener in pairs(listeners) do + listener(...) + end + end + + return { + connect = connect, + fire = fire, + } +end + +return createSignal \ No newline at end of file