Documentation
¶
Overview ¶
Package pievent provides a simple observer pattern implementation for decoupled communication.
The observer (or publish/subscribe) pattern lets different parts of your program communicate without knowing about each other's concrete types. Instead of directly calling methods on another component, a publisher broadcasts an event, and any interested subscribers listening on the same target will receive it.
This approach is useful for building flexible, decoupled systems where components shouldn't depend tightly on each other. For example, a player movement system can publish "Moved" events, and other systems (like animations, sound, or networking) can subscribe to those events and react appropriately without being directly linked to the movement logic.
Events in pievent are synchronous: when an event is published, all subscribers receive it immediately on the same goroutine. This design keeps things simple and predictable (no concurrency issues) but means event handlers should be fast to avoid blocking the publisher.
The API is also optimized to avoid allocations in typical usage. Registering and publishing events generally does not allocate on the heap, making it suitable even for high-frequency game loops.
However, note that pievent is not a silver bullet for all communication needs:
- It's best used when multiple independent systems need to react to the same event.
- If you only ever have one listener for a signal, it's often better to just call a function or assign a callback directly, which is simpler, easier to debug, and easier to maintain.
Also remember that pievent-based listeners often need careful design: they usually use type-switches or if-statements to identify the event type, which can make the code more complex if overused.
In short, use pievent when you need many decoupled listeners for an event, but prefer simpler direct calls when only one consumer exists.
Index ¶
- Variables
- type Handler
- type Target
- type TrackingTarget
- func (t *TrackingTarget[T]) Handlers() []Handler
- func (t *TrackingTarget[T]) IsSubscribed(h Handler) bool
- func (t *TrackingTarget[T]) Publish(event T)
- func (t *TrackingTarget[T]) SetTracing(enabled bool)
- func (t *TrackingTarget[T]) Subscribe(event T, listener func(T, Handler)) Handler
- func (t *TrackingTarget[T]) SubscribeAll(listener func(T, Handler)) Handler
- func (t *TrackingTarget[T]) Unsubscribe(handler Handler)
- func (t *TrackingTarget[T]) UnsubscribeAll()
Constants ¶
This section is empty.
Variables ¶
var GlobalTracingOff bool // when true, tracing is globally disabled (zero-allocation mode)
Functions ¶
This section is empty.
Types ¶
type Handler ¶
type Handler int
Handler is an identifier returned when subscribing to a Target.
It can be used to later unsubscribe or check subscription status.
type Target ¶
type Target[T comparable] interface { // Publish sends an event to all matching subscribers. Publish(event T) // SubscribeAll registers a listener that receives all events. SubscribeAll(listener func(event T, handler Handler)) Handler // Subscribe registers a listener for a specific event. // If the event is the zero value (for example, an empty string), // the listener receives all events (same as SubscribeAll). Subscribe(event T, f func(T, Handler)) Handler // Unsubscribe removes a previously registered listener. Unsubscribe(Handler) // IsSubscribed reports whether the given Handler is currently subscribed. IsSubscribed(Handler) bool // SetTracing enables or disables tracing for this Target. SetTracing(enabled bool) }
Target defines an interface for publishing and subscribing to events.
A Target manages event listeners and allows components to publish events without knowing who will receive them.
func NewTarget ¶
func NewTarget[T comparable]() Target[T]
type TrackingTarget ¶
type TrackingTarget[T comparable] struct { // contains filtered or unexported fields }
TrackingTarget wraps a Target and tracks all subscriptions.
It allows you to later unsubscribe all tracked handlers at once.
func Track ¶
func Track[T comparable](wrappedTarget Target[T]) *TrackingTarget[T]
Track creates a new target that tracks all new subscriptions, allowing them to be unsubscribed later by calling UnsubscribeAll on the returned TrackingTarget.
func (*TrackingTarget[T]) Handlers ¶
func (t *TrackingTarget[T]) Handlers() []Handler
func (*TrackingTarget[T]) IsSubscribed ¶
func (t *TrackingTarget[T]) IsSubscribed(h Handler) bool
func (*TrackingTarget[T]) Publish ¶
func (t *TrackingTarget[T]) Publish(event T)
func (*TrackingTarget[T]) SetTracing ¶
func (t *TrackingTarget[T]) SetTracing(enabled bool)
func (*TrackingTarget[T]) Subscribe ¶
func (t *TrackingTarget[T]) Subscribe(event T, listener func(T, Handler)) Handler
func (*TrackingTarget[T]) SubscribeAll ¶
func (t *TrackingTarget[T]) SubscribeAll(listener func(T, Handler)) Handler
func (*TrackingTarget[T]) Unsubscribe ¶
func (t *TrackingTarget[T]) Unsubscribe(handler Handler)
func (*TrackingTarget[T]) UnsubscribeAll ¶
func (t *TrackingTarget[T]) UnsubscribeAll()