Corium 1.1.0
High-Performance Zero-Heap C++20 MPSC Application Runtime
Loading...
Searching...
No Matches
ServiceRegistry.hpp
Go to the documentation of this file.
1
7#pragma once
8
9#include <array>
10#include <cstddef>
11#include <stop_token>
12
14
15namespace corium {
16
17namespace internal {
18
19template <typename T, typename Context>
20concept HasSetContext = requires(T& t, Context ctx) {
21 t.setContext(ctx);
22};
23
24template <typename T>
25concept HasInitialize = requires(T& t) {
26 t.initialize();
27};
28
29template <typename T>
30concept HasRunToken = requires(T& t, std::stop_token st) {
31 t.run(st);
32};
33
34template <typename T>
35concept HasStart = requires(T& t) {
36 t.start();
37};
38
39template <typename T>
40concept HasStop = requires(T& t) {
41 t.stop();
42};
43
44template <typename T>
45concept HasJoin = requires(T& t) {
46 t.join();
47};
48
49} // namespace internal
50
56template <size_t MaxServices = 8, typename EventVariant = DefaultEvents>
58public:
60
63 void* instance = nullptr;
65 void (*initFn)(void* inst, ServiceContextType ctx) = nullptr;
66 void (*startFn)(void* inst) = nullptr;
67 void (*stopFn)(void* inst) noexcept = nullptr;
68 void (*joinFn)(void* inst) noexcept = nullptr;
69 };
70
72
77 template <typename ServiceType>
78 bool registerService(ServiceType& serviceInstance)
79 {
80 if (_count >= MaxServices) {
81 return false;
82 }
83 _services[_count] = ServiceHandle{
84 &serviceInstance,
85 internal::getTypeId<ServiceType>(),
86 [](void* ptr, ServiceContextType ctx) {
87 auto* s = static_cast<ServiceType*>(ptr);
88 if constexpr (internal::HasSetContext<ServiceType, ServiceContextType>) { s->setContext(ctx); }
89 if constexpr (internal::HasInitialize<ServiceType>) { s->initialize(); }
90 },
91 [](void* ptr) {
92 auto* s = static_cast<ServiceType*>(ptr);
94 s->startThread(s);
95 } else if constexpr (internal::HasStart<ServiceType>) {
96 s->start();
97 }
98 },
99 [](void* ptr) noexcept {
100 auto* s = static_cast<ServiceType*>(ptr);
101 if constexpr (internal::HasStop<ServiceType>) { s->stop(); }
102 },
103 [](void* ptr) noexcept {
104 auto* s = static_cast<ServiceType*>(ptr);
105 if constexpr (internal::HasJoin<ServiceType>) { s->join(); }
106 }
107 };
108 _count++;
109 return true;
110 }
111
113 [[nodiscard]] void* getServiceById(internal::TypeIdPtr typeId) const noexcept
114 {
115 for (size_t i = 0; i < _count; ++i) {
116 if (_services[i].typeId == typeId) {
117 return _services[i].instance;
118 }
119 }
120 return nullptr;
121 }
122
126 template <typename ServiceType>
127 [[nodiscard]] ServiceType* getService() const noexcept
128 {
129 return static_cast<ServiceType*>(getServiceById(internal::getTypeId<ServiceType>()));
130 }
131
135 template <typename ServiceType>
136 [[nodiscard]] EventSinkT<EventVariant> getServiceSink() const noexcept
137 {
138 auto* service = getService<ServiceType>();
139 if (service) {
140 if constexpr (requires { service->sink(); }) {
141 return service->sink();
142 }
143 }
145 }
146
149 {
150 ctx.setRegistry(const_cast<BasicServiceRegistry*>(this), [](void* regPtr, internal::TypeIdPtr typeId) -> void* {
151 return static_cast<BasicServiceRegistry*>(regPtr)->getServiceById(typeId);
152 });
153
154 for (size_t i = 0; i < _count; ++i) {
155 if (_services[i].initFn) {
156 _services[i].initFn(_services[i].instance, ctx);
157 }
158 if (_services[i].startFn) {
159 _services[i].startFn(_services[i].instance);
160 }
161 }
162 }
163
165 void shutdown() noexcept
166 {
167 for (size_t i = 0; i < _count; ++i) {
168 if (_services[i].stopFn) {
169 _services[i].stopFn(_services[i].instance);
170 }
171 }
172 for (size_t i = 0; i < _count; ++i) {
173 if (_services[i].joinFn) {
174 _services[i].joinFn(_services[i].instance);
175 }
176 }
177 _count = 0;
178 }
179
181 [[nodiscard]] size_t size() const noexcept
182 {
183 return _count;
184 }
185
186private:
187 std::array<ServiceHandle, MaxServices> _services{};
188 size_t _count = 0;
189};
190
193
195template <size_t MaxServices = 8, typename EventVariant = DefaultEvents>
197
198} // namespace corium
Dependency injection context for background services.
void setRegistry(void *registryPtr, GetServiceFn fn) noexcept
Configure registry resolution bridge (internal framework usage).
Definition ServiceContext.hpp:46
Non-allocating ServiceRegistry storing service handles in a fixed stack/static array....
Definition ServiceRegistry.hpp:57
void * getServiceById(internal::TypeIdPtr typeId) const noexcept
Retrieve a registered service instance by static type ID.
Definition ServiceRegistry.hpp:113
bool registerService(ServiceType &serviceInstance)
Register a background service instance by reference.
Definition ServiceRegistry.hpp:78
void shutdown() noexcept
Stop and join all registered background service threads.
Definition ServiceRegistry.hpp:165
size_t size() const noexcept
Access number of registered services.
Definition ServiceRegistry.hpp:181
EventSinkT< EventVariant > getServiceSink() const noexcept
Retrieve event sink handle of a target registered service if available.
Definition ServiceRegistry.hpp:136
void initialize(ServiceContextType ctx)
Initialize and launch all registered background service jthreads.
Definition ServiceRegistry.hpp:148
ServiceType * getService() const noexcept
Retrieve a registered service instance by concrete type.
Definition ServiceRegistry.hpp:127
Definition ServiceRegistry.hpp:25
Definition ServiceRegistry.hpp:45
Definition ServiceRegistry.hpp:30
Definition ServiceRegistry.hpp:20
Definition ServiceRegistry.hpp:35
Definition ServiceRegistry.hpp:40
const void * TypeIdPtr
Definition VariantIndex.hpp:60
Definition Application.hpp:16
Non-allocating type-erased handle for static background services.
Definition ServiceRegistry.hpp:62
void * instance
Definition ServiceRegistry.hpp:63
void(* startFn)(void *inst)
Definition ServiceRegistry.hpp:66
void(* stopFn)(void *inst) noexcept
Definition ServiceRegistry.hpp:67
internal::TypeIdPtr typeId
Definition ServiceRegistry.hpp:64
void(* joinFn)(void *inst) noexcept
Definition ServiceRegistry.hpp:68
void(* initFn)(void *inst, ServiceContextType ctx)
Definition ServiceRegistry.hpp:65