Last active
April 6, 2020 09:32
-
-
Save SanderMertens/75623341159c79a31413be09f7d8ccc3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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