Skip to content

Instantly share code, notes, and snippets.

@SanderMertens
Last active April 6, 2020 09:32
Show Gist options
  • Save SanderMertens/75623341159c79a31413be09f7d8ccc3 to your computer and use it in GitHub Desktop.
Save SanderMertens/75623341159c79a31413be09f7d8ccc3 to your computer and use it in GitHub Desktop.
#include <meta_test.h>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
ECS_STRUCT(Position, {
float x;
float y;
});
ECS_STRUCT(Velocity, {
float x;
float y;
});
ECS_STRUCT(Mass, {
float value;
});
ECS_STRUCT(Points, {
ecs_vector(Position) points_vec;
});
ECS_STRUCT(PointArray, {
Position points[8];
})
static
void json_ser_type(ecs_vector_t *ser, void *base, ecs_strbuf_t *str);
static
void json_ser_primitive(ecs_type_op_t *op, void *base, ecs_strbuf_t *str) {
const char *bool_str[] = { "false", "true" };
switch(op->is.primitive) {
case EcsBool:
ecs_strbuf_appendstr(str, bool_str[*(bool*)base]);
break;
case EcsChar:
ecs_strbuf_appendstrn(str, "\"", 1);
ecs_strbuf_appendstrn(str, (char*)base, 1);
ecs_strbuf_appendstrn(str, "\"", 1);
break;
case EcsByte:
ecs_strbuf_append(str, "%u", *(uint8_t*)base);
break;
case EcsU8:
ecs_strbuf_append(str, "%u", *(uint8_t*)base);
break;
case EcsU16:
ecs_strbuf_append(str, "%u", *(uint16_t*)base);
break;
case EcsU32:
ecs_strbuf_append(str, "%u", *(uint32_t*)base);
break;
case EcsU64:
ecs_strbuf_append(str, "%u", *(uint64_t*)base);
break;
case EcsI8:
ecs_strbuf_append(str, "%d", *(int8_t*)base);
break;
case EcsI16:
ecs_strbuf_append(str, "%d", *(int16_t*)base);
break;
case EcsI32:
ecs_strbuf_append(str, "%d", *(int32_t*)base);
break;
case EcsI64:
ecs_strbuf_append(str, "%d", *(int64_t*)base);
break;
case EcsF32:
ecs_strbuf_append(str, "%f", *(float*)base);
break;
case EcsF64:
ecs_strbuf_append(str, "%f", *(double*)base);
break;
case EcsIPtr:
ecs_strbuf_appendstrn(str, "%i", *(intptr_t*)base);
break;
case EcsUPtr:
ecs_strbuf_appendstrn(str, "%u", *(uintptr_t*)base);
break;
case EcsString: {
char *value = *(char**)base;
if (value) {
ecs_strbuf_appendstrn(str, "\"", 1);
ecs_strbuf_appendstr(str, value);
ecs_strbuf_appendstrn(str, "\"", 1);
} else {
ecs_strbuf_appendstr(str, "null");
}
break;
}
case EcsEntity:
ecs_strbuf_appendstrn(str, "%u", *(intptr_t*)base);
break;
}
}
static
void json_ser_elements(
ecs_vector_t *elem_ops,
void *base,
int32_t elem_count,
int32_t elem_size,
ecs_strbuf_t *str)
{
ecs_strbuf_appendstrn(str, "[", 1);
void *ptr = base;
int i;
for (i = 0; i < elem_count; i ++) {
if (i) {
ecs_strbuf_appendstrn(str, ",", 1);
}
json_ser_type(elem_ops, ptr, str);
ptr = ECS_OFFSET(ptr, elem_size);
}
ecs_strbuf_appendstrn(str, "]", 1);
}
static
void json_ser_array(
ecs_type_op_t *op,
void *base,
ecs_strbuf_t *str)
{
json_ser_elements(op->is.collection, base, op->count, op->size, str);
}
static
void json_ser_vector(
ecs_type_op_t *op,
void *base,
ecs_strbuf_t *str)
{
ecs_vector_t *value = *(ecs_vector_t**)base;
int32_t count = ecs_vector_count(value);
void *array = ecs_vector_first(value);
ecs_vector_t *elem_ops = op->is.collection;
ecs_type_op_t *elem_op_hdr = (ecs_type_op_t*)ecs_vector_first(elem_ops);
ecs_assert(elem_op_hdr != NULL, ECS_INTERNAL_ERROR, NULL);
ecs_assert(elem_op_hdr->kind == EcsOpHeader, ECS_INTERNAL_ERROR, NULL);
size_t elem_size = elem_op_hdr->size;
json_ser_elements(elem_ops, array, count, elem_size, str);
}
static
void json_ser_type(ecs_vector_t *ser, void *base, ecs_strbuf_t *str) {
ecs_type_op_t *ops = (ecs_type_op_t*)ecs_vector_first(ser);
int32_t count = ecs_vector_count(ser);
int elem_count[64] = {0};
int sp = 0;
for (int i = 0; i < count; i ++) {
ecs_type_op_t *op = &ops[i];
if (sp && elem_count[sp] && op->kind != EcsOpPop) {
ecs_strbuf_appendstrn(str, ",", 1);
}
elem_count[sp] ++;
if (op->name) {
ecs_strbuf_append(str, "\"%s\":", op->name);
}
switch(op->kind) {
case EcsOpHeader:
break;
case EcsOpPrimitive:
json_ser_primitive(op, ECS_OFFSET(base, op->offset), str);
break;
case EcsOpEnum:
break;
case EcsOpBitmask:
break;
case EcsOpPush:
ecs_strbuf_appendstrn(str, "{", 1);
sp ++;
elem_count[sp] = 0;
break;
case EcsOpPop:
ecs_strbuf_appendstrn(str, "}", 1);
sp --;
break;
case EcsOpArray:
json_ser_array(op, ECS_OFFSET(base, op->offset), str);
break;
case EcsOpVector:
json_ser_vector(op, ECS_OFFSET(base, op->offset), str);
break;
}
}
}
static
void ecs_to_json(ecs_world_t *world, ecs_entity_t e) {
ecs_type_t type = ecs_get_type(world, e);
ecs_entity_t *ids = (ecs_entity_t*)ecs_vector_first(type);
int32_t count = ecs_vector_count(type);
ecs_entity_t EEcsTypeSerializer = ecs_lookup(world, "EcsTypeSerializer");
int i;
for (i = 0; i < count; i ++) {
EcsTypeSerializer *ser = ecs_get_ptr(world, ids[i], EcsTypeSerializer);
if (ser) {
ecs_strbuf_t str = ECS_STRBUF_INIT;
void *ptr = _ecs_get_ptr(world, e, ids[i]);
json_ser_type(ser->ops, ptr, &str);
char *json = ecs_strbuf_get(&str);
printf("%s: %s\n", ecs_get_id(world, ids[i]), json);
free(json);
}
}
}
int main(int argc, char *argv[]) {
/* Create the world, pass arguments for overriding the number of threads,fps
* or for starting the admin dashboard (see flecs.h for details). */
flecs::world world(argc, argv);
flecs::import<flecs::components::meta>(world, 0);
flecs::component<Position>(world, "Position")
.set<flecs::components::meta::Type>(__Position__);
flecs::component<Velocity>(world, "Velocity")
.set<flecs::components::meta::Type>(__Velocity__);
flecs::component<Mass>(world, "Mass")
.set<flecs::components::meta::Type>(__Mass__);
flecs::component<Points>(world, "Points")
.set<flecs::components::meta::Type>(__Points__);
flecs::component<PointArray>(world, "PointArray")
.set<flecs::components::meta::Type>(__PointArray__);
ecs_vector_t *vec = ecs_vector_new(Position, 3);
Position *
el = ecs_vector_add(&vec, Position);
*el = (Position){10, 20};
el = ecs_vector_add(&vec, Position);
*el = (Position){30, 40};
el = ecs_vector_add(&vec, Position);
*el = (Position){50, 60};
auto e = flecs::entity(world)
.set<Position>({10, 20})
.set<Velocity>({1, 1})
.set<Mass>({1})
.set<Points>({vec})
.set<PointArray>({ {
{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}, {13, 14},
{15, 16}
} });
ecs_to_json(world.c_ptr(), e.id());
world.set_target_fps(60);
std::cout << "Application meta_test is running, press CTRL-C to exit..." << std::endl;
/* Run systems */
while (world.progress()) { }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment