2021-03-12 10:23:54 +00:00
|
|
|
--[[
|
|
|
|
dead-simple publish-subscribe message bus
|
|
|
|
]]
|
|
|
|
|
|
|
|
local path = (...):gsub("pubsub", "")
|
|
|
|
local class = require(path .. "class")
|
2021-11-22 23:45:09 +00:00
|
|
|
local set = require(path .. "set")
|
|
|
|
|
2021-07-15 06:09:08 +00:00
|
|
|
local pubsub = class({
|
|
|
|
name = "pubsub",
|
|
|
|
})
|
2021-03-12 10:23:54 +00:00
|
|
|
|
|
|
|
--create a new pubsub bus
|
|
|
|
function pubsub:new()
|
2021-07-15 06:09:08 +00:00
|
|
|
self.subscriptions = {}
|
2021-03-12 10:23:54 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
--(internal; notify a callback set of an event)
|
|
|
|
function pubsub:_notify(callbacks, ...)
|
|
|
|
if callbacks then
|
|
|
|
for _, f in callbacks:ipairs() do
|
|
|
|
f(...)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
--publish an event, with optional arguments
|
|
|
|
--notifies both the direct subscribers, and those subscribed to "everything"
|
|
|
|
function pubsub:publish(event, ...)
|
|
|
|
self:_notify(self.subscriptions[event], ...)
|
|
|
|
self:_notify(self.subscriptions.everything, event, ...)
|
|
|
|
end
|
|
|
|
|
|
|
|
--subscribe to an event
|
|
|
|
--can be a specifically named event, or "everything" to get notified for any event
|
2021-07-18 01:30:22 +00:00
|
|
|
--for "everything", the callback will receive the event name as the first argument
|
2021-03-12 10:23:54 +00:00
|
|
|
function pubsub:subscribe(event, callback)
|
|
|
|
local callbacks = self.subscriptions[event]
|
|
|
|
if not callbacks then
|
|
|
|
callbacks = set()
|
|
|
|
self.subscriptions[event] = callbacks
|
|
|
|
end
|
|
|
|
callbacks:add(callback)
|
|
|
|
end
|
|
|
|
|
|
|
|
--unsubscribe from an event
|
|
|
|
function pubsub:unsubscribe(event, callback)
|
|
|
|
local callbacks = self.subscriptions[event]
|
|
|
|
if callbacks then
|
|
|
|
callbacks:remove(callback)
|
|
|
|
if callbacks:size() == 0 then
|
|
|
|
self.subscriptions[event] = nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
--check if there is a subscriber for a given event
|
|
|
|
function pubsub:has_subcriber(event)
|
|
|
|
return self.subscriptions[event] ~= nil
|
|
|
|
end
|
|
|
|
|
|
|
|
return pubsub
|