1#include <custom_serializer.h>
2#include <iostream>
3#include <vector>
4#include <inttypes.h>
5
6
7
8static int indent = 0;
9
10#define printIndented(...)\
11 printf("\n%*s", indent * 2, ""); printf(__VA_ARGS__)
12
13class Serializer {
14public:
15 template <typename T>
16 static void serialize(
flecs::world& ecs,
const T& value) {
17 serialize(ecs, ecs.
component<T>(), &value);
18 }
19
20 static void serialize(
22 {
23
24
25 const flecs::TypeSerializer& ts = type.get<flecs::TypeSerializer>();
26
27 Serializer{ecs}.serializeOps(
28 ecs_vec_first_t(&ts.
ops, flecs::meta::op_t),
29 ecs_vec_count(&ts.
ops), ptr);
30 }
31
32private:
33 Serializer(flecs::world& w) : ecs(w) { }
34
35
36 void serializeScope(flecs::meta::op_t *ops, const void *ptr) {
37
38
39 serializeOps(ops + 1, ops->
op_count - 2, ptr);
40 }
41
42
43 void serializeStruct(flecs::meta::op_t *ops,
44 const void *ptr)
45 {
46 printf("{");
47 indent ++;
48
49 serializeScope(ops, ptr);
50
51 indent --;
52 printIndented("}");
53 }
54
55
56 void serializeArray(flecs::meta::op_t *ops,
57 int32_t elem_count, const void *ptr)
58 {
59 printf("[");
60
61
62
63 for (int i = 0; i < elem_count; i ++) {
64 if (i) {
65 printf(", ");
66 }
67
68 serializeScope(ops, ptr);
69
71 }
72
73 printf("]");
74 }
75
76
77 void serializeVector(flecs::meta::op_t *ops,
78 const void *ptr)
79 {
80 auto vec = static_cast<const ecs_vec_t*>(ptr);
81 serializeArray(ops, vec->count, vec->array);
82 }
83
84
85 void serializeEnum(flecs::meta::op_t *op, const void *ptr)
86 {
88 ecs_map_key_t value;
89
90 if (kind == EcsOpU8 || kind == EcsOpI8) {
91 value = *static_cast<const uint8_t*>(ptr);
92 } else if (kind == EcsOpU16 || kind == EcsOpI16) {
93 value = *static_cast<const uint16_t*>(ptr);
94 } else if (kind == EcsOpU32 || kind == EcsOpI32) {
95 value = *static_cast<const uint32_t*>(ptr);
96 } else if (kind == EcsOpUPtr || kind == EcsOpIPtr) {
97 value = *static_cast<const uintptr_t*>(ptr);
98 } else if (kind == EcsOpU64 || kind == EcsOpI64) {
99 value = *static_cast<const uint64_t*>(ptr);
100 } else {
101 printf("<<invalid underlying enum type>>");
102 return;
103 }
104
107 printf(
"%s", c->
name);
108 }
109
110
111 void serializeOps(flecs::meta::op_t *ops, int32_t op_count,
112 const void *base)
113 {
114 for (int i = 0; i < op_count; i ++) {
115 flecs::meta::op_t *op = &ops[i];
116
117
119 if (i) {
120 printf(",");
121 }
122
123 printIndented(
"%s: ", op->
name);
124 }
125
126
127 void *ptr = ECS_OFFSET(base, op->
offset);
128
130
131
133 serializeStruct(op, ptr);
134 break;
137 break;
139 serializeVector(op, ptr);
140 break;
141
142
143
144
145
152 break;
153
154
157 break;
158
159
160 case EcsOpEnum:
161 serializeEnum(op, ptr);
162 break;
163 case EcsOpBitmask:
164
165
166
167 break;
168 case EcsOpBool:
169 printf("%s",
170 (*static_cast<const bool*>(ptr)) ? "true" : "false");
171 break;
172 case EcsOpChar:
173 printf("'%c'", *static_cast<const char*>(ptr));
174 break;
175 case EcsOpByte:
176 case EcsOpU8:
177 printf("%" PRIu8, *static_cast<const uint8_t*>(ptr));
178 break;
179 case EcsOpU16:
180 printf("%" PRIu16, *static_cast<const uint16_t*>(ptr));
181 break;
182 case EcsOpU32:
183 printf("%" PRIu32, *static_cast<const uint32_t*>(ptr));
184 break;
185 case EcsOpU64:
186 printf("%" PRIu64, *static_cast<const uint64_t*>(ptr));
187 break;
188 case EcsOpI8:
189 printf("%" PRIi8, *static_cast<const int8_t*>(ptr));
190 break;
191 case EcsOpI16:
192 printf("%" PRIi16, *static_cast<const int16_t*>(ptr));
193 break;
194 case EcsOpI32:
195 printf("%" PRIi32, *static_cast<const int32_t*>(ptr));
196 break;
197 case EcsOpI64:
198 printf("%" PRIi64, *static_cast<const int64_t*>(ptr));
199 break;
200 case EcsOpF32:
201 printf("%.2f",
202 static_cast<double>(*static_cast<const float*>(ptr)));
203 break;
204 case EcsOpF64:
205 printf("%.2f", *static_cast<const double*>(ptr));
206 break;
207 case EcsOpUPtr:
208 printf("%" PRIuPTR, *static_cast<const uintptr_t*>(ptr));
209 break;
210 case EcsOpIPtr:
211 printf("%" PRIiPTR, *static_cast<const intptr_t*>(ptr));
212 break;
213 case EcsOpString:
214 printf("\"%s\"", *static_cast<const char**>(ptr));
215 break;
216 case EcsOpEntity: {
218 printf("%s\n", e.path().c_str());
219 break;
220 }
221 case EcsOpId: {
224 break;
225 }
229
230 break;
231 }
232
234 }
235 }
236
237 flecs::world& ecs;
238};
239
240
241
242typedef struct {
243 uint8_t red;
244 uint8_t green;
245 uint8_t blue;
246} Rgb;
247
248typedef enum {
249 Solid, Dashed
250} StrokeKind;
251
252typedef struct {
253 float x, y;
254} Point;
255
256typedef struct {
257 Rgb color;
258 Rgb stroke_color;
259 StrokeKind stroke_kind;
260 ecs_vec_t points;
261} Polygon;
262
263int main(int, char *[]) {
265
266
267
268
270 .member(&Rgb::red, "red")
271 .member(&Rgb::green, "green")
272 .member(&Rgb::blue, "blue");
273
275
277 .member(&Point::x, "x")
278 .member(&Point::y, "y");
279
281 .member(&Polygon::color, "color")
282 .member(&Polygon::stroke_color, "stroke_color")
283 .member(&Polygon::stroke_kind, "stroke_kind")
284 .member(ecs.
vector<Point>(),
"points");
285
286
287 Polygon p = {};
288 p.color = {0, 0, 255};
289 p.stroke_color = {255, 0, 0};
290 p.stroke_kind = Dashed;
291 ecs_vec_init_t(NULL, &p.points, Point, 0);
292 *ecs_vec_append_t(NULL, &p.points, Point) = {0, 0};
293 *ecs_vec_append_t(NULL, &p.points, Point) = {1, 1};
294 *ecs_vec_append_t(NULL, &p.points, Point) = {-1, 1};
295
296
297
298 Serializer::serialize(ecs, p);
299
300 printf("\n");
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326}
flecs::component< T > component(Args &&... args) const
Find or register a component.
ecs_entity_t entity_t
Entity type.
flecs::entity entity(Args &&... args) const
Create an entity.
flecs::id id(E value) const
Convert an enum constant to an entity.
flecs::component< T > component(Args &&... args) const
Find or register a component.