Skip to content

Events

EventBus is a type-safe publish/subscribe system. Subscriptions are RAII handles and are automatically removed when destroyed.

Key Points

  • on<Event>(handler) returns a Subscription.
  • Hold the subscription as a member on any listener that captures this.
  • emit<Event>(...) dispatches immediately.
  • enqueue<Event>(...) stores an event by value until dispatchQueued().
  • The application dispatches queued events after scene, component, late-update, and UI updates. An event queued during those phases normally runs later in the same frame.
  • A dispatch pass snapshots the current queue. Events enqueued by a queued handler wait for the next dispatch pass (normally the next frame).
  • A handler added during an emission starts with the next emission. Resetting a subscription during emission prevents that handler from receiving later callbacks.

Sample Usage

struct ValueChanged {
    int value = 0;
};

class ValueObserver final : public snowpulse::Script {
public:
    void onStart() override {
        _sub = events()->on<ValueChanged>([this](const ValueChanged& event) {
            _value = event.value;
        });
    }

private:
    int _value = 0;
    snowpulse::EventBus::Subscription<ValueChanged> _sub;
};

events()->emit(ValueChanged { 10 });  // Synchronous.

Destroying a subscription or calling subscription.reset() unregisters its handler. A subscription kept only in a local variable is therefore active only until that variable leaves scope. EventBus::clear() removes all handlers and all queued events, which is useful when resetting an application context.

Queueing by Value

ValueChanged evt;
evt.value = 42;
events()->enqueue(evt);

Spine Animation Events

SpineRenderer enqueues SpineAnimationEvent on the EventBus, and also supports per-component callbacks.

class AnimationEventObserver final : public snowpulse::Script {
public:
    void onStart() override {
        _animationSub = events()->on<snowpulse::SpineAnimationEvent>(
            [](const snowpulse::SpineAnimationEvent& event) {
                // Handle the animation event.
            });
    }

private:
    snowpulse::EventBus::Subscription<snowpulse::SpineAnimationEvent>
        _animationSub;
};

Application Lifecycle Events

Supported hosts emit AppLifecycleEvent through the same bus. Android reports Suspended, Resumed, and LowMemory; web visibility changes report Suspended and Resumed. Keep the subscription handle alive exactly as for other events. Audio/video suspension is also handled by the platform runtime.

_lifecycleSub = events()->on<snowpulse::AppLifecycleEvent>(
    [](const snowpulse::AppLifecycleEvent& event) {
        if (event.state == snowpulse::AppLifecycleState::LowMemory) {
            // Release optional caches.
        }
    });

Here _lifecycleSub is a member of the listening object, with type EventBus::Subscription<AppLifecycleEvent>.