qb  2.0.0.0
C++17 Actor Framework
qb Issue Watch Star Fork Follow @isndev
Loading...
Searching...
No Matches
Actor.h
Go to the documentation of this file.
1
24
25#ifndef QB_ACTOR_H
26#define QB_ACTOR_H
27#include <map>
28#include <tuple>
29#include <utility>
30#include <vector>
31// include from qb
33#include <qb/utility/nocopy.h>
35#include "Event.h"
36#include "ICallback.h"
37#include "Pipe.h"
38
39#ifdef __GNUG__
40#include <cstdlib>
41#include <cxxabi.h>
42#include <memory>
43#endif
44
45namespace qb {
46
47class VirtualCore;
48class ActorProxy;
49class Service;
50
106class Actor : nocopy {
107 friend class VirtualCore;
108 friend class ActorProxy;
109 friend class Service;
110
111 const char *name = "unnamed";
112 ActorId _id;
113 mutable bool _alive = true;
114 std::uint32_t id_type = 0u;
115
124 template <typename _Type>
125 bool require_type() const noexcept;
126
133 explicit Actor(ActorId id) noexcept;
134
135protected:
143 template <typename Tag>
144 static ServiceId registerIndex() noexcept;
145
150
157 Actor() noexcept;
158
165 virtual ~Actor() noexcept = default;
166
197 virtual bool
199 return true;
200 };
201
202public:
216 void kill() const noexcept;
217
221
222public:
227
250 void on(KillEvent const &event) noexcept;
251
278 void on(SignalEvent const &event) noexcept;
279
289 void on(UnregisterCallbackEvent const &event) noexcept;
290
302 void on(PingEvent const &event) noexcept;
303
307
308public:
318 class EventBuilder {
319 friend class Actor;
320 Pipe dest_pipe;
321
327 explicit EventBuilder(Pipe const &pipe) noexcept;
328
329 public:
330 EventBuilder() = delete;
331 EventBuilder(EventBuilder const &rhs) noexcept = default;
332
354 template <typename _Event, typename... _Args>
355 EventBuilder &push(_Args &&...args) noexcept;
356 };
357
362
367 [[nodiscard]] ActorId
368 id() const noexcept {
369 return _id;
370 }
371
376 [[nodiscard]] CoreId getIndex() const noexcept;
377
383 [[nodiscard]] std::string_view getName() const noexcept;
384
390 [[nodiscard]] const CoreIdSet &getCoreSet() const noexcept;
391
408 [[nodiscard]] uint64_t time() const noexcept;
409
413 template <typename T>
414 [[nodiscard]] static ActorId getServiceId(CoreId index) noexcept;
415
420 template <typename _ServiceActor>
421 [[nodiscard]] _ServiceActor *getService() const noexcept;
422
423 // void setCoreLowLatency(bool state) const noexcept;
424
432 [[nodiscard]] bool is_alive() const noexcept;
433
437
444
478 template <typename _Actor>
479 void registerCallback(_Actor &actor) const noexcept;
480
496 template <typename _Actor>
497 void unregisterCallback(_Actor &actor) const noexcept;
498
504 void unregisterCallback() const noexcept;
505
528 template <typename _Event, typename _Actor>
529 void registerEvent(_Actor &actor) const noexcept;
530
545 template <typename _Event, typename _Actor>
546 void unregisterEvent(_Actor &actor) const noexcept;
547
554 template <typename _Event>
555 void unregisterEvent() const noexcept;
556
576 [[nodiscard]] EventBuilder to(ActorId dest) const noexcept;
577
604 template <typename _Event, typename... _Args>
605 _Event &push(ActorId const &dest, _Args &&...args) const noexcept;
606
627 template <typename _Event, typename... _Args>
628 void send(ActorId const &dest, _Args &&...args) const noexcept;
629
651 template <typename _Event, typename... _Args>
652 [[nodiscard]] _Event build_event(qb::ActorId const source,
653 _Args &&...args) const noexcept;
654
661 template <typename _Type>
662 [[nodiscard]] inline bool
663 is(uint32_t const id) const noexcept {
664 return id == type_id<_Type>();
665 }
666
674 template <typename _Type>
675 [[nodiscard]] inline bool
676 is(RequireEvent const &event) const noexcept {
677 return event.type == type_id<_Type>();
678 }
679
706 template <typename... _Actors>
707 bool require() const noexcept;
708
724 template <typename _Event, typename... _Args>
725 void broadcast(_Args &&...args) const noexcept;
726
746 void reply(Event &event) const noexcept;
747
769 void forward(ActorId dest, Event &event) const noexcept;
770
771 // OpenApi : used for module
773 void send(Event const &event) const noexcept;
775 void push(Event const &event) const noexcept;
777 bool try_send(Event const &event) const noexcept;
778
798 [[nodiscard]] Pipe getPipe(ActorId dest) const noexcept;
799
831 template <typename _Actor, typename... _Args>
832 _Actor *addRefActor(_Args &&...args) const;
833
837};
838
845class Service : public Actor {
846public:
847 explicit Service(ServiceId sid);
848};
849
860template <typename Tag>
861class ServiceActor : public Service {
862 friend class Main;
863 friend class CoreInitializer;
864 friend class VirtualCore;
865 static const ServiceId ServiceIndex;
866
867public:
868 ServiceActor()
869 : Service(ServiceIndex) {}
870};
871
879public:
880 virtual ~IActorFactory() = default;
885 virtual Actor *create() = 0;
890 [[nodiscard]] virtual bool isService() const = 0;
891};
892
900class ActorProxy {
901protected:
902 ActorProxy() = default;
903 template <typename _Type>
904 static void
905 setType(Actor &actor) {
906 actor.id_type = ActorProxy::getType<_Type>();
907 }
908 template <typename _Type>
909 static void
910 setName(Actor &actor) {
911 actor.name = ActorProxy::getName<_Type>();
912 }
913
914public:
915 template <typename _Type>
916 static auto
917 getType() {
918 return type_id<_Type>();
919 }
920 template <typename _Type>
921 static const char *
922 getName() {
923#ifdef __GNUC__
924 static std::unique_ptr<char, void (*)(void *)> res{
925 abi::__cxa_demangle(typeid(_Type).name(), nullptr, nullptr, nullptr),
926 std::free};
927
928 return res.get();
929#else
930 return typeid(_Type).name();
931#endif
932 }
933};
934
935// ======= Utility: detect std::reference_wrapper<T> =========
936
937template <template <typename...> class Template, typename T>
938struct is_specialization_of : std::false_type {};
939
940template <template <typename...> class Template, typename... Args>
941struct is_specialization_of<Template, Template<Args...>> : std::true_type {};
942
954template <typename T>
957 using no_ref = std::remove_reference_t<T>;
958
960 static constexpr bool is_ref_wrapper =
962
964 using type = std::conditional_t<
966 no_ref, // Keep ref_wrapper untouched
967
968 std::conditional_t<
969 std::is_array_v<T> && std::is_same_v<std::remove_extent_t<T>, const char>,
970 std::string, // string literals → std::string
971
972 std::decay_t<T> // fallback
973 >
974 >;
975};
976
990template <typename T>
991inline auto actor_factory_forward(T&& val) {
992 using Target = typename actor_factory_param<T>::type;
993
994 if constexpr (std::is_same_v<Target, std::string>) {
995 return std::string(std::forward<T>(val)); // copy literal
996 } else {
997 return std::forward<T>(val); // forward all others
998 }
999}
1000
1010template <typename _Actor, typename... _Args>
1011class TActorFactory : public IActorFactory, public ActorProxy {
1012 using Tuple = std::tuple<typename actor_factory_param<_Args>::type...>;
1013
1014 ActorId _id;
1015 Tuple _parameters;
1016
1017public:
1018 explicit TActorFactory(ActorId const id, _Args&&... args)
1019 : _id(id)
1020 , _parameters(actor_factory_forward<_Args>(std::forward<_Args>(args))...) {}
1021
1022 Actor* create() final {
1023 return create_impl(std::index_sequence_for<_Args...>{});
1024 }
1025
1026 [[nodiscard]] bool isService() const final {
1027 return std::is_base_of_v<Service, _Actor>;
1028 }
1029
1030private:
1031 template <std::size_t... Is>
1032 Actor* create_impl(std::index_sequence<Is...>) {
1033 auto actor = new _Actor(std::get<Is>(_parameters)...);
1034 ActorProxy::setType<_Actor>(*actor);
1035 ActorProxy::setName<_Actor>(*actor);
1036 return actor;
1037 }
1038};
1039
1046using actor = Actor;
1047
1055template <typename Tag>
1057
1058#ifdef QB_LOGGER
1059qb::io::log::stream &operator<<(qb::io::log::stream &os, qb::Actor const &actor);
1060#endif
1061
1071std::ostream &operator<<(std::ostream &os, qb::Actor const &actor);
1072
1073} // namespace qb
1074
1075#endif // QB_ACTOR_H
Helper class for building and sending events to actors.
Definition Actor.h:318
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
bool is(uint32_t const id) const noexcept
Check if a given ID matches the type ID of _Type.
Definition Actor.h:663
void registerEvent(_Actor &actor) const noexcept
Subscribe this actor to listen for a specific event type.
_ServiceActor * getService() const noexcept
Get direct access to ServiceActor* in same core.
_Event build_event(qb::ActorId const source, _Args &&...args) const noexcept
Construct an event locally, intended for immediate self-processing or direct calls.
void unregisterCallback(_Actor &actor) const noexcept
Unregister a previously registered looped callback for this actor.
void on(KillEvent const &event) noexcept
Handler for KillEvent.
_Actor * addRefActor(_Args &&...args) const
Create and initialize a new referenced actor on the same VirtualCore.
uint64_t time() const noexcept
Get current time from the VirtualCore's perspective (nanoseconds since epoch).
Pipe getPipe(ActorId dest) const noexcept
Get direct access to the underlying communication pipe for a destination actor.
_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.
const CoreIdSet & getCoreSet() const noexcept
Get the set of cores that this actor's VirtualCore can communicate with.
std::string_view getName() const noexcept
Get derived class name.
void registerCallback(_Actor &actor) const noexcept
Register a looped callback for this actor.
void forward(ActorId dest, Event &event) const noexcept
Forward a received event to a new destination, reusing the event object.
Actor() noexcept
Default constructor.
ActorId id() const noexcept
Get ActorId.
Definition Actor.h:368
CoreId getIndex() const noexcept
Get core index.
void reply(Event &event) const noexcept
Reply to the source of a received event, reusing the event object.
EventBuilder to(ActorId dest) const noexcept
Get an EventBuilder for sending chained events to a destination actor.
void broadcast(_Args &&...args) const noexcept
Broadcast an event to all actors on all cores.
void send(ActorId const &dest, _Args &&...args) const noexcept
Send a new event in an unordered fashion to a destination actor.
void kill() const noexcept
Terminate this actor and mark it for removal from the system.
bool is(RequireEvent const &event) const noexcept
Check if a RequireEvent is for a specific actor type.
Definition Actor.h:676
bool is_alive() const noexcept
Check if Actor is alive and processing events.
void unregisterEvent(_Actor &actor) const noexcept
Unsubscribe this actor from listening to a specific event type.
virtual bool onInit()
Initialization callback, called once after construction and ID assignment.
Definition Actor.h:198
bool require() const noexcept
Request discovery of other actors of specified types.
Unique identifier for actors.
Definition ActorId.h:374
Internal helper class for actor type and name management.
Definition Actor.h:900
Base class for all events in the actor system.
Definition Event.h:85
Interface for actor factory classes.
Definition Actor.h:878
virtual bool isService() const =0
Checks if the factory creates a service actor.
virtual Actor * create()=0
Creates an actor instance.
Represents a communication channel between actors.
Definition Pipe.h:46
SingletonActor base class, ensuring one instance per VirtualCore per Tag.
Definition Actor.h:861
Internal base class for services.
Definition Actor.h:845
Actor * create() final
Creates an actor instance.
Definition Actor.h:1022
bool isService() const final
Checks if the factory creates a service actor.
Definition Actor.h:1026
Manages a virtual processing core (worker thread) in the actor system.
Definition VirtualCore.h:75
Event system for the QB Actor Framework.
Callback interface for the QB Actor Framework.
Actor communication channel for the QB Actor Framework.
auto actor_factory_forward(T &&val)
Utility function for forwarding and transforming arguments to actor factory.
Definition Actor.h:991
Actor actor
Alias for the Actor class.
Definition Actor.h:1046
std::ostream & operator<<(std::ostream &os, qb::Actor const &actor)
Stream output operator for Actor objects.
ServiceActor< Tag > service_actor
Alias for the ServiceActor template class.
Definition Actor.h:1056
uint16_t CoreId
Type definition for core identifiers.
Definition ActorId.h:51
uint16_t ServiceId
Type definition for service identifiers.
Definition ActorId.h:59
CoreIdBitSet CoreIdSet
Efficient set implementation for storing CoreId values.
Definition ActorId.h:363
Event event
Alias for the base Event class.
Definition Event.h:385
constexpr TypeId type_id()
Function to get a unique type identifier for a given type.
Definition Event.h:72
Pipe pipe
Alias for the Pipe class.
Definition Pipe.h:117
Defines a base class to make derived classes non-copyable.
Event used to terminate an actor.
Definition Event.h:258
Event used for actor health checks.
Definition Event.h:298
Event used to query actor status.
Definition Event.h:310
Event used to handle system signals.
Definition Event.h:272
Event used to unregister an actor's callback.
Definition Event.h:265
Utility struct for processing actor factory constructor arguments.
Definition Actor.h:955
std::remove_reference_t< T > no_ref
Type with references removed.
Definition Actor.h:957
std::conditional_t< is_ref_wrapper, no_ref, std::conditional_t< std::is_array_v< T > &&std::is_same_v< std::remove_extent_t< T >, const char >, std::string, std::decay_t< T > > > type
The resulting type after transformation.
Definition Actor.h:964
static constexpr bool is_ref_wrapper
Whether the type is a reference wrapper.
Definition Actor.h:960
Definition Actor.h:938
nocopy()=default
Default constructor.
Advanced type traits and metaprogramming utilities for the QB Framework.
Optimized unordered map implementations.