Skip to content

Beacon Manager Extensions

shmellyorc edited this page Sep 23, 2026 · 1 revision

BeaconManagerExtensions adds one-shot, TimeSpan, and delayed-publish helpers on top of the core Beacon Manager.

The extensions keep the normal BeaconManager API small while providing convenient lifetime and scheduling behavior when a subscription should clean itself up automatically.


Overview

Feature Description
TimeSpan subscriptions Subscribe for a TimeSpan lifetime instead of float seconds
One-shot subscriptions Subscribe until the first matching publish, then remove automatically
Timed one-shot subscriptions Fire once if the topic is published before the lifetime expires
Delayed publishing Publish after a scaled coroutine delay and receive a CoroutineHandle
String and enum topics All helpers support the same topic styles as BeaconManager

TimeSpan Subscriptions

The core manager supports timed subscriptions with a float lifetime in seconds:

BeaconManager.Instance.Subscribe(
    GameBeacons.PlayerHit,
    OnPlayerHit,
    5f);

The extension adds the same behavior with TimeSpan:

BeaconManager.Instance.Subscribe(
    GameBeacons.PlayerHit,
    OnPlayerHit,
    TimeSpan.FromSeconds(5));

The callback is active immediately and may run multiple times during that lifetime. Once the lifetime has expired, it will not run again.

Timed subscriptions use Game.Instance.FrameTime.TotalTime and expire lazily when their topic is next touched. There is no per-frame Beacon cleanup pass.

The same behavior is available for string topics:

BeaconManager.Instance.Subscribe(
    "PlayerHit",
    OnPlayerHit,
    TimeSpan.FromSeconds(5));

For the float overloads and the core timed-subscription behavior, see Beacon Manager.


SubscribeOnce

SubscribeOnce keeps a handler subscribed until the first matching publish.

BeaconManager.Instance.SubscribeOnce(
    GameBeacons.LevelLoaded,
    handle =>
    {
        InitializeLevel();
    });

The wrapper removes itself before invoking the real callback, so reentrant publishes do not cause the same one-shot subscription to run twice.

String topics work the same way:

BeaconManager.Instance.SubscribeOnce(
    "LevelLoaded",
    OnLevelLoaded);

This is useful for events that only matter once, such as:

  • initialization completion
  • first interaction
  • one-time UI responses
  • loading completion
  • temporary gameplay gates

Timed SubscribeOnce

A one-shot subscription can also have a maximum lifetime.

Using float seconds:

BeaconManager.Instance.SubscribeOnce(
    GameBeacons.NetworkResponse,
    OnResponse,
    5f);

Using TimeSpan:

BeaconManager.Instance.SubscribeOnce(
    GameBeacons.NetworkResponse,
    OnResponse,
    TimeSpan.FromSeconds(5));

The handler runs at most once:

  • if the topic is published before expiration, the handler runs and removes itself
  • if the lifetime expires first, the subscription is removed lazily and never invokes the handler

This is useful when an event is expected soon but should not remain subscribed forever.


PublishDelay

PublishDelay schedules a publish through the Coroutine system.

CoroutineHandle pending =
    BeaconManager.Instance.PublishDelay(
        GameBeacons.PlayerDied,
        2f,
        playerPosition,
        playerScore);

The delay uses scaled coroutine time and therefore follows FrameTime.TimeScale.

The returned handle can cancel the pending publish:

pending.Stop();

When the delay completes, the extension uses the normal synchronous BeaconManager.Publish path.

This is intentionally different from timed subscriptions:

Feature Time source Behavior
Timed Subscribe FrameTime.TotalTime Subscription is active immediately, then expires
Timed SubscribeOnce FrameTime.TotalTime Fires once before expiration, otherwise expires
PublishDelay Scaled coroutine time Waits first, then publishes once

Lifetime and Cleanup

Timed Beacon subscriptions are designed to avoid a global update cost.

  • No BeaconManager.Update() call is required.
  • Expiration uses absolute TimeSpan values from FrameTime.TotalTime.
  • Cleanup is limited to the topic being touched.
  • Expired timed subscriptions are removed while processing that topic.
  • A normal timed Subscribe can still be removed manually with the original callback.

Permanent subscriptions continue to use the normal multicast delegate path.

See Beacon Manager for the core dispatch design.


See Also


Back to Home

Clone this wiki locally