Dawn Framework 1.0
Universal data acquisition framework for embedded systems
generic_handler.hxx
1// dawn/include/dawn/common/generic_handler.hxx
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5
6#pragma once
7
8#include <errno.h>
9
10#include <algorithm>
11#include <vector>
12
13#include "dawn/common/descriptor.hxx"
14#include "dawn/common/handler.hxx"
15#include "dawn/common/objectid.hxx"
16#include "dawn/debug.hxx"
17
18namespace dawn
19{
22template<typename T>
24{
25protected:
28 std::vector<T *> objects;
29 int allocError = OK;
30
37 int registerObject(T *obj)
38 {
39 DAWNASSERT(obj != nullptr, "invalid input");
40 for (const T *tmp : objects)
41 {
42 if (tmp->getIdV() == obj->getIdV())
43 {
44 DAWNERR("Duplicate object ID 0x%" PRIx32 "\n", obj->getIdV());
45 delete obj;
46 allocError = -EEXIST;
47 return allocError;
48 }
49 }
50 objects.push_back(obj);
51 return OK;
52 }
53
60 virtual void onInitObject(T *obj)
61 {
62 }
63
70 virtual void onStartObject(T *obj)
71 {
72 }
73
76 virtual const char *getObjectTypeName() const
77 {
78 return "OBJECT";
79 }
80
81public:
89 {
90#ifdef CONFIG_DAWN_LIFECYCLE_TEARDOWN
91 for (auto it = objects.rbegin(); it != objects.rend(); ++it)
92 {
93 T *obj = *it;
94 DAWNINFO("STOP %s 0x%" PRIx32 "\n", getObjectTypeName(), obj->getIdV());
95 obj->stop();
96 }
97
98 for (T *obj : objects)
99 {
100 DAWNINFO("delete 0x%" PRIx32 "\n", obj->getIdV());
101 delete obj;
102 }
103
104 objects.clear();
105#endif
106 }
107
115 {
116 int ret;
117
118 for (T *obj : objects)
119 {
120 DAWNINFO("CONFIG %s 0x%" PRIx32 "\n", getObjectTypeName(), obj->getIdV());
121 ret = obj->configure();
122 if (ret != OK)
123 {
124 DAWNERR("Failed to configure %s 0x%" PRIx32 " (error %d)\n",
126 obj->getIdV(),
127 ret);
128 return ret;
129 }
130 }
131
132 return OK;
133 }
134
142 {
143 int ret;
144
145 for (T *obj : objects)
146 {
147 DAWNINFO("INIT %s 0x%" PRIx32 "\n", getObjectTypeName(), obj->getIdV());
148 ret = obj->init();
149 if (ret != OK)
150 {
151 DAWNERR("Failed to init %s 0x%" PRIx32 " (error %d)\n",
153 obj->getIdV(),
154 ret);
155 return ret;
156 }
157 onInitObject(obj);
158 }
159
160 return OK;
161 }
162
172 {
173#ifdef CONFIG_DAWN_LIFECYCLE_TEARDOWN
174 int ret;
175 int tmp;
176
177 ret = OK;
178 for (auto it = objects.rbegin(); it != objects.rend(); ++it)
179 {
180 T *obj = *it;
181 DAWNINFO("DEINIT %s 0x%" PRIx32 "\n", getObjectTypeName(), obj->getIdV());
182 tmp = obj->deinit();
183 if (tmp != OK)
184 {
185 DAWNERR("Failed to deinit %s 0x%" PRIx32 " (error %d)\n",
187 obj->getIdV(),
188 tmp);
189 if (ret == OK)
190 {
191 ret = tmp;
192 }
193 }
194 }
195
196 for (T *obj : objects)
197 {
198 DAWNINFO("delete %s 0x%" PRIx32 "\n", getObjectTypeName(), obj->getIdV());
199 delete obj;
200 }
201
202 objects.clear();
203
204 return ret;
205#else
206 return OK;
207#endif
208 }
209
217 {
218 int ret;
219
220 for (T *obj : objects)
221 {
222 onStartObject(obj);
223 DAWNINFO("START %s 0x%" PRIx32 "\n", getObjectTypeName(), obj->getIdV());
224 ret = obj->start();
225 if (ret != OK)
226 {
227 DAWNERR("Failed to start %s 0x%" PRIx32 " (error %d)\n",
229 obj->getIdV(),
230 ret);
231 return ret;
232 }
233 }
234
235 return OK;
236 }
237
247 {
248#ifdef CONFIG_DAWN_LIFECYCLE_TEARDOWN
249 int ret;
250
251 for (auto it = objects.rbegin(); it != objects.rend(); ++it)
252 {
253 T *obj = *it;
254 DAWNINFO("STOP %s 0x%" PRIx32 "\n", getObjectTypeName(), obj->getIdV());
255 ret = obj->stop();
256 if (ret != OK)
257 {
258 DAWNERR("Failed to stop %s 0x%" PRIx32 " (error %d)\n",
260 obj->getIdV(),
261 ret);
262 return ret;
263 }
264 }
265
266 return OK;
267#else
268 return OK;
269#endif
270 }
271
278 bool hasThread() const
279 {
280 return std::any_of(
281 objects.begin(), objects.end(), [](const T *obj) { return obj->hasThread(); });
282 }
283
286 size_t getObjectCount() const
287 {
288 return objects.size();
289 }
290
291#ifdef CONFIG_DAWN_INSPECT
298 const std::vector<T *> &getObjects() const
299 {
300 return objects;
301 }
302#endif // CONFIG_DAWN_INSPECT
303
311 T *getObjectAt(size_t index) const
312 {
313 return (index < objects.size()) ? objects[index] : nullptr;
314 }
315
324 {
325 auto it = std::find_if(
326 objects.begin(), objects.end(), [&id](const T *obj) { return obj->getIdV() == id.v; });
327 return (it != objects.end()) ? *it : nullptr;
328 }
329
340 {
341 allocError = OK;
342 desc.alloc_objects(*this, func);
343 return allocError;
344 }
345};
346
347} // Namespace dawn
Binary device descriptor manager.
std::function< void(CHandler &obj, CDescObject &desc)> allocobj_func_t
Thread function callback storage.
Template handler for object lifecycle management.
virtual const char * getObjectTypeName() const
Get object type name for logging.
int initAll()
Run one-time init() for all configured objects.
size_t getObjectCount() const
Get total number of registered objects.
virtual void onInitObject(T *obj)
Hook for subclass-specific post-object-init handling.
bool hasThread() const
Check if any thread is currently running.
virtual void onStartObject(T *obj)
Hook for subclass-specific pre-start operations.
int registerObject(T *obj)
Register object.
int stopAll()
Stop all objects managed by this handler.
const std::vector< T * > & getObjects() const
Get read-only access to all objects.
int deinitAll()
De-initialize all objects managed by this handler.
T * getObjectById(const SObjectId::UObjectId &id) const
Get object by ObjectID.
int configureAll()
Configure all objects managed by this handler.
std::vector< T * > objects
Vector of registered objects.
int objalloc(CDescriptor &desc, CDescriptor::allocobj_func_t func)
Allocate objects from descriptor.
int startAll()
Start all objects managed by this handler.
T * getObjectAt(size_t index) const
Get object at index.
Base implementation of IHandler interface.
Definition handler.hxx:110
Out-of-tree user-extension hooks for Dawn.
Definition bindable.hxx:13
32-bit encoded object identifier (union with bit field).
Definition objectid.hxx:218