qb  2.0.0.0
C++17 Actor Framework
qb Issue Watch Star Fork Follow @isndev
Loading...
Searching...
No Matches

Base class for all actors in the qb framework. More...

#include <Actor.h>

Inheritance diagram for qb::Actor:
Collaboration diagram for qb::Actor:

Classes

class  EventBuilder
 Helper class for building and sending events to actors. More...

Public Member Functions

Built-in Event Handlers
void on (KillEvent const &event) noexcept
 Handler for KillEvent.
void on (SignalEvent const &event) noexcept
 Handler for SignalEvent.
void on (UnregisterCallbackEvent const &event) noexcept
 Handler for UnregisterCallbackEvent.
void on (PingEvent const &event) noexcept
 Handler for PingEvent.

Public Member Functions

This part describes how to manage Actor loop callback, events registration, several ways to send events and create referenced actors.

template<typename _Actor>
void registerCallback (_Actor &actor) const noexcept
 Register a looped callback for this actor.
template<typename _Actor>
void unregisterCallback (_Actor &actor) const noexcept
 Unregister a previously registered looped callback for this actor.
template<typename _Event, typename _Actor>
void registerEvent (_Actor &actor) const noexcept
 Subscribe this actor to listen for a specific event type.
template<typename _Event, typename _Actor>
void unregisterEvent (_Actor &actor) const noexcept
 Unsubscribe this actor from listening to a specific event type.
EventBuilder to (ActorId dest) const noexcept
 Get an EventBuilder for sending chained events to a destination actor.
template<typename _Event, typename... _Args>
_Event & push (ActorId const &dest, _Args &&...args) const noexcept
 Send a new event in an ordered fashion to a destination actor, returning a reference to it.
template<typename _Event, typename... _Args>
void send (ActorId const &dest, _Args &&...args) const noexcept
 Send a new event in an unordered fashion to a destination actor.
template<typename _Event, typename... _Args>
_Event build_event (qb::ActorId const source, _Args &&...args) const noexcept
 Construct an event locally, intended for immediate self-processing or direct calls.
template<typename _Type>
bool is (uint32_t const id) const noexcept
 Check if a given ID matches the type ID of _Type.
template<typename _Type>
bool is (RequireEvent const &event) const noexcept
 Check if a RequireEvent is for a specific actor type.
template<typename... _Actors>
bool require () const noexcept
 Request discovery of other actors of specified types.
template<typename _Event, typename... _Args>
void broadcast (_Args &&...args) const noexcept
 Broadcast an event to all actors on all cores.
void reply (Event &event) const noexcept
 Reply to the source of a received event, reusing the event object.
void forward (ActorId dest, Event &event) const noexcept
 Forward a received event to a new destination, reusing the event object.
Pipe getPipe (ActorId dest) const noexcept
 Get direct access to the underlying communication pipe for a destination actor.
template<typename _Actor, typename... _Args>
_Actor * addRefActor (_Args &&...args) const
 Create and initialize a new referenced actor on the same VirtualCore.

Public Accessors

ActorId id () const noexcept
 Get ActorId.
CoreId getIndex () const noexcept
 Get core index.
std::string_view getName () const noexcept
 Get derived class name.
const CoreIdSetgetCoreSet () const noexcept
 Get the set of cores that this actor's VirtualCore can communicate with.
uint64_t time () const noexcept
 Get current time from the VirtualCore's perspective (nanoseconds since epoch).
template<typename _ServiceActor>
_ServiceActor * getService () const noexcept
 Get direct access to ServiceActor* in same core.
bool is_alive () const noexcept
 Check if Actor is alive and processing events.

Construction/Destruction

 Actor () noexcept
 Default constructor.
virtual ~Actor () noexcept=default
 Virtual destructor.
virtual bool onInit ()
 Initialization callback, called once after construction and ID assignment.
void kill () const noexcept
 Terminate this actor and mark it for removal from the system.

Detailed Description

Base class for all actors in the qb framework.

The Actor class is the fundamental unit of computation in the qb framework. Actors communicate exclusively by passing messages (events) to each other, which are processed by event handlers. This messaging pattern ensures isolation and prevents shared mutable state, making the system more robust for concurrent and distributed applications.

Each actor:

  • Has a unique identity (ActorId)
  • Processes events asynchronously
  • Can send events to other actors
  • Manages its own internal state
  • Has a well-defined lifecycle

Example usage:

class MyActor : public qb::Actor {
private:
int counter = 0;
public:
// Custom event type
struct IncrementEvent : qb::Event {
int amount;
IncrementEvent(int amt) : amount(amt) {}
};
bool onInit() override {
// Register event handlers
LOG_INFO("MyActor initialized with ID: " << id());
return true;
}
void on(const IncrementEvent& event) {
counter += event.amount;
LOG_INFO("Counter updated to: " << counter);
}
void on(const qb::KillEvent& event) {
LOG_INFO("MyActor shutting down...");
kill();
}
};
// In a VirtualCore or Main context:
auto actor_id = addActor<MyActor>();
to(actor_id).push<MyActor::IncrementEvent>(5);
EventBuilder & push(_Args &&...args) noexcept
Send a new event to the target actor.
Base class for all actors in the qb framework.
Definition Actor.h:106
void registerEvent(_Actor &actor) const noexcept
Subscribe this actor to listen for a specific event type.
void on(KillEvent const &event) noexcept
Handler for KillEvent.
EventBuilder to(ActorId dest) const noexcept
Get an EventBuilder for sending chained events to a destination actor.
void kill() const noexcept
Terminate this actor and mark it for removal from the system.
virtual bool onInit()
Initialization callback, called once after construction and ID assignment.
Definition Actor.h:198
Base class for all events in the actor system.
Definition Event.h:85
ActorId actor_id
Alias for ActorId.
Definition ActorId.h:495
Event event
Alias for the base Event class.
Definition Event.h:385
#define LOG_INFO(X)
Info-level log macro (no-op if QB_STDOUT_LOG is not defined)
Definition io.h:229

Constructor & Destructor Documentation

◆ Actor()

qb::Actor::Actor ( )
protectednoexcept

Default constructor.

Creates an actor with a default (invalid) ID. The actual ID will be assigned when the actor is registered with a VirtualCore.

◆ ~Actor()

virtual qb::Actor::~Actor ( )
protectedvirtualdefaultnoexcept

Virtual destructor.

Ensures proper cleanup of derived actor classes.

Note
Called after the actor logic has completed and it has been removed from the engine.

Member Function Documentation

◆ onInit()

virtual bool qb::Actor::onInit ( )
inlineprotectedvirtual

Initialization callback, called once after construction and ID assignment.

This method is called when the actor is added to the system, before it starts processing any events. Override this method to perform initialization tasks such as registering event handlers and setting up actor state.

Returns
true if initialization was successful, which allows the actor to start.
false if initialization failed, which prevents the actor from being added to the engine and leads to its immediate destruction.

Crucial for registerEvent<EventType>(*this) calls. Example:

bool onInit() override {
// Register events
registerEvent<qb::KillEvent>(*this); // Important for graceful shutdown
// Initialize resources or state
_my_resource = std::make_unique<MyResource>();
if (!_my_resource) {
LOG_CRIT("Failed to allocate MyResource for Actor " << id());
return false; // Initialization failed
}
LOG_INFO("Actor " << id() << " initialized successfully.");
return true; // Initialization successful
}
#define LOG_CRIT(X)
Critical-level log macro (no-op if QB_STDOUT_LOG is not defined)
Definition io.h:243

◆ kill()

void qb::Actor::kill ( ) const
noexcept

Terminate this actor and mark it for removal from the system.

Marks the actor for removal from the system. After calling this method, the actor will no longer receive new events (though it may process events already in its queue) and will be cleaned up by the framework during the next appropriate cycle.

This method is typically called from within an event handler (e.g., on(qb::KillEvent&)) when the actor decides to terminate itself, or it can be triggered by sending a KillEvent to the actor.

Note
This method only flags the actor for termination; the actual destruction and ~Actor() call occur later, managed by the VirtualCore.

◆ on() [1/4]

void qb::Actor::on ( KillEvent const & event)
noexcept

Handler for KillEvent.

Default handler for the KillEvent which terminates the actor by calling this->kill(). Derived classes can override this handler to perform cleanup actions before termination, but should typically call Actor::kill() or this->kill() at the end of their implementation to ensure proper termination.

Parameters
eventThe received kill event (often unused in overrides, but available). Example of overriding:
void on(qb::KillEvent const &event) override {
LOG_INFO("Actor " << id() << " cleaning up before termination...");
// Perform cleanup: close connections, release resources not handled by RAII, etc.
closeConnections();
releaseResources();
// Finally, ensure the actor is marked for termination
Actor::kill(); // Or just kill();
}
Event used to terminate an actor.
Definition Event.h:258

◆ on() [2/4]

void qb::Actor::on ( SignalEvent const & event)
noexcept

Handler for SignalEvent.

Default handler for system signals (e.g., SIGINT) that terminates the actor. Derived classes can override this handler to perform custom signal handling. If overridden, ensure proper state management or actor termination if needed.

Parameters
eventThe received signal event, containing event.signum. Example of overriding:
void on(qb::SignalEvent const &event) override {
if (event.signum == SIGINT) {
LOG_INFO("Actor " << id() << " received SIGINT, performing graceful shutdown.");
// Custom shutdown logic here...
kill(); // Terminate the actor
} else if (event.signum == SIGUSR1) {
LOG_INFO("Actor " << id() << " received SIGUSR1, reloading configuration.");
reloadConfig();
} else {
LOG_WARN("Actor " << id() << " received unhandled signal: " << event.signum);
// Default behavior for other signals might be to kill, or call base:
// Actor::on(event);
}
}
#define LOG_WARN(X)
Warning-level log macro (no-op if QB_STDOUT_LOG is not defined)
Definition io.h:236
Event used to handle system signals.
Definition Event.h:272

◆ on() [3/4]

void qb::Actor::on ( UnregisterCallbackEvent const & event)
noexcept

Handler for UnregisterCallbackEvent.

This handler unregisters a previously registered callback for this actor. It should generally not be overridden by derived classes as its behavior is fixed.

Parameters
eventThe received unregister callback event.
Note
This event is usually sent internally when unregisterCallback() is called.

◆ on() [4/4]

void qb::Actor::on ( PingEvent const & event)
noexcept

Handler for PingEvent.

Responds to ping requests, primarily used for actor alive checks, diagnostics, and by the require<T>() mechanism for actor discovery. The default implementation sends a RequireEvent back to the source of the PingEvent if the ping type matches.

Parameters
eventThe received ping event, containing event.type to match against.
Note
Derived classes typically do not need to override this unless they have very specific custom ping/discovery logic.

◆ id()

ActorId qb::Actor::id ( ) const
inlinenodiscardnoexcept

Get ActorId.

Returns
ActorId of this actor. This ID is unique within the QB system.

◆ getIndex()

CoreId qb::Actor::getIndex ( ) const
nodiscardnoexcept

Get core index.

Returns
CoreId (unsigned short) indicating the VirtualCore where this actor is running.

◆ getName()

std::string_view qb::Actor::getName ( ) const
nodiscardnoexcept

Get derived class name.

Returns
A std::string_view of this actor's demangled class name.
Note
The name is determined at compile time via typeid.

◆ getCoreSet()

const CoreIdSet & qb::Actor::getCoreSet ( ) const
nodiscardnoexcept

Get the set of cores that this actor's VirtualCore can communicate with.

Returns
Const reference to a CoreIdSet representing connected cores.

This reflects the CoreSet the VirtualCore was initialized with.

◆ time()

uint64_t qb::Actor::time ( ) const
nodiscardnoexcept

Get current time from the VirtualCore's perspective (nanoseconds since epoch).

Returns
uint64_t timestamp in nanoseconds.

This value is optimized and cached/updated by the VirtualCore at the beginning of each of its processing loops. Thus, multiple calls to time() within the same event handler or onCallback() invocation will return the same timestamp.

// ...
auto t1 = time();
// ... some heavy calculation ...
assert(t1 == time()); // true - will not assert within the same event handler execution
uint64_t time() const noexcept
Get current time from the VirtualCore's perspective (nanoseconds since epoch).

For a continuously updating, high-precision timestamp, use qb::NanoTimestamp()::count() from <qb/system/timestamp.h>.

Note
This time is primarily for relative measurements or logging within an actor's turn.

◆ getService()

template<typename _ServiceActor>
_ServiceActor * qb::Actor::getService ( ) const
nodiscardnoexcept

Get direct access to ServiceActor* in same core.

Returns
ptr to _ServiceActor else nullptr if not registered in core

◆ is_alive()

bool qb::Actor::is_alive ( ) const
nodiscardnoexcept

Check if Actor is alive and processing events.

Returns
true if Actor is alive (i.e., kill() has not been effectively processed yet), false otherwise.

An actor is considered alive until its kill() method has been called AND the VirtualCore has processed its removal. It might still process events in its queue after kill() is called but before it's fully removed.

◆ registerCallback()

template<typename _Actor>
void qb::Actor::registerCallback ( _Actor & actor) const
noexcept

Register a looped callback for this actor.

Template Parameters
_ActorThe derived actor type, which must inherit from qb::ICallback.
Parameters
actorA reference to the derived actor instance (usually *this).

The registered onCallback() method (from qb::ICallback) will be called by the VirtualCore during each of its processing loop iterations, after event processing. This allows the actor to perform periodic tasks or background operations. The callback remains active until explicitly unregistered or the actor is terminated.

Note
Ensure the onCallback() implementation is fast and non-blocking.
See also
qb::ICallback
class MyPollingActor
: public qb::Actor
, public qb::ICallback // Must inherit from ICallback
{
public:
bool onInit() override {
registerCallback(*this); // Register self for periodic callbacks
return true;
}
void onCallback() override {
// This code will be executed periodically by the VirtualCore
// pollExternalSystem();
// if (checkCondition()) {
// unregisterCallback(); // Stop further callbacks
// }
}
// ... other methods and event handlers ...
};
void registerCallback(_Actor &actor) const noexcept
Register a looped callback for this actor.
Interface for actor callbacks.
Definition ICallback.h:49
virtual void onCallback()=0
Callback function executed during each VirtualCore loop iteration.

◆ unregisterCallback()

template<typename _Actor>
void qb::Actor::unregisterCallback ( _Actor & actor) const
noexcept

Unregister a previously registered looped callback for this actor.

Template Parameters
_ActorThe derived actor type.
Parameters
actorA reference to the derived actor instance (usually *this).

Stops the periodic invocation of the actor's onCallback() method. It is safe to call this even if no callback is currently registered.

Note
Can be called from within onCallback() to self-terminate the callback cycle, or from any event handler.
// void on(MyStopEvent& event) {
// unregisterCallback(*this); // Stop the periodic callback
// }

◆ registerEvent()

template<typename _Event, typename _Actor>
void qb::Actor::registerEvent ( _Actor & actor) const
noexcept

Subscribe this actor to listen for a specific event type.

Template Parameters
_EventThe type of event to listen for (must derive from qb::Event).
_ActorThe derived actor type that implements the on(_Event&) handler.
Parameters
actorA reference to the derived actor instance (usually *this).

After registration, if an event of type _Event is sent to this actor's ID, its corresponding void on(_Event& event) or void on(const _Event& event) method will be invoked by the VirtualCore. This is typically called within the actor's onInit() method.

Note
The actor must have a public member function void on(const _Event& event) or void on(_Event& event).
// bool onInit() override {
// registerEvent<MyCustomEvent>(*this);
// registerEvent<AnotherEvent>(*this);
// return true;
// }
//
// void on(const MyCustomEvent& event) { handle MyCustomEvent... }
// void on(AnotherEvent& event) { handle AnotherEvent, can reply/forward }

◆ unregisterEvent()

template<typename _Event, typename _Actor>
void qb::Actor::unregisterEvent ( _Actor & actor) const
noexcept

Unsubscribe this actor from listening to a specific event type.

Template Parameters
_EventThe type of event to stop listening for.
_ActorThe derived actor type.
Parameters
actorA reference to the derived actor instance (usually *this).

After this call, the actor will no longer receive new events of type _Event. It is safe to call this for event types the actor was not subscribed to.

// void on(StopListeningEvent& event) {
// unregisterEvent<MyCustomEvent>(*this);
// }

◆ to()

EventBuilder qb::Actor::to ( ActorId dest) const
nodiscardnoexcept

Get an EventBuilder for sending chained events to a destination actor.

Parameters
destThe ActorId of the destination actor.
Returns
An Actor::EventBuilder instance associated with the destination actor.

This provides a fluent interface for sending multiple events to the same actor:

// ActorId target_id = GetSomeActorId();
// to(target_id)
// .push<MyEvent1>()
// .push<MyEvent2>(param1, param2)
// .push<MyEvent3>(data_ptr);

All events pushed via the builder are sent in an ordered fashion, similar to push().

Attention
Multiple calls to to(same_id) will yield EventBuilder instances that operate on the same underlying communication pipe to that destination. Event ordering is maintained per pipe.
See also
Actor::EventBuilder

◆ push()

template<typename _Event, typename... _Args>
_Event & qb::Actor::push ( ActorId const & dest,
_Args &&... args ) const
noexcept

Send a new event in an ordered fashion to a destination actor, returning a reference to it.

Template Parameters
_EventThe type of event to create and send (must derive from qb::Event).
_ArgsTypes of arguments to forward to the _Event constructor.
Parameters
destThe ActorId of the destination actor.
argsArguments to forward to the constructor of _Event.
Returns
A mutable reference to the constructed _Event object before it is sent. This allows modification of the event's members after construction but before sending.

This is the primary and recommended method for sending events. Events sent using push() to the same destination actor from the same source actor are guaranteed to be received in the order they were pushed. The event is queued and sent by the VirtualCore at an appropriate time (usually at the end of the current processing loop). Supports events with non-trivially destructible members (e.g., std::string, std::vector).

// ActorId target_id = GetSomeActorId();
// auto& my_evt = push<MyDataEvent>(target_id, initial_value);
// my_evt.data_field = 42; // Modify event before it's sent
// my_evt.message = "Hello";
//
// push<AnotherEvent>(target_id); // This will be processed by target_id after my_evt
Note
If the event type has a non-trivial destructor, the framework ensures it is called appropriately.
Attention
Do not store the returned reference beyond the current scope, as the event object's lifetime is managed by the framework after it's sent.

◆ send()

template<typename _Event, typename... _Args>
void qb::Actor::send ( ActorId const & dest,
_Args &&... args ) const
noexcept

Send a new event in an unordered fashion to a destination actor.

Template Parameters
_EventThe type of event to create and send (must derive from qb::Event and be trivially destructible).
_ArgsTypes of arguments to forward to the _Event constructor.
Parameters
destThe ActorId of the destination actor.
argsArguments to forward to the constructor of _Event.

Events sent using send() are not guaranteed to be received in the order they were sent, even if sent to the same destination from the same source. This method may offer slightly lower latency for same-core communication in specific scenarios but sacrifices ordering.

Note
The _Event type must be trivially destructible (e.g., contain only POD types or qb::string). std::string, std::vector, etc., are not permitted.
// ActorId critical_service_id = GetSomeActorId();
// // Fire-and-forget status update, order not critical
// send<StatusUpdateEvent>(critical_service_id, current_status);
Attention
Use with caution. Prefer push() for most use cases. Misuse can lead to difficult-to-debug race conditions or logical errors if order matters.

◆ build_event()

template<typename _Event, typename... _Args>
_Event qb::Actor::build_event ( qb::ActorId const source,
_Args &&... args ) const
nodiscardnoexcept

Construct an event locally, intended for immediate self-processing or direct calls.

Template Parameters
_EventThe type of event to build (must derive from qb::Event).
_ArgsTypes of arguments to forward to the _Event constructor.
Parameters
sourceThe ActorId to be set as the source of this event (usually this->id()).
argsArguments to forward to the constructor of _Event.
Returns
A locally constructed _Event object.

This method creates an event object but does not send it through the actor system's messaging queues. It's typically used to prepare an event that will be passed directly to one of the actor's own on() handlers or to a referenced actor's methods. The dest field of the event will be set to this->id().

// // ... inside an actor method ...
// MyInternalEvent local_evt = build_event<MyInternalEvent>(id(), event_data);
// local_evt.some_flag = true;
// this->on(local_evt); // Directly call the event handler
Note
The lifetime of the returned event is managed by the caller. This does not involve the actor framework's event queue.

◆ is() [1/2]

template<typename _Type>
bool qb::Actor::is ( uint32_t const id) const
inlinenodiscardnoexcept

Check if a given ID matches the type ID of _Type.

Template Parameters
_TypeThe type to check against.
Parameters
idThe type ID (usually from an event or actor) to compare.
Returns
true if id is the type ID of _Type, false otherwise.

◆ is() [2/2]

template<typename _Type>
bool qb::Actor::is ( RequireEvent const & event) const
inlinenodiscardnoexcept

Check if a RequireEvent is for a specific actor type.

Template Parameters
_TypeThe actor type to check against.
Parameters
eventThe RequireEvent to inspect.
Returns
true if event.type matches the type ID of _Type, false otherwise.
See also
qb::RequireEvent

◆ require()

template<typename... _Actors>
bool qb::Actor::require ( ) const
noexcept

Request discovery of other actors of specified types.

Template Parameters
_ActorsVariadic template pack of actor types to discover.
Returns
true if the discovery ping was successfully broadcasted for all types.

For each type in _Actors, this method broadcasts a PingEvent. Live actors of the specified types will respond with a RequireEvent, which this actor must be registered to handle (via registerEvent<RequireEvent>(*this)). The on(RequireEvent&) handler can then use is<_ActorType>(event) to identify responses.

// bool onInit() override {
// registerEvent<qb::RequireEvent>(*this);
// require<ServiceA, ServiceB>(); // Discover ServiceA and ServiceB instances
// return true;
// }
//
// void on(const qb::RequireEvent& event) {
// if (is<ServiceA>(event) && event.status == qb::ActorStatus::Alive) {
// // _service_a_id = event.getSource();
// } else if (is<ServiceB>(event) && event.status == qb::ActorStatus::Alive) {
// // _service_b_id = event.getSource();
// }
// }
See also
qb::PingEvent, qb::RequireEvent

◆ broadcast()

template<typename _Event, typename... _Args>
void qb::Actor::broadcast ( _Args &&... args) const
noexcept

Broadcast an event to all actors on all cores.

Template Parameters
_EventThe type of event to broadcast (must derive from qb::Event).
_ArgsTypes of arguments to forward to the _Event constructor.
Parameters
argsArguments to forward to the constructor of _Event.

The event will be sent to every actor currently running in the system across all VirtualCores. The source of the event will be this actor's ID. Use push<MyEvent>(qb::BroadcastId(core_id), ...) to broadcast only to a specific core.

// broadcast<SystemShutdownNoticeEvent>("System shutting down in 5 minutes");
Note
Ensure the event type _Event is appropriate for system-wide broadcast and that all potential recipient actors are registered to handle it or will ignore it safely.

◆ reply()

void qb::Actor::reply ( Event & event) const
noexcept

Reply to the source of a received event, reusing the event object.

Parameters
eventThe event object that was received. This event will be modified (its dest and source will be swapped) and sent back to its original source.

This is the most efficient way to send a response back to the sender of an event. The original event object is reused, minimizing allocations and copies. The on() handler receiving the event must take it by non-const reference (MyEvent& event) to allow reply() to modify and effectively consume it.

// void on(MyRequestEvent& request) { // Note: non-const reference
// request.result_data = process(request.input_data);
// request.status_code = 200;
// reply(request); // Sends the modified MyRequestEvent back to its original source
// }
Attention
After calling reply(event), the event object in the current handler should be considered consumed and no longer valid for further use or modification.

◆ forward()

void qb::Actor::forward ( ActorId dest,
Event & event ) const
noexcept

Forward a received event to a new destination, reusing the event object.

Parameters
destThe ActorId of the new destination actor.
eventThe event object that was received. This event will be modified (its dest will be updated to dest) and sent. The original source of the event is preserved.

This is an efficient way to delegate an event to another actor without creating a new event. The on() handler receiving the event must take it by non-const reference (MyEvent& event) to allow forward() to modify and effectively consume it.

// void on(WorkItemEvent& item) { // Note: non-const reference
// if (item.type == WorkType::TypeA)
// forward(_worker_a_id, item); // Forward to Worker A
// else
// forward(_worker_b_id, item); // Forward to Worker B
// }
Attention
After calling forward(dest, event), the event object in the current handler should be considered consumed and no longer valid for further use or modification.

◆ getPipe()

Pipe qb::Actor::getPipe ( ActorId dest) const
nodiscardnoexcept

Get direct access to the underlying communication pipe for a destination actor.

Parameters
destThe ActorId of the destination actor.
Returns
A qb::Pipe object representing the unidirectional communication channel to dest.

This provides lower-level access to the event sending mechanism. It can be useful for performance-critical scenarios, especially when sending multiple events to the same destination or when needing to pre-allocate buffer space for large events using Pipe::allocated_push().

// ActorId target_id = GetSomeActorId();
// qb::Pipe comm_pipe = getPipe(target_id);
// auto& ev1 = comm_pipe.push<MyEvent1>();
// auto& ev2 = comm_pipe.allocated_push<LargeEvent>(data_size, constructor_args_for_large_event);
See also
qb::Pipe
Pipe::push
Pipe::allocated_push

◆ addRefActor()

template<typename _Actor, typename... _Args>
_Actor * qb::Actor::addRefActor ( _Args &&... args) const

Create and initialize a new referenced actor on the same VirtualCore.

Template Parameters
_ActorThe concrete derived actor type to create (must inherit from qb::Actor).
_ArgsTypes of arguments to forward to the _Actor's constructor.
Parameters
argsArguments to forward to the constructor of _Actor.
Returns
A raw pointer to the newly created _Actor instance if successful (i.e., its onInit() returned true), otherwise nullptr.

Referenced actors are created on the same VirtualCore as the calling (parent) actor. The parent receives a raw pointer to the child actor. This allows for direct method calls from the parent to the child, bypassing the event queue for the child. The child actor still has its own ActorId and can receive events normally.

Note
The parent actor does not own the referenced actor. The referenced actor manages its own lifecycle and must call kill() to terminate. The parent must be aware that the pointer can become dangling if the child terminates independently.
// // Inside ParentActor
// HelperActor* _helper = addRefActor<HelperActor>(initial_config_for_helper);
// if (_helper) {
// // Helper created successfully. Can send events:
// push<TaskEvent>(_helper->id(), task_data);
// // Or, cautiously, call public methods (bypasses event queue):
// // _helper->doSomethingSynchronously();
// } else {
// // LOG_CRIT("Failed to create HelperActor for ParentActor " << id());
// }
Attention
Direct method calls on the referenced actor bypass its event queue and mailbox, which can break actor model guarantees if not handled with extreme care. Prefer sending events to the child's ID (child_actor->id()) for most interactions.