mirror of
https://github.com/1bardesign/batteries.git
synced 2024-11-22 14:14:36 +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"),
|
vec3 = require_relative("vec3"),
|
||||||
intersect = require_relative("intersect"),
|
intersect = require_relative("intersect"),
|
||||||
--
|
--
|
||||||
|
timer = require_relative("timer"),
|
||||||
|
pubsub = require_relative("pubsub"),
|
||||||
unique_mapping = require_relative("unique_mapping"),
|
unique_mapping = require_relative("unique_mapping"),
|
||||||
state_machine = require_relative("state_machine"),
|
state_machine = require_relative("state_machine"),
|
||||||
async = require_relative("async"),
|
async = require_relative("async"),
|
||||||
@ -73,6 +75,9 @@ function _batteries:export()
|
|||||||
--overwrite assert wholesale (it's compatible)
|
--overwrite assert wholesale (it's compatible)
|
||||||
assert = self.assert
|
assert = self.assert
|
||||||
|
|
||||||
|
--export the whole library to global `batteries`
|
||||||
|
batteries = self
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
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.
|
- `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`.
|
- `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...
|
- `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:**
|
**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