mirror of
https://github.com/1bardesign/batteries.git
synced 2024-11-25 15:14:35 +00:00
[added] pubsub
and timer
modules
This commit is contained in:
parent
16c183ec31
commit
89ad4c2dda
5
init.lua
5
init.lua
@ -31,6 +31,8 @@ local _batteries = {
|
||||
vec3 = require_relative("vec3"),
|
||||
intersect = require_relative("intersect"),
|
||||
--
|
||||
timer = require_relative("timer"),
|
||||
pubsub = require_relative("pubsub"),
|
||||
unique_mapping = require_relative("unique_mapping"),
|
||||
state_machine = require_relative("state_machine"),
|
||||
async = require_relative("async"),
|
||||
@ -73,6 +75,9 @@ function _batteries:export()
|
||||
--overwrite assert wholesale (it's compatible)
|
||||
assert = self.assert
|
||||
|
||||
--export the whole library to global `batteries`
|
||||
batteries = self
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
60
pubsub.lua
Normal file
60
pubsub.lua
Normal file
@ -0,0 +1,60 @@
|
||||
--[[
|
||||
dead-simple publish-subscribe message bus
|
||||
]]
|
||||
|
||||
local path = (...):gsub("pubsub", "")
|
||||
local class = require(path .. "class")
|
||||
local pubsub = class()
|
||||
|
||||
--create a new pubsub bus
|
||||
function pubsub:new()
|
||||
return self:init({
|
||||
subscriptions = {},
|
||||
})
|
||||
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
|
||||
--for "everything", the callback will recieve the event name as the first argument
|
||||
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
|
@ -64,6 +64,8 @@ General utility data structures and algorithms to speed you along your way.
|
||||
- `set` - A set type supporting a full suite of set operations with fast membership testing and `ipairs`-style iteration.
|
||||
- `sort` - Provides a stable merge+insertion sorting algorithm that is also, as a bonus, often faster than `table.sort` under luajit. Also exposes `insertion_sort` if needed. Alias `stable_sort`.
|
||||
- `state_machine` - Finite state machine implementation with state transitions and all the rest. Useful for game states, AI, cutscenes...
|
||||
- `timer` - a "countdown" style timer with progress and completion callbacks.
|
||||
- `pubsub` - a self-contained publish/subscribe message bus. Immediate mode rather than queued, local rather than networked, but if you were expecting mqtt in 60 lines I don't know what to tell you. Scales pretty well nonetheless.
|
||||
|
||||
**Geometry:**
|
||||
|
||||
|
59
timer.lua
Normal file
59
timer.lua
Normal file
@ -0,0 +1,59 @@
|
||||
--[[
|
||||
basic timer class
|
||||
|
||||
can check for expiry and register a callback to be called on progress and on finish
|
||||
|
||||
if you find yourself using lots of these for pushing stuff into the future,
|
||||
look into async.lua and see if it might be a better fit!
|
||||
]]
|
||||
|
||||
local path = (...):gsub("timer", "")
|
||||
local class = require(path .. "class")
|
||||
local timer = class()
|
||||
|
||||
--create a timer, with optional callbacks
|
||||
--callbacks recieve as arguments:
|
||||
-- the current progress as a number from 0 to 1, so can be used for lerps
|
||||
-- the timer object, so can be reset if needed
|
||||
function timer:new(time, on_progress, on_finish)
|
||||
return self:init({
|
||||
time = math.max(time, 1e-6), --negative time not allowed
|
||||
timer = 0,
|
||||
on_progress = on_progress,
|
||||
on_finish = on_finish,
|
||||
})
|
||||
end
|
||||
|
||||
--update this timer, calling the relevant callback if it exists
|
||||
function timer:update(dt)
|
||||
if not self:expired() then
|
||||
self.timer = self.timer + dt
|
||||
|
||||
--get the relevant callback
|
||||
local cb = self:expired()
|
||||
and self.on_finish
|
||||
or self.on_progress
|
||||
|
||||
if cb then
|
||||
cb(self:progress(), self)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--check if the timer has expired
|
||||
function timer:expired()
|
||||
return self.timer >= self.time
|
||||
end
|
||||
|
||||
--get the timer's progress from 0 to 1
|
||||
function timer:progress()
|
||||
return math.min(self.timer / self.time, 1)
|
||||
end
|
||||
|
||||
--reset the timer
|
||||
--will resume calling the same callbacks, so can be used for intervals
|
||||
function timer:reset()
|
||||
self.timer = 0
|
||||
end
|
||||
|
||||
return timer
|
Loading…
Reference in New Issue
Block a user