Loading...
Searching...
No Matches
ml::MessageManager Class Reference

Typed, enum-keyed message bus for structured inter-object communication. More...

#include <MessageManager.h>

Inheritance diagram for ml::MessageManager:

Static Public Member Functions

static void clear ()
 Remove all subscriptions for all subscribers and all keys.
static void clearPending ()
 Discard all pending operations without executing them.
static bool isBusy ()
 Return true if the manager is currently iterating.
static void processPending ()
 Flush all pending operations immediately.
template<typename DataType, typename Enum>
static void publish (Enum event, const DataType &data)
 Deliver a typed message to all matching subscribers.
template<typename DataType, typename Enum>
static void subscribe (Enum event, void *subscriber, std::function< void(const DataType &)> callback)
 Register a typed callback for a specific enum event.
template<typename DataType, typename Enum>
static void unsubscribe (Enum event, void *subscriber)
 Remove one subscriber's callback for a specific typed event.
static void unsubscribeAll (void *subscriber)
 Remove all subscriptions for a given subscriber.

Static Protected Member Functions

static void beginBusy ()
 Signal that iteration has begun.
static void deferOrExecute (std::function< void()> operation)
 Execute operation now if safe, otherwise queue it.
static void endBusy ()
 Signal that iteration has ended; flush pending operations.

Static Protected Attributes

static int busyDepth
 Iteration nesting depth. Operations are deferred while this is > 0.
static std::vector< std::function< void()> > pendingOperations
 Queue of operations pending until the current iteration completes.

Detailed Description

Typed, enum-keyed message bus for structured inter-object communication.

MessageManager is the engine behind the Messenger trait. It provides a completely separate communication channel from EventsManager:

EventsManager MessageManager
String keys ("click", "hover") Enum keys (GameEvent::Started)
Fired by dispatchers based on SFML input Fired explicitly by application code
Delivers to Subscribable objects Delivers to any void* subscriber
Used for input and UI lifecycle events Used for application-level signals

How the key works

Each subscription is identified by a three-part key:

  • The enum type (std::type_index of Enum)
  • The enum value (cast to int)
  • The data type (std::type_index of DataType)

This means the same enum value can carry different payload types without collision, and different enum types are always distinct even if their integer values overlap.

Iteration safety

MessageManager inherits DeferredOperationsManager<MessageManager>. Any unsubscribe or unsubscribeAll call made while publish() is iterating is automatically deferred and processed after the iteration completes. This makes it safe to unsubscribe from within a message callback.

Usage

Most user code interacts with MessageManager through the Messenger trait methods (sendMessage, onMessage, offMessage). Direct calls are only needed for framework-internal wiring.

enum class GameEvent { Started, ScoreChanged, Stopped };
// Subscribe (via Messenger trait — preferred)
onMessage<int>(GameEvent::ScoreChanged, [](const int& score) {
updateHUD(score);
});
// Publish (via Messenger trait — preferred)
sendMessage<int>(GameEvent::ScoreChanged, 42);
See also
Messenger, EventsManager, DeferredOperationsManager

Definition at line 69 of file MessageManager.h.

Member Function Documentation

◆ beginBusy()

void ml::DeferredOperationsManager< MessageManager >::beginBusy ( )
staticprotectedinherited

Signal that iteration has begun.

Increments the busy-depth counter. Multiple nested calls are safe — operations remain deferred until the outermost endBusy() is reached.

◆ clear()

void ml::MessageManager::clear ( )
static

Remove all subscriptions for all subscribers and all keys.

Use during application teardown or full scene reset.

◆ clearPending()

void ml::DeferredOperationsManager< MessageManager >::clearPending ( )
staticinherited

Discard all pending operations without executing them.

Use during application shutdown or full reset when executing the queued operations would be unsafe (e.g., the objects they reference have already been destroyed).

◆ deferOrExecute()

void ml::DeferredOperationsManager< MessageManager >::deferOrExecute ( std::function< void()> operation)
staticprotectedinherited

Execute operation now if safe, otherwise queue it.

If busyDepth > 0 the operation is appended to pendingOperations and will run when the current iteration completes. If the manager is idle the operation executes immediately.

Parameters
operationThe callable to execute or defer.

◆ endBusy()

void ml::DeferredOperationsManager< MessageManager >::endBusy ( )
staticprotectedinherited

Signal that iteration has ended; flush pending operations.

Decrements the busy-depth counter. When the counter reaches zero, all operations in pendingOperations are executed in FIFO order and the queue is cleared.

◆ isBusy()

bool ml::DeferredOperationsManager< MessageManager >::isBusy ( )
staticinherited

Return true if the manager is currently iterating.

Can be used by external code that needs to know whether a destructive operation will be deferred.

Returns
true when busyDepth > 0.

◆ processPending()

void ml::DeferredOperationsManager< MessageManager >::processPending ( )
staticinherited

Flush all pending operations immediately.

Normally called automatically by endBusy(). Provided as a public escape hatch for unusual teardown sequences.

Warning
Calling this while isBusy() is true can cause iterator invalidation in the currently running loop. Only call manually when you are certain it is safe.

◆ publish()

template<typename DataType, typename Enum>
void ml::MessageManager::publish ( Enum event,
const DataType & data )
static

Deliver a typed message to all matching subscribers.

Looks up all subscriptions matching the composite key for event and DataType, then invokes each callback with data. The manager marks itself busy for the duration; any unsubscriptions that arrive during delivery are deferred.

Template Parameters
DataTypePayload type. Must match the type used in the corresponding subscribe call.
EnumEnum type identifying the message.
Parameters
eventThe specific enum value to publish.
dataPayload delivered to all matching callbacks.

◆ subscribe()

template<typename DataType, typename Enum>
void ml::MessageManager::subscribe ( Enum event,
void * subscriber,
std::function< void(const DataType &)> callback )
static

Register a typed callback for a specific enum event.

The callback is stored against the composite key formed by Enum, event, and DataType. If subscriber has already registered a callback for this exact key, the new callback replaces the old one.

Template Parameters
DataTypeExpected payload type.
EnumEnum type identifying the message.
Parameters
eventThe specific enum value to subscribe to.
subscriberOpaque pointer identifying the subscribing object (typically this). Used for targeted unsubscription.
callbackCalled with a const reference to the payload when the message is published.

◆ unsubscribe()

template<typename DataType, typename Enum>
void ml::MessageManager::unsubscribe ( Enum event,
void * subscriber )
static

Remove one subscriber's callback for a specific typed event.

If called during a publish() iteration the removal is deferred.

Template Parameters
DataTypePayload type of the subscription to remove.
EnumEnum type identifying the message.
Parameters
eventThe specific enum value to unsubscribe from.
subscriberThe subscribing object to remove.

◆ unsubscribeAll()

void ml::MessageManager::unsubscribeAll ( void * subscriber)
static

Remove all subscriptions for a given subscriber.

Called automatically by Messenger's destructor. If called during a publish() iteration the removal is deferred, preventing use-after-free when an object destroys itself inside a callback.

Parameters
subscriberThe subscribing object to remove from all messages.

Member Data Documentation

◆ busyDepth

int ml::DeferredOperationsManager< MessageManager >::busyDepth
inlinestaticprotectedinherited

Iteration nesting depth. Operations are deferred while this is > 0.

Definition at line 69 of file DeferredOperationsManager.h.

◆ pendingOperations

std::vector<std::function<void()> > ml::DeferredOperationsManager< MessageManager >::pendingOperations
inlinestaticprotectedinherited

Queue of operations pending until the current iteration completes.

Definition at line 72 of file DeferredOperationsManager.h.


The documentation for this class was generated from the following file: