code: update flecs to v3
parent
ffb8aa80a2
commit
28c07c53c8
|
@ -160,7 +160,7 @@ void debug_replay_run(void) {
|
|||
Position const *p1 = ecs_get(world_ecs(), plr, Position);
|
||||
|
||||
mime = entity_spawn(EKIND_MACRO_BOT);
|
||||
Position *pos = ecs_get_mut(world_ecs(), mime, Position, NULL);
|
||||
Position *pos = ecs_get_mut(world_ecs(), mime, Position);
|
||||
*pos = *p1;
|
||||
|
||||
ecs_set(world_ecs(), mime, Input, {0});
|
||||
|
@ -184,7 +184,7 @@ void debug_replay_update(void) {
|
|||
|
||||
switch (r->kind) {
|
||||
case RPKIND_KEY: {
|
||||
Input *i = ecs_get_mut(world_ecs(), mime, Input, NULL);
|
||||
Input *i = ecs_get_mut(world_ecs(), mime, Input);
|
||||
i->x = r->pkt.x;
|
||||
i->y = r->pkt.y;
|
||||
i->mx = r->pkt.mx;
|
||||
|
@ -207,7 +207,7 @@ void debug_replay_update(void) {
|
|||
ecs_entity_t e = vehicle_spawn();
|
||||
|
||||
Position const *origin = ecs_get(world_ecs(), mime, Position);
|
||||
Position *dest = ecs_get_mut(world_ecs(), e, Position, NULL);
|
||||
Position *dest = ecs_get_mut(world_ecs(), e, Position);
|
||||
*dest = *origin;
|
||||
|
||||
zpl_array_append(temp_actors, e);
|
||||
|
|
|
@ -14,7 +14,7 @@ ActSpawnCar(void) {
|
|||
ecs_entity_t plr = camera_get().ent_id;
|
||||
|
||||
Position const* origin = ecs_get(world_ecs(), plr, Position);
|
||||
Position * dest = ecs_get_mut(world_ecs(), e, Position, NULL);
|
||||
Position * dest = ecs_get_mut(world_ecs(), e, Position);
|
||||
*dest = *origin;
|
||||
|
||||
debug_replay_special_action(RPKIND_SPAWN_CAR);
|
||||
|
@ -26,7 +26,7 @@ ActSpawnIcemaker(void) {
|
|||
ecs_entity_t plr = camera_get().ent_id;
|
||||
|
||||
Position const* origin = ecs_get(world_ecs(), plr, Position);
|
||||
Position * dest = ecs_get_mut(world_ecs(), e, Position, NULL);
|
||||
Position * dest = ecs_get_mut(world_ecs(), e, Position);
|
||||
*dest = *origin;
|
||||
|
||||
debug_replay_special_action(RPKIND_SPAWN_ICEMAKER_ITEM);
|
||||
|
@ -39,16 +39,16 @@ ActSpawnCirclingDriver(void) {
|
|||
ecs_entity_t e = entity_spawn(EKIND_DEMO_NPC);
|
||||
|
||||
Position const *origin = ecs_get(world_ecs(), plr, Position);
|
||||
Position *veh_dest = ecs_get_mut(world_ecs(), ve, Position, NULL);
|
||||
Position *dest = ecs_get_mut(world_ecs(), e, Position, NULL);
|
||||
Position *veh_dest = ecs_get_mut(world_ecs(), ve, Position);
|
||||
Position *dest = ecs_get_mut(world_ecs(), e, Position);
|
||||
*veh_dest = *origin;
|
||||
*dest = *origin;
|
||||
|
||||
Input *input = ecs_get_mut(world_ecs(), e, Input, NULL);
|
||||
Input *input = ecs_get_mut(world_ecs(), e, Input);
|
||||
zpl_zero_item(input);
|
||||
input->x = input->y = 1.0f;
|
||||
|
||||
Vehicle *veh = ecs_get_mut(world_ecs(), ve, Vehicle, NULL);
|
||||
Vehicle *veh = ecs_get_mut(world_ecs(), ve, Vehicle);
|
||||
veh->seats[0] = e;
|
||||
|
||||
ecs_set(world_ecs(), e, IsInVehicle, { .veh = ve });
|
||||
|
@ -209,12 +209,12 @@ ActSpawnDemoNPCs(void) {
|
|||
|
||||
for (uint32_t i = 0; i < 1000; i++) {
|
||||
uint64_t e = entity_spawn(EKIND_DEMO_NPC);
|
||||
ecs_add(world_ecs(), e, EcsDemoNPC);
|
||||
Position *pos = ecs_get_mut(world_ecs(), e, Position, NULL);
|
||||
ecs_add(world_ecs(), e, DemoNPC);
|
||||
Position *pos = ecs_get_mut(world_ecs(), e, Position);
|
||||
pos->x=(float)(rand() % world_dim());
|
||||
pos->y=(float)(rand() % world_dim());
|
||||
|
||||
Velocity *v = ecs_get_mut(world_ecs(), e, Velocity, NULL);
|
||||
Velocity *v = ecs_get_mut(world_ecs(), e, Velocity);
|
||||
v->x = (float)((rand()%3-1) * 10);
|
||||
v->y = (float)((rand()%3-1) * 10);
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include "entity.h"
|
||||
#include "entity_view.h"
|
||||
#include "flecs/flecs.h"
|
||||
#include "flecs/flecs_meta.h"
|
||||
#include "librg.h"
|
||||
#include "world/world.h"
|
||||
|
||||
|
@ -16,8 +15,7 @@ uint64_t entity_spawn(uint16_t class_id) {
|
|||
|
||||
if (class_id != EKIND_SERVER) {
|
||||
ecs_set(world_ecs(), e, Velocity, {0});
|
||||
ecs_add(world_ecs(), e, Walking);
|
||||
Position *pos = ecs_get_mut(world_ecs(), e, Position, NULL);
|
||||
Position *pos = ecs_get_mut(world_ecs(), e, Position);
|
||||
#if 1
|
||||
pos->x=(float)(rand() % world_dim());
|
||||
pos->y=(float)(rand() % world_dim());
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
#include "assets.h"
|
||||
#include "items.h"
|
||||
|
||||
#include "modules/components.h"
|
||||
|
||||
#define ZPL_PICO
|
||||
#include "zpl.h"
|
||||
|
||||
|
|
|
@ -11,9 +11,6 @@
|
|||
#include "camera.h"
|
||||
#include "profiler.h"
|
||||
|
||||
#include "flecs/flecs.h"
|
||||
//#include "flecs/flecs_dash.h"
|
||||
//#include "flecs/flecs_systems_civetweb.h"
|
||||
#include "flecs/flecs_os_api_stdcpp.h"
|
||||
|
||||
#include "modules/components.h"
|
||||
|
@ -117,12 +114,7 @@ size_t game_world_view_count(void) {
|
|||
}
|
||||
|
||||
void flecs_dash_init() {
|
||||
#if 0
|
||||
ECS_IMPORT(world_ecs(), FlecsDash);
|
||||
ECS_IMPORT(world_ecs(), FlecsSystemsCivetweb);
|
||||
|
||||
ecs_set(world_ecs(), 0, EcsDashServer, {.port = 27001});
|
||||
#endif
|
||||
ecs_singleton_set(world_ecs(), EcsRest, {0});
|
||||
}
|
||||
|
||||
float game_time() {
|
||||
|
|
|
@ -27,7 +27,7 @@ static inline asset_id item_fix_kind(asset_id id) {
|
|||
uint64_t item_spawn(asset_id kind, uint32_t qty) {
|
||||
ecs_entity_t e = entity_spawn(EKIND_ITEM);
|
||||
|
||||
ItemDrop *d = ecs_get_mut(world_ecs(), e, ItemDrop, NULL);
|
||||
ItemDrop *d = ecs_get_mut(world_ecs(), e, ItemDrop);
|
||||
*d = (ItemDrop){
|
||||
.kind = item_fix_kind(kind),
|
||||
.quantity = qty,
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
#include "profiler.h"
|
||||
|
||||
#include "flecs/flecs.h"
|
||||
#include "flecs/flecs_dash.h"
|
||||
#include "flecs/flecs_systems_civetweb.h"
|
||||
#include "flecs/flecs_os_api_stdcpp.h"
|
||||
|
||||
#include "modules/components.h"
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include "game.h"
|
||||
#include "player.h"
|
||||
|
||||
#include "modules/components.h"
|
||||
|
||||
#define NETWORK_UPDATE_DELAY 0.100
|
||||
|
||||
static ENetHost *host = NULL;
|
||||
|
@ -218,10 +220,10 @@ int32_t network_server_tick(void) {
|
|||
}
|
||||
|
||||
void network_server_despawn_viewers(void *peer_id) {
|
||||
ecs_iter_t it = ecs_query_iter(world_ecs_clientinfo());
|
||||
ecs_iter_t it = ecs_query_iter(world_ecs(), world_ecs_clientinfo());
|
||||
|
||||
while (ecs_query_next(&it)) {
|
||||
ClientInfo *p = ecs_column(&it, ClientInfo, 1);
|
||||
ClientInfo *p = ecs_field(&it, ClientInfo, 1);
|
||||
|
||||
for (int i = 0; i < it.count; i++) {
|
||||
if (p[i].peer == (uintptr_t)peer_id) {
|
||||
|
@ -232,10 +234,10 @@ void network_server_despawn_viewers(void *peer_id) {
|
|||
}
|
||||
|
||||
uint64_t network_server_get_entity(void *peer_id, uint16_t view_id) {
|
||||
ecs_iter_t it = ecs_query_iter(world_ecs_clientinfo());
|
||||
ecs_iter_t it = ecs_query_iter(world_ecs(), world_ecs_clientinfo());
|
||||
|
||||
while (ecs_query_next(&it)) {
|
||||
ClientInfo *p = ecs_column(&it, ClientInfo, 1);
|
||||
ClientInfo *p = ecs_field(&it, ClientInfo, 1);
|
||||
|
||||
for (int i = 0; i < it.count; i++) {
|
||||
if (p[i].peer == (uintptr_t)peer_id && p[i].view_id == view_id) {
|
||||
|
|
|
@ -28,7 +28,7 @@ int32_t pkt_00_init_handler(pkt_header *header) {
|
|||
uint64_t peer_id = (uint64_t)header->udata;
|
||||
uint64_t ent_id = player_spawn(NULL);
|
||||
|
||||
Position *pos = ecs_get_mut(world_ecs(), ent_id, Position, NULL);
|
||||
Position *pos = ecs_get_mut(world_ecs(), ent_id, Position);
|
||||
|
||||
#if 0
|
||||
pos->x = world_dim()/2.0f + rand()%15*15.0f;
|
||||
|
|
|
@ -38,7 +38,7 @@ int32_t pkt_send_keystate_handler(pkt_header *header) {
|
|||
if (!world_entity_valid(e))
|
||||
return 1;
|
||||
|
||||
Input *i = ecs_get_mut(world_ecs(), e, Input, NULL);
|
||||
Input *i = ecs_get_mut(world_ecs(), e, Input);
|
||||
if (i && !i->is_blocked) {
|
||||
i->x = zpl_clamp(table.x, -1.0f, 1.0f);
|
||||
i->y = zpl_clamp(table.y, -1.0f, 1.0f);
|
||||
|
|
|
@ -30,10 +30,10 @@ int32_t pkt_switch_viewer_handler(pkt_header *header) {
|
|||
if (!world_entity_valid(e))
|
||||
return 1;
|
||||
|
||||
ecs_iter_t it = ecs_query_iter(world_ecs_clientinfo());
|
||||
ecs_iter_t it = ecs_query_iter(world_ecs(), world_ecs_clientinfo());
|
||||
|
||||
while (ecs_query_next(&it)) {
|
||||
ClientInfo *p = ecs_column(&it, ClientInfo, 1);
|
||||
ClientInfo *p = ecs_field(&it, ClientInfo, 1);
|
||||
|
||||
for (int i = 0; i < it.count; i++) {
|
||||
if (p[i].peer == (uintptr_t)peer_id && p[i].view_id == table.view_id) {
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#include "entity.h"
|
||||
#include "entity_view.h"
|
||||
#include "flecs/flecs.h"
|
||||
#include "flecs/flecs_meta.h"
|
||||
#include "librg.h"
|
||||
#include "world/world.h"
|
||||
|
||||
|
@ -24,7 +23,6 @@ uint64_t player_spawn(char *name) {
|
|||
ecs_set(world_ecs(), e, Input, {0});
|
||||
ecs_set(world_ecs(), e, Inventory, {0});
|
||||
ecs_set(world_ecs(), e, Health, {.hp = PLAYER_MAX_HP, .max_hp = PLAYER_MAX_HP});
|
||||
ecs_add(world_ecs(), e, Player);
|
||||
|
||||
librg_entity_owner_set(world_tracker(), e, (int64_t)e);
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
uint64_t vehicle_spawn(void) {
|
||||
ecs_entity_t e = entity_spawn(EKIND_VEHICLE);
|
||||
|
||||
Vehicle *veh = ecs_get_mut(world_ecs(), e, Vehicle, NULL);
|
||||
Vehicle *veh = ecs_get_mut(world_ecs(), e, Vehicle);
|
||||
*veh = (Vehicle){
|
||||
.wheel_base = 50.0f,
|
||||
.speed = 50.0f,
|
||||
|
|
|
@ -147,7 +147,7 @@ void world_chunk_setup_grid(void) {
|
|||
for (int i = 0; i < zpl_square(world.chunk_amount); ++i) {
|
||||
ecs_entity_t e = ecs_new(world.ecs, 0);
|
||||
ecs_set(world.ecs, e, Classify, {.id = EKIND_CHUNK });
|
||||
Chunk *chunk = ecs_get_mut(world.ecs, e, Chunk, NULL);
|
||||
Chunk *chunk = ecs_get_mut(world.ecs, e, Chunk);
|
||||
librg_entity_track(world.tracker, e);
|
||||
librg_entity_chunk_set(world.tracker, e, i);
|
||||
librg_chunk_to_chunkpos(world.tracker, i, &chunk->x, &chunk->y, NULL);
|
||||
|
@ -280,12 +280,12 @@ static void world_tracker_update(uint8_t ticker, float freq, uint8_t radius) {
|
|||
world.tracker_update[ticker] = (float)zpl_time_rel() + freq;
|
||||
|
||||
profile(PROF_WORLD_WRITE) {
|
||||
ecs_iter_t it = ecs_query_iter(world.ecs_update);
|
||||
ecs_iter_t it = ecs_query_iter(world_ecs(), world.ecs_update);
|
||||
static char buffer[WORLD_LIBRG_BUFSIZ] = {0};
|
||||
world.active_layer_id = ticker;
|
||||
|
||||
while (ecs_query_next(&it)) {
|
||||
ClientInfo *p = ecs_column(&it, ClientInfo, 1);
|
||||
ClientInfo *p = ecs_field(&it, ClientInfo, 1);
|
||||
|
||||
for (int i = 0; i < it.count; i++) {
|
||||
size_t datalen = WORLD_LIBRG_BUFSIZ;
|
||||
|
@ -468,7 +468,7 @@ void world_chunk_destroy_block(float x, float y, bool drop_item) {
|
|||
if (item_find(item_asset) == ASSET_INVALID) return;
|
||||
uint64_t e = item_spawn(item_asset, 1);
|
||||
|
||||
Position *dest = ecs_get_mut(world_ecs(), e, Position, NULL);
|
||||
Position *dest = ecs_get_mut(world_ecs(), e, Position);
|
||||
dest->x = x;
|
||||
dest->y = y;
|
||||
}
|
||||
|
@ -525,15 +525,13 @@ block_id *world_chunk_get_blocks(int64_t id) {
|
|||
|
||||
void world_chunk_mark_dirty(ecs_entity_t e) {
|
||||
bool was_added=false;
|
||||
Chunk *chunk = ecs_get_mut(world_ecs(), e, Chunk, &was_added);
|
||||
ZPL_ASSERT(!was_added);
|
||||
Chunk *chunk = ecs_get_mut(world_ecs(), e, Chunk);
|
||||
if (chunk) chunk->is_dirty = true;
|
||||
}
|
||||
|
||||
bool world_chunk_is_dirty(ecs_entity_t e) {
|
||||
bool was_added=false;
|
||||
Chunk *chunk = ecs_get_mut(world_ecs(), e, Chunk, &was_added);
|
||||
ZPL_ASSERT(!was_added);
|
||||
Chunk *chunk = ecs_get_mut(world_ecs(), e, Chunk);
|
||||
if (chunk) return chunk->is_dirty;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -3,9 +3,7 @@
|
|||
#include "librg.h"
|
||||
#include "packet.h"
|
||||
#include "flecs/flecs.h"
|
||||
#include "flecs/flecs_meta.h"
|
||||
#include "world/blocks.h"
|
||||
#include "modules/components.h"
|
||||
|
||||
#define WORLD_ERROR_NONE +0x0000
|
||||
#define WORLD_ERROR_OUTOFMEM -0x0001
|
||||
|
|
|
@ -212,7 +212,7 @@ int32_t worldgen_test(world_data *wld) {
|
|||
for (int i=0; i<RAND_RANGE(258, 1124); i++) {
|
||||
uint64_t e = vehicle_spawn();
|
||||
|
||||
Position *dest = ecs_get_mut(world_ecs(), e, Position, NULL);
|
||||
Position *dest = ecs_get_mut(world_ecs(), e, Position);
|
||||
dest->x = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE);
|
||||
dest->y = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE);
|
||||
}
|
||||
|
@ -223,7 +223,7 @@ int32_t worldgen_test(world_data *wld) {
|
|||
for (int i=0; i<RAND_RANGE(328, 164); i++) {
|
||||
uint64_t e = item_spawn(ASSET_DEMO_ICEMAKER, 32);
|
||||
|
||||
Position *dest = ecs_get_mut(world_ecs(), e, Position, NULL);
|
||||
Position *dest = ecs_get_mut(world_ecs(), e, Position);
|
||||
dest->x = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE);
|
||||
dest->y = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE);
|
||||
}
|
||||
|
@ -231,7 +231,7 @@ int32_t worldgen_test(world_data *wld) {
|
|||
for (int i=0; i<RAND_RANGE(328, 164); i++) {
|
||||
uint64_t e = item_spawn(ASSET_FENCE, 64);
|
||||
|
||||
Position *dest = ecs_get_mut(world_ecs(), e, Position, NULL);
|
||||
Position *dest = ecs_get_mut(world_ecs(), e, Position);
|
||||
dest->x = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE);
|
||||
dest->y = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE);
|
||||
}
|
||||
|
@ -239,7 +239,7 @@ int32_t worldgen_test(world_data *wld) {
|
|||
for (int i=0; i<RAND_RANGE(328, 164); i++) {
|
||||
uint64_t e = item_spawn(ASSET_WOOD, 64);
|
||||
|
||||
Position *dest = ecs_get_mut(world_ecs(), e, Position, NULL);
|
||||
Position *dest = ecs_get_mut(world_ecs(), e, Position);
|
||||
dest->x = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE);
|
||||
dest->y = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE);
|
||||
}
|
||||
|
@ -247,7 +247,7 @@ int32_t worldgen_test(world_data *wld) {
|
|||
for (int i=0; i<RAND_RANGE(128, 564); i++) {
|
||||
uint64_t e = item_spawn(ASSET_BELT, 999);
|
||||
|
||||
Position *dest = ecs_get_mut(world_ecs(), e, Position, NULL);
|
||||
Position *dest = ecs_get_mut(world_ecs(), e, Position);
|
||||
dest->x = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE);
|
||||
dest->y = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include "world/world.h"
|
||||
#include "game.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
int32_t tracker_read_remove(librg_world *w, librg_event *e) {
|
||||
int64_t entity_id = librg_event_entity_get(w, e);
|
||||
world_view *view = (world_view*)librg_world_userdata_get(w);
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#include "modules/components.h"
|
||||
|
||||
ECS_COMPONENT_DECLARE(Chunk);
|
||||
ECS_COMPONENT_DECLARE(Position);
|
||||
ECS_COMPONENT_DECLARE(Vector2D);
|
||||
ECS_COMPONENT_DECLARE(Position);
|
||||
ECS_COMPONENT_DECLARE(Velocity);
|
||||
ECS_COMPONENT_DECLARE(Chunk);
|
||||
ECS_COMPONENT_DECLARE(Drawable);
|
||||
ECS_COMPONENT_DECLARE(Input);
|
||||
ECS_COMPONENT_DECLARE(Velocity);
|
||||
ECS_COMPONENT_DECLARE(ClientInfo);
|
||||
ECS_COMPONENT_DECLARE(Health);
|
||||
ECS_COMPONENT_DECLARE(Classify);
|
||||
|
@ -13,59 +13,23 @@ ECS_COMPONENT_DECLARE(Vehicle);
|
|||
ECS_COMPONENT_DECLARE(IsInVehicle);
|
||||
ECS_COMPONENT_DECLARE(ItemDrop);
|
||||
ECS_COMPONENT_DECLARE(Inventory);
|
||||
ECS_TAG_DECLARE(EcsActor);
|
||||
ECS_TAG_DECLARE(EcsDemoNPC);
|
||||
ECS_TYPE_DECLARE(Player);
|
||||
ECS_TYPE_DECLARE(Movement);
|
||||
ECS_TYPE_DECLARE(Walking);
|
||||
ECS_TYPE_DECLARE(Flying);
|
||||
// NOTE(zaklaus): @1 DECLARE
|
||||
ECS_COMPONENT_DECLARE(DemoNPC);
|
||||
|
||||
void ComponentsImport(ecs_world_t *ecs) {
|
||||
ECS_MODULE(ecs, Components);
|
||||
ECS_IMPORT(ecs, FlecsMeta);
|
||||
|
||||
ECS_META_DEFINE(ecs, Position);
|
||||
ECS_META_DEFINE(ecs, Chunk);
|
||||
ECS_META_DEFINE(ecs, Vector2D);
|
||||
ECS_META_DEFINE(ecs, Drawable);
|
||||
ECS_META_DEFINE(ecs, ClientInfo);
|
||||
ECS_META_DEFINE(ecs, Velocity);
|
||||
ECS_META_DEFINE(ecs, Input);
|
||||
ECS_META_DEFINE(ecs, Health);
|
||||
ECS_META_DEFINE(ecs, Classify);
|
||||
ECS_META_DEFINE(ecs, Vehicle);
|
||||
|
||||
ECS_COMPONENT_DEFINE(ecs, Vector2D);
|
||||
ECS_COMPONENT_DEFINE(ecs, Position);
|
||||
ECS_COMPONENT_DEFINE(ecs, Velocity);
|
||||
ECS_COMPONENT_DEFINE(ecs, Chunk);
|
||||
ECS_COMPONENT_DEFINE(ecs, Drawable);
|
||||
ECS_COMPONENT_DEFINE(ecs, Input);
|
||||
ECS_COMPONENT_DEFINE(ecs, ClientInfo);
|
||||
ECS_COMPONENT_DEFINE(ecs, Health);
|
||||
ECS_COMPONENT_DEFINE(ecs, Classify);
|
||||
ECS_COMPONENT_DEFINE(ecs, Vehicle);
|
||||
ECS_COMPONENT_DEFINE(ecs, IsInVehicle);
|
||||
ECS_COMPONENT_DEFINE(ecs, ItemDrop);
|
||||
ECS_COMPONENT_DEFINE(ecs, Inventory);
|
||||
|
||||
ECS_TAG_DEFINE(ecs, Walking);
|
||||
ECS_TAG_DEFINE(ecs, Flying);
|
||||
|
||||
ECS_TAG_DEFINE(ecs, EcsActor);
|
||||
ECS_TAG_DEFINE(ecs, EcsDemoNPC);
|
||||
|
||||
ECS_PREFAB(ecs, Base, Position, Velocity, Input, EcsActor);
|
||||
ECS_TYPE_DEFINE(ecs, Movement, Walking, Flying);
|
||||
|
||||
ECS_SET_COMPONENT(Chunk);
|
||||
ECS_SET_COMPONENT(Vector2D);
|
||||
ECS_SET_COMPONENT(Position);
|
||||
ECS_SET_COMPONENT(Drawable);
|
||||
ECS_SET_COMPONENT(Velocity);
|
||||
ECS_SET_COMPONENT(ClientInfo);
|
||||
ECS_SET_COMPONENT(Input);
|
||||
ECS_SET_COMPONENT(Health);
|
||||
ECS_SET_COMPONENT(Classify);
|
||||
ECS_SET_COMPONENT(Vehicle);
|
||||
ECS_SET_COMPONENT(IsInVehicle);
|
||||
ECS_SET_COMPONENT(ItemDrop);
|
||||
ECS_SET_COMPONENT(Inventory);
|
||||
ECS_SET_ENTITY(Walking);
|
||||
ECS_SET_ENTITY(Flying);
|
||||
ECS_SET_ENTITY(EcsActor);
|
||||
ECS_SET_ENTITY(EcsDemoNPC);
|
||||
ECS_SET_TYPE(Movement);
|
||||
// NOTE(zaklaus): @2 SET
|
||||
ECS_COMPONENT_DEFINE(ecs, DemoNPC);
|
||||
}
|
||||
|
|
|
@ -1,94 +1,85 @@
|
|||
#pragma once
|
||||
#include "flecs/flecs.h"
|
||||
#include "flecs/flecs_meta.h"
|
||||
|
||||
//NOTE(zaklaus): custom macro to define meta components outside the current scope
|
||||
|
||||
#ifndef ECS_META_DEFINE
|
||||
#define ECS_META_DEFINE(world, T)\
|
||||
ECS_COMPONENT_DEFINE(world, T);\
|
||||
ecs_new_meta(world, ecs_entity(T), &__##T##__);
|
||||
#endif
|
||||
|
||||
#ifndef ecs_get_mut_if
|
||||
#define ecs_get_mut_if(world, entity, component)\
|
||||
(ecs_get(world, entity, component) ? ecs_get_mut(world, entity, component, NULL) : NULL)
|
||||
(ecs_get(world, entity, component) ? ecs_get_mut(world, entity, component) : NULL)
|
||||
#endif
|
||||
|
||||
#define ITEMS_INVENTORY_SIZE 9
|
||||
|
||||
ECS_STRUCT(Vector2D, {
|
||||
float x;
|
||||
float y;
|
||||
});
|
||||
typedef struct {
|
||||
float x;
|
||||
float y;
|
||||
} Vector2D;
|
||||
|
||||
ECS_STRUCT(Chunk, {
|
||||
uint32_t id;
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
uint8_t is_dirty;
|
||||
});
|
||||
typedef struct {
|
||||
uint32_t id;
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
uint8_t is_dirty;
|
||||
} Chunk;
|
||||
|
||||
ECS_STRUCT(Drawable, {
|
||||
uint16_t id;
|
||||
});
|
||||
typedef struct {
|
||||
uint16_t id;
|
||||
} Drawable;
|
||||
|
||||
ECS_ALIAS(Vector2D, Position);
|
||||
ECS_ALIAS(Vector2D, Velocity);
|
||||
typedef Vector2D Position;
|
||||
typedef Vector2D Velocity;
|
||||
|
||||
ECS_STRUCT(Input, {
|
||||
float x;
|
||||
float y;
|
||||
float mx;
|
||||
float my;
|
||||
uint8_t use;
|
||||
uint8_t sprint;
|
||||
uint8_t ctrl;
|
||||
uint8_t is_blocked;
|
||||
typedef struct {
|
||||
float x;
|
||||
float y;
|
||||
float mx;
|
||||
float my;
|
||||
uint8_t use;
|
||||
uint8_t sprint;
|
||||
uint8_t ctrl;
|
||||
uint8_t is_blocked;
|
||||
|
||||
// NOTE(zaklaus): inventory
|
||||
uint8_t selected_item;
|
||||
uint8_t drop;
|
||||
uint8_t swap;
|
||||
uint8_t swap_from;
|
||||
uint8_t swap_to;
|
||||
// NOTE(zaklaus): inventory
|
||||
uint8_t selected_item;
|
||||
uint8_t drop;
|
||||
uint8_t swap;
|
||||
uint8_t swap_from;
|
||||
uint8_t swap_to;
|
||||
|
||||
// NOTE(zaklaus): build mode
|
||||
uint8_t num_placements;
|
||||
float placements_x[20];
|
||||
float placements_y[20];
|
||||
});
|
||||
// NOTE(zaklaus): build mode
|
||||
uint8_t num_placements;
|
||||
float placements_x[20];
|
||||
float placements_y[20];
|
||||
} Input;
|
||||
|
||||
ECS_STRUCT(ClientInfo, {
|
||||
uintptr_t peer;
|
||||
uint16_t view_id;
|
||||
uint8_t active;
|
||||
});
|
||||
typedef struct {
|
||||
uintptr_t peer;
|
||||
uint16_t view_id;
|
||||
uint8_t active;
|
||||
} ClientInfo;
|
||||
|
||||
ECS_STRUCT(Health, {
|
||||
float hp;
|
||||
float max_hp;
|
||||
typedef struct {
|
||||
float hp;
|
||||
float max_hp;
|
||||
|
||||
//NOTE(zaklaus): Intentionally global, to allow for creative use of damage combos
|
||||
float pain_time;
|
||||
float heal_time;
|
||||
});
|
||||
//NOTE(zaklaus): Intentionally global, to allow for creative use of damage combos
|
||||
float pain_time;
|
||||
float heal_time;
|
||||
} Health;
|
||||
|
||||
ECS_STRUCT(Classify, {
|
||||
uint16_t id;
|
||||
});
|
||||
typedef struct {
|
||||
uint16_t id;
|
||||
} Classify;
|
||||
|
||||
ECS_STRUCT(Vehicle, {
|
||||
uint64_t seats[4];
|
||||
typedef struct {
|
||||
uint64_t seats[4];
|
||||
|
||||
float force;
|
||||
float heading;
|
||||
float steer;
|
||||
float wheel_base;
|
||||
float force;
|
||||
float heading;
|
||||
float steer;
|
||||
float wheel_base;
|
||||
|
||||
float speed;
|
||||
float reverse_speed;
|
||||
});
|
||||
float speed;
|
||||
float reverse_speed;
|
||||
} Vehicle;
|
||||
|
||||
typedef struct {
|
||||
ecs_entity_t veh;
|
||||
|
@ -105,73 +96,21 @@ typedef struct {
|
|||
float pickup_time;
|
||||
} Inventory;
|
||||
|
||||
ECS_COMPONENT_EXTERN(Chunk);
|
||||
ECS_COMPONENT_EXTERN(Position);
|
||||
ECS_COMPONENT_EXTERN(Vector2D);
|
||||
ECS_COMPONENT_EXTERN(Drawable);
|
||||
ECS_COMPONENT_EXTERN(Input);
|
||||
ECS_COMPONENT_EXTERN(Velocity);
|
||||
ECS_COMPONENT_EXTERN(ClientInfo);
|
||||
ECS_COMPONENT_EXTERN(Health);
|
||||
ECS_COMPONENT_EXTERN(Classify);
|
||||
ECS_COMPONENT_EXTERN(Vehicle);
|
||||
ECS_COMPONENT_EXTERN(IsInVehicle);
|
||||
ECS_COMPONENT_EXTERN(ItemDrop);
|
||||
ECS_COMPONENT_EXTERN(Inventory);
|
||||
ECS_TAG_EXTERN(EcsActor);
|
||||
ECS_TAG_EXTERN(EcsDemoNPC);
|
||||
ECS_TYPE_EXTERN(Player);
|
||||
ECS_TYPE_EXTERN(Movement);
|
||||
ECS_TYPE_EXTERN(Walking);
|
||||
ECS_TYPE_EXTERN(Flying);
|
||||
ECS_TYPE_EXTERN(EcsClient);
|
||||
// NOTE(zaklaus): @1 EXTERN
|
||||
typedef struct {char _unused;} DemoNPC;
|
||||
|
||||
typedef struct {
|
||||
ECS_DECLARE_COMPONENT(Chunk);
|
||||
ECS_DECLARE_COMPONENT(Position);
|
||||
ECS_DECLARE_COMPONENT(Vector2D);
|
||||
ECS_DECLARE_COMPONENT(Drawable);
|
||||
ECS_DECLARE_COMPONENT(Input);
|
||||
ECS_DECLARE_COMPONENT(Velocity);
|
||||
ECS_DECLARE_COMPONENT(ClientInfo);
|
||||
ECS_DECLARE_COMPONENT(Health);
|
||||
ECS_DECLARE_COMPONENT(Classify);
|
||||
ECS_DECLARE_COMPONENT(Vehicle);
|
||||
ECS_DECLARE_COMPONENT(IsInVehicle);
|
||||
ECS_DECLARE_COMPONENT(ItemDrop);
|
||||
ECS_DECLARE_COMPONENT(Inventory);
|
||||
ECS_DECLARE_ENTITY(EcsActor);
|
||||
ECS_DECLARE_ENTITY(EcsDemoNPC);
|
||||
ECS_DECLARE_TYPE(Player);
|
||||
ECS_DECLARE_TYPE(Builder);
|
||||
ECS_DECLARE_TYPE(Movement);
|
||||
ECS_DECLARE_ENTITY(Walking);
|
||||
ECS_DECLARE_ENTITY(Flying);
|
||||
// NOTE(zaklaus): @2 DECLARE
|
||||
} Components;
|
||||
|
||||
#define ComponentsImportHandles(handles)\
|
||||
ECS_IMPORT_COMPONENT(handles, Chunk);\
|
||||
ECS_IMPORT_COMPONENT(handles, Vector2D);\
|
||||
ECS_IMPORT_COMPONENT(handles, Position);\
|
||||
ECS_IMPORT_COMPONENT(handles, Drawable);\
|
||||
ECS_IMPORT_COMPONENT(handles, Input);\
|
||||
ECS_IMPORT_COMPONENT(handles, Velocity);\
|
||||
ECS_IMPORT_COMPONENT(handles, ClientInfo);\
|
||||
ECS_IMPORT_COMPONENT(handles, Health);\
|
||||
ECS_IMPORT_COMPONENT(handles, Classify);\
|
||||
ECS_IMPORT_COMPONENT(handles, Vehicle);\
|
||||
ECS_IMPORT_COMPONENT(handles, IsInVehicle);\
|
||||
ECS_IMPORT_COMPONENT(handles, ItemDrop);\
|
||||
ECS_IMPORT_COMPONENT(handles, Inventory);\
|
||||
ECS_IMPORT_TYPE(handles, Player);\
|
||||
ECS_IMPORT_TYPE(handles, Builder);\
|
||||
ECS_IMPORT_TYPE(handles, Movement);\
|
||||
ECS_IMPORT_ENTITY(handles, EcsActor);\
|
||||
ECS_IMPORT_ENTITY(handles, EcsDemoNPC);\
|
||||
ECS_IMPORT_ENTITY(handles, Walking);\
|
||||
ECS_IMPORT_ENTITY(handles, Flying);\
|
||||
// NOTE(zaklaus): @3 IMPORT
|
||||
extern ECS_COMPONENT_DECLARE(Vector2D);
|
||||
extern ECS_COMPONENT_DECLARE(Position);
|
||||
extern ECS_COMPONENT_DECLARE(Velocity);
|
||||
extern ECS_COMPONENT_DECLARE(Chunk);
|
||||
extern ECS_COMPONENT_DECLARE(Drawable);
|
||||
extern ECS_COMPONENT_DECLARE(Input);
|
||||
extern ECS_COMPONENT_DECLARE(ClientInfo);
|
||||
extern ECS_COMPONENT_DECLARE(Health);
|
||||
extern ECS_COMPONENT_DECLARE(Classify);
|
||||
extern ECS_COMPONENT_DECLARE(Vehicle);
|
||||
extern ECS_COMPONENT_DECLARE(IsInVehicle);
|
||||
extern ECS_COMPONENT_DECLARE(ItemDrop);
|
||||
extern ECS_COMPONENT_DECLARE(Inventory);
|
||||
extern ECS_COMPONENT_DECLARE(DemoNPC);
|
||||
|
||||
void ComponentsImport(ecs_world_t *ecs);
|
||||
|
|
|
@ -23,8 +23,8 @@ static inline float physics_correction(float x, float vx, float bounce) {
|
|||
|
||||
void IntegratePositions(ecs_iter_t *it) {
|
||||
profile(PROF_INTEGRATE_POS) {
|
||||
Position *p = ecs_column(it, Position, 1);
|
||||
Velocity *v = ecs_column(it, Velocity, 2);
|
||||
Position *p = ecs_field(it, Position, 1);
|
||||
Velocity *v = ecs_field(it, Velocity, 2);
|
||||
|
||||
for (int i = 0; i < it->count; i++) {
|
||||
// NOTE(zaklaus): world bounds
|
||||
|
@ -69,7 +69,7 @@ void IntegratePositions(ecs_iter_t *it) {
|
|||
}
|
||||
|
||||
void UpdateTrackerPos(ecs_iter_t *it) {
|
||||
Position *p = ecs_column(it, Position, 1);
|
||||
Position *p = ecs_field(it, Position, 1);
|
||||
|
||||
for (int i = 0; i < it->count; i++){
|
||||
librg_entity_chunk_set(world_tracker(), it->entities[i], librg_chunk_from_realpos(world_tracker(), p[i].x, p[i].y, 0));
|
||||
|
@ -86,8 +86,8 @@ void UpdateTrackerPos(ecs_iter_t *it) {
|
|||
#define HAZARD_BLOCK_DMG 5.0f
|
||||
|
||||
void HurtOnHazardBlock(ecs_iter_t *it) {
|
||||
Position *p = ecs_column(it, Position, 1);
|
||||
Health *h = ecs_column(it, Health, 2);
|
||||
Position *p = ecs_field(it, Position, 1);
|
||||
Health *h = ecs_field(it, Health, 2);
|
||||
|
||||
for (int i = 0; i < it->count; i++) {
|
||||
world_block_lookup l = world_block_from_realpos(p[i].x, p[i].y);
|
||||
|
@ -106,7 +106,7 @@ void HurtOnHazardBlock(ecs_iter_t *it) {
|
|||
#define HP_REGEN_RECOVERY 15.0f
|
||||
|
||||
void RegenerateHP(ecs_iter_t *it) {
|
||||
Health *h = ecs_column(it, Health, 1);
|
||||
Health *h = ecs_field(it, Health, 1);
|
||||
|
||||
for (int i = 0; i < it->count; i++) {
|
||||
if (h[i].pain_time < 0.0f) {
|
||||
|
@ -124,7 +124,7 @@ void RegenerateHP(ecs_iter_t *it) {
|
|||
}
|
||||
|
||||
void ResetActivators(ecs_iter_t *it) {
|
||||
Input *in = ecs_column(it, Input, 1);
|
||||
Input *in = ecs_field(it, Input, 1);
|
||||
|
||||
for (int i = 0; i < it->count; i++) {
|
||||
in[i].use = false;
|
||||
|
@ -135,8 +135,8 @@ void ResetActivators(ecs_iter_t *it) {
|
|||
}
|
||||
|
||||
void ApplyWorldDragOnVelocity(ecs_iter_t *it) {
|
||||
Position *p = ecs_column(it, Position, 1);
|
||||
Velocity *v = ecs_column(it, Velocity, 2);
|
||||
Position *p = ecs_field(it, Position, 1);
|
||||
Velocity *v = ecs_field(it, Velocity, 2);
|
||||
|
||||
for (int i = 0; i < it->count; i++) {
|
||||
world_block_lookup lookup = world_block_from_realpos(p[i].x, p[i].y);
|
||||
|
@ -163,7 +163,7 @@ void SystemsImport(ecs_world_t *ecs) {
|
|||
|
||||
ECS_SYSTEM(ecs, EnableWorldEdit, EcsOnLoad);
|
||||
ECS_SYSTEM(ecs, MovementImpulse, EcsOnLoad, components.Input, components.Velocity, components.Position, !components.IsInVehicle);
|
||||
ECS_SYSTEM(ecs, DemoNPCMoveAround, EcsOnLoad, components.Velocity, components.EcsDemoNPC);
|
||||
ECS_SYSTEM(ecs, DemoNPCMoveAround, EcsOnLoad, components.Velocity, components.DemoNPC);
|
||||
|
||||
ECS_SYSTEM(ecs, ApplyWorldDragOnVelocity, EcsOnUpdate, components.Position, components.Velocity);
|
||||
ECS_SYSTEM(ecs, HurtOnHazardBlock, EcsOnUpdate, components.Position, components.Health);
|
||||
|
|
|
@ -5,11 +5,4 @@ static inline float safe_dt(ecs_iter_t *it) {
|
|||
return zpl_min(it->delta_time, 0.03334f);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
// NOTE(zaklaus): Public systems are exposed here
|
||||
int32_t _unused;
|
||||
} Systems;
|
||||
|
||||
#define SystemsImportHandles(handles) (void)(handles)
|
||||
|
||||
void SystemsImport(ecs_world_t *ecs);
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
#define DEMO_NPC_MOVE_SPEED 500
|
||||
#define DEMO_NPC_STEER_SPEED 300
|
||||
|
||||
#include <math.h>
|
||||
|
||||
void DemoNPCMoveAround(ecs_iter_t *it) {
|
||||
Velocity *v = ecs_column(it, Velocity, 1);
|
||||
Velocity *v = ecs_field(it, Velocity, 1);
|
||||
for (int i = 0; i < it->count; i++) {
|
||||
float d = zpl_quake_rsqrt(v[i].x*v[i].x + v[i].y*v[i].y);
|
||||
v[i].x += (v[i].x*d*DEMO_NPC_MOVE_SPEED*safe_dt(it) + zpl_cos(zpl_to_radians((float)(rand()%360)))*DEMO_NPC_STEER_SPEED*safe_dt(it));
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
#define ITEM_ATTRACT_FORCE 0.63f
|
||||
|
||||
void PickItem(ecs_iter_t *it) {
|
||||
Position *p = ecs_column(it, Position, 2);
|
||||
Inventory *inv = ecs_column(it, Inventory, 3);
|
||||
Position *p = ecs_field(it, Position, 2);
|
||||
Inventory *inv = ecs_field(it, Inventory, 3);
|
||||
|
||||
for (int i = 0; i < it->count; i++) {
|
||||
if (inv[i].pickup_time > game_time()) continue;
|
||||
|
@ -17,7 +17,7 @@ void PickItem(ecs_iter_t *it) {
|
|||
for (size_t j = 0; j < ents_count; j++) {
|
||||
ItemDrop *drop = 0;
|
||||
if ((drop = ecs_get_mut_if(it->world, ents[j], ItemDrop))) {
|
||||
Position *p2 = ecs_get_mut(it->world, ents[j], Position, NULL);
|
||||
Position *p2 = ecs_get_mut(it->world, ents[j], Position);
|
||||
|
||||
float dx = p2->x - p[i].x;
|
||||
float dy = p2->y - p[i].y;
|
||||
|
@ -52,9 +52,9 @@ void PickItem(ecs_iter_t *it) {
|
|||
#define ITEM_DROP_MERGER_TIME 6.5f
|
||||
|
||||
void DropItem(ecs_iter_t *it) {
|
||||
Input *in = ecs_column(it, Input, 1);
|
||||
Position *p = ecs_column(it, Position, 2);
|
||||
Inventory *inv = ecs_column(it, Inventory, 3);
|
||||
Input *in = ecs_field(it, Input, 1);
|
||||
Position *p = ecs_field(it, Position, 2);
|
||||
Inventory *inv = ecs_field(it, Inventory, 3);
|
||||
|
||||
for (int i = 0; i < it->count; i++) {
|
||||
if (!in[i].drop) continue;
|
||||
|
@ -77,17 +77,17 @@ void DropItem(ecs_iter_t *it) {
|
|||
ecs_entity_t te = item_spawn(item->kind, dropped_count);
|
||||
item->quantity -= dropped_count;
|
||||
|
||||
ItemDrop *d = ecs_get_mut(world_ecs(), te, ItemDrop, NULL);
|
||||
ItemDrop *d = ecs_get_mut(world_ecs(), te, ItemDrop);
|
||||
*d = (ItemDrop){
|
||||
.kind = item->kind,
|
||||
.quantity = dropped_count,
|
||||
.merger_time = game_time() + ITEM_DROP_MERGER_TIME,
|
||||
};
|
||||
|
||||
Position *ipos = ecs_get_mut(it->world, te, Position, NULL);
|
||||
Position *ipos = ecs_get_mut(it->world, te, Position);
|
||||
*ipos = p[i];
|
||||
|
||||
Velocity *v = ecs_get_mut(it->world, te, Velocity, NULL);
|
||||
Velocity *v = ecs_get_mut(it->world, te, Velocity);
|
||||
v->x = in[i].mx * 800.0f;
|
||||
v->y = in[i].my * 800.0f;
|
||||
|
||||
|
@ -101,8 +101,8 @@ void DropItem(ecs_iter_t *it) {
|
|||
}
|
||||
|
||||
void MergeItems(ecs_iter_t *it) {
|
||||
Position *p = ecs_column(it, Position, 1);
|
||||
ItemDrop *id = ecs_column(it, ItemDrop, 2);
|
||||
Position *p = ecs_field(it, Position, 1);
|
||||
ItemDrop *id = ecs_field(it, ItemDrop, 2);
|
||||
|
||||
for (int i = 0; i < it->count; i += 1) {
|
||||
ItemDrop *item = &id[i];
|
||||
|
@ -135,8 +135,8 @@ void MergeItems(ecs_iter_t *it) {
|
|||
}
|
||||
|
||||
void SwapItems(ecs_iter_t *it) {
|
||||
Input *in = ecs_column(it, Input, 1);
|
||||
Inventory *inv = ecs_column(it, Inventory, 2);
|
||||
Input *in = ecs_field(it, Input, 1);
|
||||
Inventory *inv = ecs_field(it, Inventory, 2);
|
||||
|
||||
for (int i = 0; i < it->count; i++) {
|
||||
if (!in[i].swap) continue;
|
||||
|
@ -183,9 +183,9 @@ void SwapItems(ecs_iter_t *it) {
|
|||
}
|
||||
|
||||
void UseItem(ecs_iter_t *it) {
|
||||
Input *in = ecs_column(it, Input, 1);
|
||||
Position *p = ecs_column(it, Position, 2);
|
||||
Inventory *inv = ecs_column(it, Inventory, 3);
|
||||
Input *in = ecs_field(it, Input, 1);
|
||||
Position *p = ecs_field(it, Position, 2);
|
||||
Inventory *inv = ecs_field(it, Inventory, 3);
|
||||
|
||||
for (int i = 0; i < it->count; i++) {
|
||||
if (!in[i].use && !in[i].num_placements) continue;
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
#define PLR_MOVE_SPEED_MULT 1.5f
|
||||
|
||||
void MovementImpulse(ecs_iter_t *it) {
|
||||
Input *in = ecs_column(it, Input, 1);
|
||||
Velocity *v = ecs_column(it, Velocity, 2);
|
||||
Position *p = ecs_column(it, Position, 3);
|
||||
Input *in = ecs_field(it, Input, 1);
|
||||
Velocity *v = ecs_field(it, Velocity, 2);
|
||||
Position *p = ecs_field(it, Position, 3);
|
||||
|
||||
for (int i = 0; i < it->count; i++) {
|
||||
world_block_lookup lookup = world_block_from_realpos(p[i].x, p[i].y);
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
#define VEH_ENTER_RADIUS 45.0f
|
||||
|
||||
void LeaveVehicle(ecs_iter_t *it) {
|
||||
Input *in = ecs_column(it, Input, 1);
|
||||
IsInVehicle *vehp = ecs_column(it, IsInVehicle, 2);
|
||||
Velocity *v = ecs_column(it, Velocity, 3);
|
||||
Input *in = ecs_field(it, Input, 1);
|
||||
IsInVehicle *vehp = ecs_field(it, IsInVehicle, 2);
|
||||
Velocity *v = ecs_field(it, Velocity, 3);
|
||||
|
||||
for (int i = 0; i < it->count; i++) {
|
||||
if (!in[i].use) continue;
|
||||
|
@ -36,8 +36,8 @@ void LeaveVehicle(ecs_iter_t *it) {
|
|||
}
|
||||
|
||||
void EnterVehicle(ecs_iter_t *it) {
|
||||
Input *in = ecs_column(it, Input, 1);
|
||||
Position *p = ecs_column(it, Position, 2);
|
||||
Input *in = ecs_field(it, Input, 1);
|
||||
Position *p = ecs_field(it, Position, 2);
|
||||
|
||||
for (int i = 0; i < it->count; i++) {
|
||||
if (!in[i].use) continue;
|
||||
|
@ -87,9 +87,9 @@ void EnterVehicle(ecs_iter_t *it) {
|
|||
#define VEHICLE_BRAKE_FORCE 0.84f
|
||||
|
||||
void VehicleHandling(ecs_iter_t *it) {
|
||||
Vehicle *veh = ecs_column(it, Vehicle, 1);
|
||||
Position *p = ecs_column(it, Position, 2);
|
||||
Velocity *v = ecs_column(it, Velocity, 3);
|
||||
Vehicle *veh = ecs_field(it, Vehicle, 1);
|
||||
Position *p = ecs_field(it, Position, 2);
|
||||
Velocity *v = ecs_field(it, Velocity, 3);
|
||||
|
||||
for (int i = 0; i < it->count; i++) {
|
||||
Vehicle *car = &veh[i];
|
||||
|
@ -154,8 +154,8 @@ void VehicleHandling(ecs_iter_t *it) {
|
|||
|
||||
// NOTE(zaklaus): Update passenger position
|
||||
{
|
||||
Position *p2 = ecs_get_mut(it->world, pe, Position, NULL);
|
||||
Velocity *v2 = ecs_get_mut(it->world, pe, Velocity, NULL);
|
||||
Position *p2 = ecs_get_mut(it->world, pe, Position);
|
||||
Velocity *v2 = ecs_get_mut(it->world, pe, Velocity);
|
||||
*p2 = p[i];
|
||||
*v2 = v[i];
|
||||
}
|
||||
|
@ -184,7 +184,7 @@ void VehicleHandling(ecs_iter_t *it) {
|
|||
}
|
||||
|
||||
void ClearVehicle(ecs_iter_t *it) {
|
||||
Vehicle *veh = ecs_column(it, Vehicle, 1);
|
||||
Vehicle *veh = ecs_field(it, Vehicle, 1);
|
||||
|
||||
for (int i = 0; i < it->count; i++) {
|
||||
for (int k = 0; k < 4; k++) {
|
||||
|
|
|
@ -118,7 +118,7 @@ Thanks to the new Flecs sponsors ❤️ :
|
|||
|
||||
## Bugfixes
|
||||
- Fixed issues with subqueries and query rematching
|
||||
- Corrected wrong return type of ecs_column_size (was ecs_entity_t, is now size_t)
|
||||
- Corrected wrong return type of ecs_field_size (was ecs_entity_t, is now size_t)
|
||||
- Add missing \0 when appending to application buffer with strbuf datastructure
|
||||
- Fixed crash when instantiating an empty prefab
|
||||
- Fixed issue with shared tags and queries using each() in the C++ API
|
||||
|
|
|
@ -2,7 +2,6 @@ use_cxx11()
|
|||
|
||||
file(GLOB SRCS *.h
|
||||
flecs.c
|
||||
flecs_meta.c
|
||||
|
||||
flecs-os_api-stdcpp.cpp
|
||||
)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,94 +0,0 @@
|
|||
#ifndef FLECS_COMPONENTS_HTTP_IMPL
|
||||
#include "flecs_components_http.h"
|
||||
#endif
|
||||
|
||||
static
|
||||
void decode(
|
||||
char *str)
|
||||
{
|
||||
char ch, *ptr, *dst = str;
|
||||
|
||||
for (ptr = str; (ch = *ptr); ptr++) {
|
||||
if (ch == '%') {
|
||||
if (ptr[1] == '2' && ptr[2] == '0') {
|
||||
dst[0] = ' ';
|
||||
dst ++;
|
||||
ptr += 2;
|
||||
}
|
||||
} else {
|
||||
dst[0] = ptr[0];
|
||||
dst ++;
|
||||
}
|
||||
}
|
||||
|
||||
dst[0] = '\0';
|
||||
}
|
||||
|
||||
size_t ecs_http_get_query_param(
|
||||
const char *query,
|
||||
const char *name,
|
||||
char *buffer,
|
||||
size_t len)
|
||||
{
|
||||
if (!query) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *cur, *start = query, *value = NULL;
|
||||
char ch;
|
||||
int arg_len = strlen(name);
|
||||
|
||||
for (cur = query; (ch = *cur); cur ++) {
|
||||
if (ch == '=') {
|
||||
if (cur - start >= 256) {
|
||||
/* Ignore, key is too long */
|
||||
} else {
|
||||
int32_t key_len = cur - start;
|
||||
cur ++;
|
||||
value = cur;
|
||||
while ((ch = *cur) && ch != '&') {
|
||||
cur ++;
|
||||
}
|
||||
|
||||
if (!ch || ch == '&') {
|
||||
/* Check if requested key matches */
|
||||
if (arg_len == key_len && !strncmp(name, start, key_len)) {
|
||||
size_t size;
|
||||
if (cur - value < (int32_t)len) {
|
||||
size = cur - value;
|
||||
} else {
|
||||
size = len - 1;
|
||||
}
|
||||
|
||||
memcpy(buffer, value, size);
|
||||
buffer[size] = '\0';
|
||||
|
||||
decode(buffer);
|
||||
|
||||
return cur - value;
|
||||
}
|
||||
}
|
||||
|
||||
start = cur + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FlecsComponentsHttpImport(
|
||||
ecs_world_t *world)
|
||||
{
|
||||
ECS_MODULE(world, FlecsComponentsHttp);
|
||||
|
||||
ECS_IMPORT(world, FlecsMeta);
|
||||
|
||||
ecs_set_name_prefix(world, "EcsHttp");
|
||||
|
||||
ECS_META(world, EcsHttpServer);
|
||||
ECS_META(world, EcsHttpEndpoint);
|
||||
|
||||
ECS_SET_COMPONENT(EcsHttpServer);
|
||||
ECS_SET_COMPONENT(EcsHttpEndpoint);
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
#define flecs_components_http_STATIC
|
||||
#ifndef FLECS_COMPONENTS_HTTP_H
|
||||
#define FLECS_COMPONENTS_HTTP_H
|
||||
|
||||
/*
|
||||
)
|
||||
(.)
|
||||
.|.
|
||||
| |
|
||||
_.--| |--._
|
||||
.-'; ;`-'& ; `&.
|
||||
\ & ; & &_/
|
||||
|"""---...---"""|
|
||||
\ | | | | | | | /
|
||||
`---.|.|.|.---'
|
||||
|
||||
* This file is generated by bake.lang.c for your convenience. Headers of
|
||||
* dependencies will automatically show up in this file. Include bake_config.h
|
||||
* in your main project file. Do not edit! */
|
||||
|
||||
#ifndef FLECS_COMPONENTS_HTTP_BAKE_CONFIG_H
|
||||
#define FLECS_COMPONENTS_HTTP_BAKE_CONFIG_H
|
||||
|
||||
/* Headers of public dependencies */
|
||||
#include <flecs.h>
|
||||
#include <flecs_meta.h>
|
||||
|
||||
/* Convenience macro for exporting symbols */
|
||||
#ifndef flecs_components_http_STATIC
|
||||
#if flecs_components_http_EXPORTS && (defined(_MSC_VER) || defined(__MINGW32__))
|
||||
#define FLECS_COMPONENTS_HTTP_API __declspec(dllexport)
|
||||
#elif flecs_components_http_EXPORTS
|
||||
#define FLECS_COMPONENTS_HTTP_API __attribute__((__visibility__("default")))
|
||||
#elif defined _MSC_VER
|
||||
#define FLECS_COMPONENTS_HTTP_API __declspec(dllimport)
|
||||
#else
|
||||
#define FLECS_COMPONENTS_HTTP_API
|
||||
#endif
|
||||
#else
|
||||
#define FLECS_COMPONENTS_HTTP_API
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
ECS_ENUM(EcsHttpMethod, {
|
||||
EcsHttpGet,
|
||||
EcsHttpPost,
|
||||
EcsHttpPut,
|
||||
EcsHttpDelete,
|
||||
EcsHttpMethodUnknown
|
||||
});
|
||||
|
||||
struct EcsHttpEndpoint;
|
||||
|
||||
typedef struct EcsHttpRequest {
|
||||
const char *url;
|
||||
const char *relative_url;
|
||||
const char *params;
|
||||
void *ctx;
|
||||
EcsHttpMethod method;
|
||||
ecs_entity_t server;
|
||||
} EcsHttpRequest;
|
||||
|
||||
ECS_STRUCT(EcsHttpReply, {
|
||||
char *header;
|
||||
char *body;
|
||||
int status;
|
||||
bool is_file;
|
||||
});
|
||||
|
||||
typedef bool (*EcsHttpServiceAction)(
|
||||
ecs_world_t *world,
|
||||
ecs_entity_t entity,
|
||||
struct EcsHttpEndpoint *endpoint,
|
||||
EcsHttpRequest *request,
|
||||
EcsHttpReply *reply);
|
||||
|
||||
ECS_STRUCT(EcsHttpServer, {
|
||||
uint16_t port;
|
||||
});
|
||||
|
||||
ECS_STRUCT(EcsHttpEndpoint, {
|
||||
char *url;
|
||||
void *ctx;
|
||||
bool synchronous;
|
||||
|
||||
ECS_PRIVATE
|
||||
EcsHttpServiceAction action;
|
||||
});
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct FlecsComponentsHttp {
|
||||
ECS_DECLARE_COMPONENT(EcsHttpServer);
|
||||
ECS_DECLARE_COMPONENT(EcsHttpEndpoint);
|
||||
} FlecsComponentsHttp;
|
||||
|
||||
FLECS_COMPONENTS_HTTP_API
|
||||
void FlecsComponentsHttpImport(
|
||||
ecs_world_t *world);
|
||||
|
||||
/* Utility to get parameter from query string */
|
||||
FLECS_COMPONENTS_HTTP_API
|
||||
size_t ecs_http_get_query_param(
|
||||
const char *query,
|
||||
const char *name,
|
||||
char *buffer,
|
||||
size_t len);
|
||||
|
||||
#define FlecsComponentsHttpImportHandles(handles)\
|
||||
ECS_IMPORT_COMPONENT(handles, EcsHttpServer);\
|
||||
ECS_IMPORT_COMPONENT(handles, EcsHttpEndpoint);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,271 +0,0 @@
|
|||
#ifndef FLECS_DASH_IMPL
|
||||
#include "flecs_dash.h"
|
||||
#endif
|
||||
|
||||
|
||||
static
|
||||
void EcsUpdateFps(ecs_iter_t *it) {
|
||||
ecs_world_t *world = it->world;
|
||||
|
||||
EcsFps *world_fps = ecs_column(it, EcsFps, 1);
|
||||
|
||||
const ecs_world_info_t *info = ecs_get_world_info(world);
|
||||
world_fps->value = 1.0 / info->delta_time_raw;
|
||||
world_fps->count += world_fps->value;
|
||||
world_fps->target = info->target_fps;
|
||||
}
|
||||
|
||||
static
|
||||
void EcsUpdateLoad(ecs_iter_t *it) {
|
||||
ecs_world_t *world = it->world;
|
||||
|
||||
EcsLoad *world_load = ecs_column(it, EcsLoad, 1);
|
||||
|
||||
const ecs_world_info_t *info = ecs_get_world_info(world);
|
||||
|
||||
world_load->total_time_count += info->delta_time_raw;
|
||||
world_load->frame_time_count = info->frame_time_total;
|
||||
world_load->system_time_count = info->system_time_total;
|
||||
world_load->merge_time_count = info->merge_time_total;
|
||||
}
|
||||
|
||||
static
|
||||
void EcsUpdateTick(ecs_iter_t *it) {
|
||||
ecs_world_t *world = it->world;
|
||||
|
||||
EcsTick *world_tick = ecs_column(it, EcsTick, 1);
|
||||
|
||||
const ecs_world_info_t *info = ecs_get_world_info(world);
|
||||
world_tick->count = info->frame_count_total;
|
||||
}
|
||||
|
||||
static
|
||||
void EcsUpdateClock(ecs_iter_t *it) {
|
||||
ecs_world_t *world = it->world;
|
||||
|
||||
EcsWorldClock *world_clock = ecs_column(it, EcsWorldClock, 1);
|
||||
|
||||
const ecs_world_info_t *info = ecs_get_world_info(world);
|
||||
world_clock->world_time = info->world_time_total;
|
||||
world_clock->world_time_raw = 0;
|
||||
}
|
||||
|
||||
void FlecsDashMonitorImport(
|
||||
ecs_world_t *world)
|
||||
{
|
||||
ECS_MODULE(world, FlecsDashMonitor);
|
||||
|
||||
ECS_IMPORT(world, FlecsMeta);
|
||||
|
||||
ecs_set_name_prefix(world, "Ecs");
|
||||
|
||||
ECS_META(world, EcsFps);
|
||||
ECS_META(world, EcsLoad);
|
||||
ECS_META(world, EcsTick);
|
||||
ECS_META(world, EcsWorldClock);
|
||||
|
||||
/* System for keeping track of world stats */
|
||||
ecs_set(world, EcsWorld, EcsFps, {0});
|
||||
ECS_SYSTEM(world, EcsUpdateFps, EcsOnLoad, flecs.core.World:Fps);
|
||||
|
||||
ecs_set(world, EcsWorld, EcsLoad, {0});
|
||||
ECS_SYSTEM(world, EcsUpdateLoad, EcsOnLoad, flecs.core.World:Load);
|
||||
|
||||
ecs_set(world, EcsWorld, EcsTick, {0});
|
||||
ECS_SYSTEM(world, EcsUpdateTick, EcsOnLoad, flecs.core.World:Tick);
|
||||
|
||||
ecs_set(world, EcsWorld, EcsWorldClock, {0});
|
||||
ECS_SYSTEM(world, EcsUpdateClock, EcsOnLoad, flecs.core.World:WorldClock);
|
||||
}
|
||||
|
||||
static
|
||||
bool request_this(
|
||||
ecs_world_t *world,
|
||||
ecs_entity_t entity,
|
||||
EcsHttpEndpoint *endpoint,
|
||||
EcsHttpRequest *request,
|
||||
EcsHttpReply *reply)
|
||||
{
|
||||
ecs_entity_t server = ecs_get_parent_w_entity(world, entity, 0);
|
||||
if (server) {
|
||||
ecs_strbuf_t buf = ECS_STRBUF_INIT;
|
||||
char *path = ecs_get_fullpath(world, server);
|
||||
ecs_strbuf_append(&buf, "{\"server_id\":\"%s\"}", path);
|
||||
ecs_os_free(path);
|
||||
reply->body = ecs_strbuf_get(&buf);
|
||||
return true;
|
||||
} else {
|
||||
reply->body = ecs_os_strdup("{\"server_id\":\"unknown\"}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
bool request_files(
|
||||
ecs_world_t *world,
|
||||
ecs_entity_t entity,
|
||||
EcsHttpEndpoint *endpoint,
|
||||
EcsHttpRequest *request,
|
||||
EcsHttpReply *reply)
|
||||
{
|
||||
const char *file = request->relative_url;
|
||||
char path[1024];
|
||||
|
||||
if (!file || !strlen(file)) {
|
||||
file = "index.html";
|
||||
}
|
||||
|
||||
char *etc_path = ecs_os_module_to_etc("flecs.dash");
|
||||
|
||||
sprintf(path, "%s/%s", etc_path, file);
|
||||
|
||||
FILE *f = fopen(path, "r");
|
||||
if (!f) {
|
||||
return false;
|
||||
} else {
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
reply->body = ecs_os_strdup(path);
|
||||
reply->is_file = true;
|
||||
|
||||
ecs_os_free(etc_path);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static
|
||||
bool request_player(
|
||||
ecs_world_t *world,
|
||||
ecs_entity_t entity,
|
||||
EcsHttpEndpoint *endpoint,
|
||||
EcsHttpRequest *request,
|
||||
EcsHttpReply *reply)
|
||||
{
|
||||
const char *cmd = request->relative_url;
|
||||
|
||||
ecs_entity_t ecs_typeid(EcsPlayer) = ecs_lookup_fullpath(
|
||||
world, "flecs.player.Player");
|
||||
|
||||
if (ecs_typeid(EcsPlayer)) {
|
||||
EcsPlayer *player = ecs_get_mut(world, EcsWorld, EcsPlayer, NULL);
|
||||
|
||||
if (!strcmp(cmd, "play")) {
|
||||
player->state = EcsPlayerPlay;
|
||||
} else if (!strcmp(cmd, "pause")) {
|
||||
player->state = EcsPlayerPause;
|
||||
} else if (!strcmp(cmd, "stop")) {
|
||||
player->state = EcsPlayerStop;
|
||||
}
|
||||
|
||||
ecs_modified(world, EcsWorld, EcsPlayer);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static
|
||||
void RunServer(ecs_iter_t *it) {
|
||||
ecs_world_t *world = it->world;
|
||||
|
||||
EcsDashServer *server = ecs_column(it, EcsDashServer, 1);
|
||||
|
||||
ecs_entity_t ecs_typeid(EcsHttpEndpoint) = ecs_column_entity(it, 2);
|
||||
ecs_entity_t ecs_typeid(EcsRestServer) = ecs_column_entity(it, 3);
|
||||
ecs_entity_t ecs_typeid(EcsMonitorServer) = ecs_column_entity(it, 4);
|
||||
ecs_entity_t ecs_typeid(EcsDashApp) = ecs_column_entity(it, 5);
|
||||
ecs_entity_t EcsDashInitialized = ecs_column_entity(it, 6);
|
||||
|
||||
int32_t i;
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
ecs_entity_t e = it->entities[i];
|
||||
EcsDashServer *s = &server[i];
|
||||
|
||||
/* Create REST & monitor server */
|
||||
ecs_set(world, e, EcsRestServer, {.port = s->port});
|
||||
ecs_set(world, e, EcsMonitorServer, {.port = s->port});
|
||||
|
||||
if (ecs_has_entity(world, e, EcsDashInitialized)) {
|
||||
/* Don't add endpoints again if already initialized */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Add endpoint to server for serving up files */
|
||||
ecs_entity_t e_files = ecs_new_w_entity(world, ECS_CHILDOF | e);
|
||||
ecs_set(world, e_files, EcsName, {"e_files"});
|
||||
ecs_set(world, e_files, EcsHttpEndpoint, {
|
||||
.url = "",
|
||||
.action = request_files});
|
||||
|
||||
/* Add endpoint to server that returns entity id of server */
|
||||
ecs_entity_t e_this = ecs_new_w_entity(world, ECS_CHILDOF | e);
|
||||
ecs_set(world, e_this, EcsName, {"e_this"});
|
||||
ecs_set(world, e_this, EcsHttpEndpoint, {
|
||||
.url = "this",
|
||||
.action = request_this});
|
||||
|
||||
/* Add endpoint to server that returns entity id of server */
|
||||
ecs_entity_t e_player = ecs_new_w_entity(world, ECS_CHILDOF | e);
|
||||
ecs_set(world, e_player, EcsName, {"e_player"});
|
||||
ecs_set(world, e_player, EcsHttpEndpoint, {
|
||||
.url = "player",
|
||||
.action = request_player,
|
||||
.synchronous = true});
|
||||
|
||||
/* Add browser app */
|
||||
ecs_entity_t dash_overview = ecs_new_w_entity(world, ECS_CHILDOF | e);
|
||||
ecs_set(world, dash_overview, EcsName, {"overview"});
|
||||
ecs_set(world, dash_overview, EcsDashApp, {
|
||||
.path = "etc/apps/overview",
|
||||
.icon = "images/usage.png"
|
||||
});
|
||||
|
||||
ecs_entity_t dash_systems = ecs_new_w_entity(world, ECS_CHILDOF | e);
|
||||
ecs_set(world, dash_systems, EcsName, {"systems"});
|
||||
ecs_set(world, dash_systems, EcsDashApp, {
|
||||
.path = "etc/apps/systems",
|
||||
.icon = "images/layers.png"
|
||||
});
|
||||
|
||||
ecs_entity_t dash_browser = ecs_new_w_entity(world, ECS_CHILDOF | e);
|
||||
ecs_set(world, dash_browser, EcsName, {"browser"});
|
||||
ecs_set(world, dash_browser, EcsDashApp, {
|
||||
.path = "etc/apps/browser",
|
||||
.icon = "images/tree.png"
|
||||
});
|
||||
|
||||
/* Prevent initializing the server again */
|
||||
ecs_add_entity(world, e, EcsDashInitialized);
|
||||
}
|
||||
}
|
||||
|
||||
void FlecsDashImport(
|
||||
ecs_world_t *world)
|
||||
{
|
||||
ECS_MODULE(world, FlecsDash);
|
||||
|
||||
ECS_IMPORT(world, FlecsMonitor);
|
||||
ECS_IMPORT(world, FlecsDashMonitor);
|
||||
|
||||
ECS_IMPORT(world, FlecsMeta);
|
||||
ECS_IMPORT(world, FlecsPlayer);
|
||||
ECS_IMPORT(world, FlecsComponentsHttp);
|
||||
ECS_IMPORT(world, FlecsRest);
|
||||
|
||||
ecs_set_name_prefix(world, "EcsDash");
|
||||
|
||||
ECS_META(world, EcsDashServer);
|
||||
ECS_META(world, EcsDashApp);
|
||||
|
||||
ECS_TAG(world, EcsDashInitialized);
|
||||
|
||||
ECS_SYSTEM(world, RunServer, EcsOnSet, Server,
|
||||
:flecs.components.http.Endpoint,
|
||||
:flecs.rest.Server,
|
||||
:flecs.monitor.Server,
|
||||
:App,
|
||||
:Initialized);
|
||||
|
||||
ECS_EXPORT_COMPONENT(EcsDashServer);
|
||||
ECS_EXPORT_COMPONENT(EcsDashApp);
|
||||
}
|
|
@ -1,158 +0,0 @@
|
|||
#define flecs_dash_STATIC
|
||||
#ifndef FLECS_DASH_H
|
||||
#define FLECS_DASH_H
|
||||
|
||||
/* This generated file contains includes for project dependencies */
|
||||
/*
|
||||
)
|
||||
(.)
|
||||
.|.
|
||||
| |
|
||||
_.--| |--._
|
||||
.-'; ;`-'& ; `&.
|
||||
\ & ; & &_/
|
||||
|"""---...---"""|
|
||||
\ | | | | | | | /
|
||||
`---.|.|.|.---'
|
||||
|
||||
* This file is generated by bake.lang.c for your convenience. Headers of
|
||||
* dependencies will automatically show up in this file. Include bake_config.h
|
||||
* in your main project file. Do not edit! */
|
||||
|
||||
#ifndef FLECS_DASH_BAKE_CONFIG_H
|
||||
#define FLECS_DASH_BAKE_CONFIG_H
|
||||
|
||||
/* Headers of public dependencies */
|
||||
#include <flecs.h>
|
||||
#include <flecs_meta.h>
|
||||
#include <flecs_player.h>
|
||||
#include <flecs_components_http.h>
|
||||
#include <flecs_rest.h>
|
||||
#include <flecs_monitor.h>
|
||||
|
||||
/* Convenience macro for exporting symbols */
|
||||
#ifndef flecs_dash_STATIC
|
||||
#if flecs_dash_EXPORTS && (defined(_MSC_VER) || defined(__MINGW32__))
|
||||
#define FLECS_DASH_API __declspec(dllexport)
|
||||
#elif flecs_dash_EXPORTS
|
||||
#define FLECS_DASH_API __attribute__((__visibility__("default")))
|
||||
#elif defined _MSC_VER
|
||||
#define FLECS_DASH_API __declspec(dllimport)
|
||||
#else
|
||||
#define FLECS_DASH_API
|
||||
#endif
|
||||
#else
|
||||
#define FLECS_DASH_API
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef FLECS_DASH_MONITOR_H
|
||||
#define FLECS_DASH_MONITOR_H
|
||||
|
||||
/* This generated file contains includes for project dependencies */
|
||||
|
||||
ECS_STRUCT(EcsFps, {
|
||||
double value;
|
||||
double count;
|
||||
double target;
|
||||
});
|
||||
|
||||
ECS_STRUCT(EcsTick, {
|
||||
double count;
|
||||
});
|
||||
|
||||
ECS_STRUCT(EcsLoad, {
|
||||
double total_time_count;
|
||||
double frame_time_count;
|
||||
double system_time_count;
|
||||
double merge_time_count;
|
||||
});
|
||||
|
||||
ECS_STRUCT(EcsWorldClock, {
|
||||
double world_time;
|
||||
double world_time_raw;
|
||||
});
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct FlecsDashMonitor {
|
||||
ECS_DECLARE_COMPONENT(EcsFps);
|
||||
} FlecsDashMonitor;
|
||||
|
||||
FLECS_DASH_API
|
||||
void FlecsDashMonitorImport(
|
||||
ecs_world_t *world);
|
||||
|
||||
#define FlecsDashMonitorImportHandles(handles)\
|
||||
ECS_IMPORT_COMPONENT(handles, EcsFps);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Module implementation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ECS_STRUCT(EcsDashServer, {
|
||||
int16_t port;
|
||||
});
|
||||
|
||||
ECS_STRUCT(EcsDashApp, {
|
||||
char *path;
|
||||
char *icon;
|
||||
});
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct FlecsDash {
|
||||
ECS_DECLARE_COMPONENT(EcsDashServer);
|
||||
ECS_DECLARE_COMPONENT(EcsDashApp);
|
||||
} FlecsDash;
|
||||
|
||||
FLECS_DASH_API
|
||||
void FlecsDashImport(
|
||||
ecs_world_t *world);
|
||||
|
||||
#define FlecsDashImportHandles(handles)\
|
||||
ECS_IMPORT_COMPONENT(handles, EcsDashServer);\
|
||||
ECS_IMPORT_COMPONENT(handles, EcsDashApp)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#ifndef FLECS_NO_CPP
|
||||
|
||||
namespace flecs {
|
||||
|
||||
class dash : public FlecsDash {
|
||||
public:
|
||||
using Server = EcsDashServer;
|
||||
using App = EcsDashApp;
|
||||
|
||||
dash(flecs::world& world) {
|
||||
FlecsDashImport(world.c_ptr());
|
||||
|
||||
flecs::module<flecs::dash>(world, "flecs::dash");
|
||||
|
||||
flecs::component<Server>(world, "flecs::dash::Server");
|
||||
flecs::component<App>(world, "flecs::dash::App");
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // FLECS_NO_CPP
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
|
@ -1,561 +0,0 @@
|
|||
#ifndef FLECS_JSON_IMPL
|
||||
#include "flecs_json.h"
|
||||
#endif
|
||||
|
||||
/* Simple serializer to turn values into strings. Use this code as a template
|
||||
* for when implementing a new serializer. */
|
||||
|
||||
static
|
||||
void json_ser_type(
|
||||
ecs_world_t *world,
|
||||
ecs_vector_t *ser,
|
||||
const void *base,
|
||||
ecs_strbuf_t *str);
|
||||
|
||||
static
|
||||
void json_ser_type_op(
|
||||
ecs_world_t *world,
|
||||
ecs_type_op_t *op,
|
||||
const void *base,
|
||||
ecs_strbuf_t *str);
|
||||
|
||||
/* Serialize a primitive value */
|
||||
static
|
||||
void json_ser_primitive(
|
||||
ecs_world_t *world,
|
||||
ecs_type_op_t *op,
|
||||
const void *base,
|
||||
ecs_strbuf_t *str)
|
||||
{
|
||||
const char *bool_str[] = { "false", "true" };
|
||||
|
||||
switch(op->is.primitive) {
|
||||
case EcsBool:
|
||||
ecs_strbuf_appendstr(str, bool_str[(int)*(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_append(str, "%i", *(intptr_t*)base);
|
||||
break;
|
||||
case EcsUPtr:
|
||||
ecs_strbuf_append(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, "\"", 1);
|
||||
ecs_strbuf_appendstr(str, ecs_get_name(world, *(ecs_entity_t*)base));
|
||||
ecs_strbuf_appendstrn(str, "\"", 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Serialize enumeration */
|
||||
static
|
||||
void json_ser_enum(
|
||||
ecs_world_t *world,
|
||||
ecs_type_op_t *op,
|
||||
const void *base,
|
||||
ecs_strbuf_t *str)
|
||||
{
|
||||
const EcsEnum *enum_type = ecs_get_ref_w_entity(world, &op->is.constant, 0, 0);
|
||||
ecs_assert(enum_type != NULL, ECS_INVALID_PARAMETER, NULL);
|
||||
|
||||
int32_t value = *(int32_t*)base;
|
||||
|
||||
/* Enumeration constants are stored in a map that is keyed on the
|
||||
* enumeration value. */
|
||||
char **constant = ecs_map_get(enum_type->constants, char*, value);
|
||||
ecs_assert(constant != NULL, ECS_INVALID_PARAMETER, NULL);
|
||||
|
||||
ecs_strbuf_appendstrn(str, "\"", 1);
|
||||
ecs_strbuf_appendstr(str, *constant);
|
||||
ecs_strbuf_appendstrn(str, "\"", 1);
|
||||
}
|
||||
|
||||
/* Serialize bitmask */
|
||||
static
|
||||
void json_ser_bitmask(
|
||||
ecs_world_t *world,
|
||||
ecs_type_op_t *op,
|
||||
const void *base,
|
||||
ecs_strbuf_t *str)
|
||||
{
|
||||
const EcsBitmask *bitmask_type = ecs_get_ref_w_entity(world, &op->is.constant, 0, 0);
|
||||
ecs_assert(bitmask_type != NULL, ECS_INVALID_PARAMETER, NULL);
|
||||
|
||||
int32_t value = *(int32_t*)base;
|
||||
ecs_map_key_t key;
|
||||
char **constant;
|
||||
|
||||
ecs_strbuf_list_push(str, "[", ",");
|
||||
|
||||
/* Multiple flags can be set at a given time. Iterate through all the flags
|
||||
* and append the ones that are set. */
|
||||
ecs_map_iter_t it = ecs_map_iter(bitmask_type->constants);
|
||||
while ((constant = ecs_map_next(&it, char*, &key))) {
|
||||
if ((value & key) == key) {
|
||||
ecs_strbuf_list_append(str, "\"%s\"", *constant);
|
||||
}
|
||||
}
|
||||
|
||||
ecs_strbuf_list_pop(str, "]");
|
||||
}
|
||||
|
||||
/* Serialize elements of a contiguous array */
|
||||
static
|
||||
void json_ser_elements(
|
||||
ecs_world_t *world,
|
||||
ecs_vector_t *elem_ops,
|
||||
const void *base,
|
||||
int32_t elem_count,
|
||||
int32_t elem_size,
|
||||
ecs_strbuf_t *str)
|
||||
{
|
||||
ecs_strbuf_list_push(str, "[", ",");
|
||||
|
||||
const void *ptr = base;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < elem_count; i ++) {
|
||||
ecs_strbuf_list_next(str);
|
||||
json_ser_type(world, elem_ops, ptr, str);
|
||||
ptr = ECS_OFFSET(ptr, elem_size);
|
||||
}
|
||||
|
||||
ecs_strbuf_list_pop(str, "]");
|
||||
}
|
||||
|
||||
/* Serialize array */
|
||||
static
|
||||
void json_ser_array(
|
||||
ecs_world_t *world,
|
||||
ecs_type_op_t *op,
|
||||
void *base,
|
||||
ecs_strbuf_t *str)
|
||||
{
|
||||
const EcsMetaTypeSerializer *ser = ecs_get_ref_w_entity(world, &op->is.collection, 0, 0);
|
||||
ecs_assert(ser != NULL, ECS_INTERNAL_ERROR, NULL);
|
||||
|
||||
json_ser_elements(world, ser->ops, base, op->count, op->size, str);
|
||||
}
|
||||
|
||||
/* Serialize vector */
|
||||
static
|
||||
void json_ser_vector(
|
||||
ecs_world_t *world,
|
||||
ecs_type_op_t *op,
|
||||
const 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_t(value, op->size, op->alignment);
|
||||
|
||||
const EcsMetaTypeSerializer *ser = ecs_get_ref_w_entity(world, &op->is.collection, 0, 0);
|
||||
ecs_assert(ser != NULL, ECS_INTERNAL_ERROR, NULL);
|
||||
|
||||
ecs_vector_t *elem_ops = ser->ops;
|
||||
|
||||
ecs_type_op_t *elem_op_hdr = (ecs_type_op_t*)ecs_vector_first(elem_ops, ecs_type_op_t);
|
||||
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;
|
||||
|
||||
/* Serialize contiguous buffer of vector */
|
||||
json_ser_elements(world, elem_ops, array, count, elem_size, str);
|
||||
}
|
||||
|
||||
/* Serialize map */
|
||||
static
|
||||
void json_ser_map(
|
||||
ecs_world_t *world,
|
||||
ecs_type_op_t *op,
|
||||
const void *base,
|
||||
ecs_strbuf_t *str)
|
||||
{
|
||||
ecs_map_t *value = *(ecs_map_t**)base;
|
||||
|
||||
const EcsMetaTypeSerializer *key_ser = ecs_get_ref_w_entity(world, &op->is.map.key, 0, 0);
|
||||
ecs_assert(key_ser != NULL, ECS_INTERNAL_ERROR, NULL);
|
||||
|
||||
const EcsMetaTypeSerializer *elem_ser = ecs_get_ref_w_entity(world, &op->is.map.element, 0, 0);
|
||||
ecs_assert(elem_ser != NULL, ECS_INTERNAL_ERROR, NULL);
|
||||
|
||||
/* 2 instructions, one for the header */
|
||||
ecs_assert(ecs_vector_count(key_ser->ops) == 2, ECS_INTERNAL_ERROR, NULL);
|
||||
|
||||
ecs_type_op_t *key_op = ecs_vector_first(key_ser->ops, ecs_type_op_t);
|
||||
ecs_assert(key_op->kind == EcsOpHeader, ECS_INTERNAL_ERROR, NULL);
|
||||
key_op = &key_op[1];
|
||||
|
||||
ecs_map_iter_t it = ecs_map_iter(value);
|
||||
ecs_map_key_t key;
|
||||
void *ptr;
|
||||
|
||||
ecs_strbuf_list_push(str, "{", ",");
|
||||
|
||||
while ((ptr = _ecs_map_next(&it, 0, &key))) {
|
||||
ecs_strbuf_list_next(str);
|
||||
ecs_strbuf_appendstrn(str, "\"", 1);
|
||||
json_ser_type_op(world, key_op, (void*)&key, str);
|
||||
ecs_strbuf_appendstrn(str, "\"", 1);
|
||||
ecs_strbuf_appendstr(str, ":");
|
||||
json_ser_type(world, elem_ser->ops, ptr, str);
|
||||
|
||||
key = 0;
|
||||
}
|
||||
|
||||
ecs_strbuf_list_pop(str, "}");
|
||||
}
|
||||
|
||||
/* Forward serialization to the different type kinds */
|
||||
static
|
||||
void json_ser_type_op(
|
||||
ecs_world_t *world,
|
||||
ecs_type_op_t *op,
|
||||
const void *base,
|
||||
ecs_strbuf_t *str)
|
||||
{
|
||||
switch(op->kind) {
|
||||
case EcsOpHeader:
|
||||
case EcsOpPush:
|
||||
case EcsOpPop:
|
||||
/* Should not be parsed as single op */
|
||||
ecs_abort(ECS_INVALID_PARAMETER, NULL);
|
||||
break;
|
||||
case EcsOpPrimitive:
|
||||
json_ser_primitive(world, op, ECS_OFFSET(base, op->offset), str);
|
||||
break;
|
||||
case EcsOpEnum:
|
||||
json_ser_enum(world, op, ECS_OFFSET(base, op->offset), str);
|
||||
break;
|
||||
case EcsOpBitmask:
|
||||
json_ser_bitmask(world, op, ECS_OFFSET(base, op->offset), str);
|
||||
break;
|
||||
case EcsOpArray:
|
||||
json_ser_array(world, op, ECS_OFFSET(base, op->offset), str);
|
||||
break;
|
||||
case EcsOpVector:
|
||||
json_ser_vector(world, op, ECS_OFFSET(base, op->offset), str);
|
||||
break;
|
||||
case EcsOpMap:
|
||||
json_ser_map(world, op, ECS_OFFSET(base, op->offset), str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Iterate over the type ops of a type */
|
||||
static
|
||||
void json_ser_type(
|
||||
ecs_world_t *world,
|
||||
ecs_vector_t *ser,
|
||||
const void *base,
|
||||
ecs_strbuf_t *str)
|
||||
{
|
||||
ecs_type_op_t *ops = (ecs_type_op_t*)ecs_vector_first(ser, ecs_type_op_t);
|
||||
int32_t count = ecs_vector_count(ser);
|
||||
|
||||
for (int i = 0; i < count; i ++) {
|
||||
ecs_type_op_t *op = &ops[i];
|
||||
|
||||
if (op->name) {
|
||||
if (op->kind != EcsOpHeader) {
|
||||
ecs_strbuf_list_next(str);
|
||||
}
|
||||
|
||||
ecs_strbuf_append(str, "\"%s\":", op->name);
|
||||
}
|
||||
|
||||
switch(op->kind) {
|
||||
case EcsOpHeader:
|
||||
break;
|
||||
case EcsOpPush:
|
||||
ecs_strbuf_list_push(str, "{", ",");
|
||||
break;
|
||||
case EcsOpPop:
|
||||
ecs_strbuf_list_pop(str, "}");
|
||||
break;
|
||||
default:
|
||||
json_ser_type_op(world, op, base, str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char* ecs_ptr_to_json(
|
||||
ecs_world_t *world,
|
||||
ecs_entity_t type,
|
||||
void* ptr)
|
||||
{
|
||||
ecs_entity_t ecs_typeid(EcsMetaTypeSerializer) = ecs_lookup(world, "EcsMetaTypeSerializer");
|
||||
const EcsMetaTypeSerializer *ser = ecs_get(world, type, EcsMetaTypeSerializer);
|
||||
ecs_assert(ser != NULL, ECS_INVALID_PARAMETER, NULL);
|
||||
|
||||
ecs_strbuf_t str = ECS_STRBUF_INIT;
|
||||
json_ser_type(world, ser->ops, ptr, &str);
|
||||
return ecs_strbuf_get(&str);
|
||||
}
|
||||
|
||||
void json_ser_column(
|
||||
ecs_world_t *world,
|
||||
const EcsMetaTypeSerializer *ser,
|
||||
void *ptr,
|
||||
int32_t count,
|
||||
ecs_strbuf_t *str)
|
||||
{
|
||||
ecs_vector_t *ops = ser->ops;
|
||||
ecs_type_op_t *hdr = ecs_vector_first(ops, ecs_type_op_t);
|
||||
ecs_assert(hdr->kind == EcsOpHeader, ECS_INTERNAL_ERROR, NULL);
|
||||
int32_t size = hdr->size;
|
||||
|
||||
ecs_strbuf_list_push(str, "[", ",");
|
||||
|
||||
int i;
|
||||
for (i = 0; i < count; i ++) {
|
||||
ecs_strbuf_list_next(str);
|
||||
json_ser_type(world, ops, ptr, str);
|
||||
ptr = ECS_OFFSET(ptr, size);
|
||||
}
|
||||
|
||||
ecs_strbuf_list_pop(str, "]");
|
||||
}
|
||||
|
||||
static
|
||||
void serialize_type(
|
||||
ecs_world_t *world,
|
||||
ecs_type_t type,
|
||||
ecs_strbuf_t *str)
|
||||
{
|
||||
ecs_strbuf_list_push(str, "[", ",");
|
||||
|
||||
int i, count = ecs_vector_count(type);
|
||||
ecs_entity_t *comps = ecs_vector_first(type, ecs_entity_t);
|
||||
for (i = 0; i < count; i ++) {
|
||||
ecs_entity_t comp = comps[i];
|
||||
bool has_role = (comp & ECS_COMPONENT_MASK) != comp;
|
||||
ecs_entity_t comp_e = comp & ECS_COMPONENT_MASK;
|
||||
|
||||
if (has_role) {
|
||||
ecs_strbuf_list_next(str);
|
||||
ecs_strbuf_list_push(str, "[", ",");
|
||||
ecs_strbuf_list_append(str, "\"%s\"", ecs_role_str(comp));
|
||||
}
|
||||
|
||||
if (ECS_HAS_ROLE(comp, TRAIT)) {
|
||||
ecs_entity_t hi = ecs_entity_t_hi(comp_e);
|
||||
char *hi_path = ecs_get_fullpath(world, hi);
|
||||
ecs_strbuf_list_append(str, "\"%s\"", hi_path);
|
||||
ecs_os_free(hi_path);
|
||||
comp_e = ecs_entity_t_lo(comp_e);
|
||||
}
|
||||
|
||||
char *comp_path = ecs_get_fullpath(world, comp_e);
|
||||
if (comp_path) {
|
||||
ecs_strbuf_list_append(str, "\"%s\"", comp_path);
|
||||
} else {
|
||||
ecs_strbuf_list_append(str, "%d", (int32_t)comp);
|
||||
}
|
||||
|
||||
if (has_role) {
|
||||
ecs_strbuf_list_pop(str, "]");
|
||||
}
|
||||
|
||||
ecs_os_free(comp_path);
|
||||
}
|
||||
|
||||
ecs_strbuf_list_pop(str, "]");
|
||||
}
|
||||
|
||||
char* ecs_type_to_json(
|
||||
ecs_world_t *world,
|
||||
ecs_type_t type)
|
||||
{
|
||||
ecs_strbuf_t str = ECS_STRBUF_INIT;
|
||||
serialize_type(world, type, &str);
|
||||
return ecs_strbuf_get(&str);
|
||||
}
|
||||
|
||||
char* ecs_iter_to_json(
|
||||
ecs_world_t *world,
|
||||
ecs_iter_t *it,
|
||||
ecs_iter_next_action_t iter_next,
|
||||
ecs_type_t select)
|
||||
{
|
||||
ecs_strbuf_t str = ECS_STRBUF_INIT;
|
||||
ecs_entity_t ecs_typeid(EcsMetaTypeSerializer) =
|
||||
ecs_lookup_fullpath(world, "flecs.meta.MetaTypeSerializer");
|
||||
ecs_assert(ecs_typeid(EcsMetaTypeSerializer) != 0, ECS_INTERNAL_ERROR, NULL);
|
||||
|
||||
ecs_strbuf_list_push(&str, "[", ",");
|
||||
|
||||
while (iter_next(it)) {
|
||||
ecs_type_t table_type = ecs_iter_type(it);
|
||||
ecs_entity_t *comps = ecs_vector_first(table_type, ecs_entity_t);
|
||||
int32_t i, count = ecs_vector_count(table_type);
|
||||
|
||||
if (!it->count) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ecs_strbuf_list_next(&str);
|
||||
ecs_strbuf_list_push(&str, "{", ",");
|
||||
|
||||
/* Serialize type */
|
||||
ecs_strbuf_list_appendstr(&str, "\"type\":");
|
||||
serialize_type(world, table_type, &str);
|
||||
|
||||
/* Add entity identifiers */
|
||||
ecs_strbuf_list_appendstr(&str, "\"entities\":");
|
||||
ecs_strbuf_list_push(&str, "[", ",");
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
ecs_strbuf_list_append(&str, "%d", (int32_t)it->entities[i]);
|
||||
}
|
||||
ecs_strbuf_list_pop(&str, "]");
|
||||
|
||||
/* Serialize data */
|
||||
ecs_strbuf_list_appendstr(&str, "\"data\":");
|
||||
ecs_strbuf_list_push(&str, "{", ",");
|
||||
|
||||
for (i = 0; i < count; i ++) {
|
||||
if (select) {
|
||||
if (!ecs_type_has_entity(world, select, comps[i])) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
const EcsMetaTypeSerializer *ser = ecs_get(
|
||||
world, comps[i], EcsMetaTypeSerializer);
|
||||
|
||||
/* Don't serialize if there's no metadata for component */
|
||||
if (!ser) {
|
||||
continue;
|
||||
}
|
||||
|
||||
char *comp_path = ecs_get_fullpath(world, comps[i]);
|
||||
ecs_strbuf_list_append(&str, "\"%s\":", comp_path);
|
||||
ecs_os_free(comp_path);
|
||||
|
||||
json_ser_column(
|
||||
world, ser, ecs_table_column(it, i), it->count, &str);
|
||||
}
|
||||
|
||||
ecs_strbuf_list_pop(&str, "}");
|
||||
ecs_strbuf_list_pop(&str, "}");
|
||||
}
|
||||
|
||||
ecs_strbuf_list_pop(&str, "]");
|
||||
|
||||
return ecs_strbuf_get(&str);
|
||||
}
|
||||
|
||||
char* ecs_entity_to_json(
|
||||
ecs_world_t *world,
|
||||
ecs_entity_t entity,
|
||||
ecs_type_t select)
|
||||
{
|
||||
ecs_strbuf_t str = ECS_STRBUF_INIT;
|
||||
ecs_entity_t ecs_typeid(EcsMetaTypeSerializer) =
|
||||
ecs_lookup_fullpath(world, "flecs.meta.MetaTypeSerializer");
|
||||
ecs_assert(ecs_typeid(EcsMetaTypeSerializer) != 0, ECS_INTERNAL_ERROR, NULL);
|
||||
|
||||
ecs_strbuf_list_push(&str, "{", ",");
|
||||
|
||||
/* Serialize type */
|
||||
ecs_type_t type = ecs_get_type(world, entity);
|
||||
ecs_strbuf_list_appendstr(&str, "\"type\":");
|
||||
serialize_type(world, type, &str);
|
||||
|
||||
/* Serialize entity id */
|
||||
ecs_strbuf_list_append(&str, "\"entity\":%d", (int32_t)entity);
|
||||
|
||||
/* Serialize entity path */
|
||||
char *path = ecs_get_fullpath(world, entity);
|
||||
ecs_strbuf_list_append(&str, "\"path\":\"%s\"", path);
|
||||
ecs_os_free(path);
|
||||
|
||||
/* Serialize data */
|
||||
if (type) {
|
||||
ecs_strbuf_list_appendstr(&str, "\"data\":");
|
||||
ecs_strbuf_list_push(&str, "{", ",");
|
||||
|
||||
int i, count = ecs_vector_count(type);
|
||||
ecs_entity_t *comps = ecs_vector_first(type, ecs_entity_t);
|
||||
for (i = 0; i < count; i ++) {
|
||||
if (select) {
|
||||
if (!ecs_type_has_entity(world, select, comps[i])) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
const EcsMetaTypeSerializer *ser = ecs_get(
|
||||
world, comps[i], EcsMetaTypeSerializer);
|
||||
|
||||
/* Don't serialize if there's no metadata for component */
|
||||
if (!ser) {
|
||||
continue;
|
||||
}
|
||||
|
||||
char *comp_path = ecs_get_fullpath(world, comps[i]);
|
||||
ecs_strbuf_list_append(&str, "\"%s\":", comp_path);
|
||||
ecs_os_free(comp_path);
|
||||
|
||||
const void *comp_ptr = ecs_get_w_entity(world, entity, comps[i]);
|
||||
ecs_assert(comp_ptr != NULL, ECS_INTERNAL_ERROR, NULL);
|
||||
|
||||
json_ser_type(world, ser->ops, comp_ptr, &str);
|
||||
}
|
||||
|
||||
ecs_strbuf_list_pop(&str, "}");
|
||||
}
|
||||
|
||||
ecs_strbuf_list_pop(&str, "}");
|
||||
|
||||
return ecs_strbuf_get(&str);
|
||||
}
|
|
@ -1,116 +0,0 @@
|
|||
#define flecs_json_STATIC
|
||||
#ifndef FLECS_JSON_H
|
||||
#define FLECS_JSON_H
|
||||
|
||||
/* This generated file contains includes for project dependencies */
|
||||
/*
|
||||
)
|
||||
(.)
|
||||
.|.
|
||||
| |
|
||||
_.--| |--._
|
||||
.-'; ;`-'& ; `&.
|
||||
\ & ; & &_/
|
||||
|"""---...---"""|
|
||||
\ | | | | | | | /
|
||||
`---.|.|.|.---'
|
||||
|
||||
* This file is generated by bake.lang.c for your convenience. Headers of
|
||||
* dependencies will automatically show up in this file. Include bake_config.h
|
||||
* in your main project file. Do not edit! */
|
||||
|
||||
#ifndef FLECS_JSON_BAKE_CONFIG_H
|
||||
#define FLECS_JSON_BAKE_CONFIG_H
|
||||
|
||||
/* Headers of public dependencies */
|
||||
#include <flecs.h>
|
||||
#include <flecs_meta.h>
|
||||
|
||||
/* Convenience macro for exporting symbols */
|
||||
#ifndef flecs_json_STATIC
|
||||
#if flecs_json_EXPORTS && (defined(_MSC_VER) || defined(__MINGW32__))
|
||||
#define FLECS_JSON_API __declspec(dllexport)
|
||||
#elif flecs_json_EXPORTS
|
||||
#define FLECS_JSON_API __attribute__((__visibility__("default")))
|
||||
#elif defined _MSC_VER
|
||||
#define FLECS_JSON_API __declspec(dllimport)
|
||||
#else
|
||||
#define FLECS_JSON_API
|
||||
#endif
|
||||
#else
|
||||
#define FLECS_JSON_API
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
FLECS_JSON_API
|
||||
char* ecs_ptr_to_json(
|
||||
ecs_world_t *world,
|
||||
ecs_entity_t type,
|
||||
void *ptr);
|
||||
|
||||
FLECS_JSON_API
|
||||
char* ecs_entity_to_json(
|
||||
ecs_world_t *world,
|
||||
ecs_entity_t e,
|
||||
ecs_type_t select);
|
||||
|
||||
FLECS_JSON_API
|
||||
char* ecs_iter_to_json(
|
||||
ecs_world_t *world,
|
||||
ecs_iter_t *it,
|
||||
ecs_iter_next_action_t iter_next,
|
||||
ecs_type_t select);
|
||||
|
||||
FLECS_JSON_API
|
||||
char* ecs_type_to_json(
|
||||
ecs_world_t *world,
|
||||
ecs_type_t type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace flecs {
|
||||
|
||||
template <typename T>
|
||||
std::string to_json(flecs::world& world, flecs::entity_t type, T& data) {
|
||||
char *str = ecs_ptr_to_json(world.c_ptr(), type, &data);
|
||||
std::string result = std::string(str);
|
||||
free(str);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::string to_json(flecs::world& world, flecs::entity type, T& data) {
|
||||
return to_json(world, type.id(), data);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::string to_json(flecs::world& world, T& data) {
|
||||
entity_t type = _::component_info<T>::s_entity;
|
||||
return flecs::to_json(world, type, data);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline std::string to_json<flecs::entity>(flecs::world& world, flecs::entity& entity) {
|
||||
char *str = ecs_entity_to_json(world.c_ptr(), entity.id(), nullptr);
|
||||
std::string result = std::string(str);
|
||||
free(str);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,698 +0,0 @@
|
|||
#define flecs_meta_STATIC
|
||||
#ifndef FLECS_META_H
|
||||
#define FLECS_META_H
|
||||
|
||||
/* This generated file contains includes for project dependencies */
|
||||
/*
|
||||
)
|
||||
(.)
|
||||
.|.
|
||||
| |
|
||||
_.--| |--._
|
||||
.-'; ;`-'& ; `&.
|
||||
\ & ; & &_/
|
||||
|"""---...---"""|
|
||||
\ | | | | | | | /
|
||||
`---.|.|.|.---'
|
||||
|
||||
* This file is generated by bake.lang.c for your convenience. Headers of
|
||||
* dependencies will automatically show up in this file. Include bake_config.h
|
||||
* in your main project file. Do not edit! */
|
||||
|
||||
#ifndef FLECS_META_BAKE_CONFIG_H
|
||||
#define FLECS_META_BAKE_CONFIG_H
|
||||
|
||||
/* Headers of public dependencies */
|
||||
#include <flecs.h>
|
||||
|
||||
/* Convenience macro for exporting symbols */
|
||||
#ifndef flecs_meta_STATIC
|
||||
#if flecs_meta_EXPORTS && (defined(_MSC_VER) || defined(__MINGW32__))
|
||||
#define FLECS_META_API __declspec(dllexport)
|
||||
#elif flecs_meta_EXPORTS
|
||||
#define FLECS_META_API __attribute__((__visibility__("default")))
|
||||
#elif defined _MSC_VER
|
||||
#define FLECS_META_API __declspec(dllimport)
|
||||
#else
|
||||
#define FLECS_META_API
|
||||
#endif
|
||||
#else
|
||||
#define FLECS_META_API
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef FLECS_LEGACY
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Utility macro's (do not use in code!)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define ECS_ENUM_BOOTSTRAP(name, ...)\
|
||||
typedef enum name __VA_ARGS__ name;\
|
||||
ECS_UNUSED \
|
||||
static const char * __##name##__ = #__VA_ARGS__;
|
||||
|
||||
#define ECS_STRUCT_IMPL(name, descriptor, ...)\
|
||||
typedef struct name __VA_ARGS__ name;\
|
||||
ECS_UNUSED \
|
||||
static EcsMetaType __##name##__ = {EcsStructType, sizeof(name), ECS_ALIGNOF(name), descriptor, NULL};
|
||||
|
||||
#define ECS_ENUM_IMPL(name, descriptor, ...)\
|
||||
typedef enum name __VA_ARGS__ name;\
|
||||
ECS_UNUSED \
|
||||
static EcsMetaType __##name##__ = {EcsEnumType, sizeof(name), ECS_ALIGNOF(name), descriptor, NULL};
|
||||
|
||||
#define ECS_BITMASK_IMPL(name, descriptor, ...)\
|
||||
typedef enum name __VA_ARGS__ name;\
|
||||
ECS_UNUSED \
|
||||
static EcsMetaType __##name##__ = {EcsBitmaskType, sizeof(name), ECS_ALIGNOF(name), descriptor, NULL};
|
||||
|
||||
#define ECS_STRUCT_C(T, ...) ECS_STRUCT_IMPL(T, #__VA_ARGS__, __VA_ARGS__)
|
||||
#define ECS_ENUM_C(T, ...) ECS_ENUM_IMPL(T, #__VA_ARGS__, __VA_ARGS__)
|
||||
#define ECS_BITMASK_C(T, ...) ECS_BITMASK_IMPL(T, #__VA_ARGS__, __VA_ARGS__)
|
||||
|
||||
#define ECS_ARRAY(name, T, length)\
|
||||
typedef T name[length];\
|
||||
ECS_UNUSED \
|
||||
static EcsMetaType __##name##__ = {EcsArrayType, sizeof(T) * length, ECS_ALIGNOF(T), "(" #T "," #length ")", NULL}
|
||||
|
||||
#define ECS_VECTOR(name, T)\
|
||||
typedef ecs_vector_t *name;\
|
||||
ECS_UNUSED \
|
||||
static EcsMetaType __##name##__ = {EcsVectorType, sizeof(ecs_vector_t*), ECS_ALIGNOF(ecs_vector_t*), "(" #T ")", NULL}
|
||||
|
||||
#define ECS_MAP(name, K, T)\
|
||||
typedef ecs_map_t *name;\
|
||||
ECS_UNUSED \
|
||||
static EcsMetaType __##name##__ = {EcsMapType, sizeof(ecs_map_t*), ECS_ALIGNOF(ecs_map_t*), "(" #K "," #T ")", NULL}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
// Unspecialized class (see below)
|
||||
namespace flecs {
|
||||
template <typename T>
|
||||
class __meta__ { };
|
||||
}
|
||||
|
||||
// Specialized C++ class that stores name and descriptor of type
|
||||
#define ECS_META_CPP(T, kind, descr)\
|
||||
namespace flecs {\
|
||||
template<>\
|
||||
class __meta__ <T> {\
|
||||
public:\
|
||||
static const char* name() {\
|
||||
return #T;\
|
||||
}\
|
||||
static EcsMetaType descriptor() {\
|
||||
return {kind, sizeof(T), ECS_ALIGNOF(T), descr, NULL};\
|
||||
}\
|
||||
};\
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Use these macro's to define types.
|
||||
//// The API will automatically select the right macro's for C or C++
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
// C++
|
||||
|
||||
// Define a struct
|
||||
#define ECS_STRUCT(T, ...)\
|
||||
ECS_STRUCT_IMPL(T, #__VA_ARGS__, __VA_ARGS__)\
|
||||
ECS_META_CPP(T, EcsStructType, #__VA_ARGS__)
|
||||
|
||||
// Define an enumeration
|
||||
#define ECS_ENUM(T, ...)\
|
||||
ECS_ENUM_IMPL(T, #__VA_ARGS__, __VA_ARGS__)\
|
||||
ECS_META_CPP(T, EcsEnumType, #__VA_ARGS__)
|
||||
|
||||
// Define a bitmask
|
||||
#define ECS_BITMASK(T, ...)\
|
||||
ECS_BITMASK_IMPL(T, #__VA_ARGS__, __VA_ARGS__)\
|
||||
ECS_META_CPP(T, EcsBitmaskType, #__VA_ARGS__)
|
||||
|
||||
#else
|
||||
|
||||
// C
|
||||
|
||||
// Define a struct
|
||||
#define ECS_STRUCT(name, ...)\
|
||||
ECS_STRUCT_IMPL(name, #__VA_ARGS__, __VA_ARGS__)
|
||||
|
||||
// Define an enumeration
|
||||
#define ECS_ENUM(name, ...)\
|
||||
ECS_ENUM_IMPL(name, #__VA_ARGS__, __VA_ARGS__)
|
||||
|
||||
// Define a bitmask
|
||||
#define ECS_BITMASK(name, ...)\
|
||||
ECS_BITMASK_IMPL(name, #__VA_ARGS__, __VA_ARGS__)
|
||||
|
||||
// Define a type alias
|
||||
#define ECS_ALIAS(type, name)\
|
||||
typedef type name;\
|
||||
ECS_UNUSED \
|
||||
static EcsMetaType __##name##__ = {0, sizeof(name), ECS_ALIGNOF(name), NULL, &__##type##__};\
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Use these macro's inside types
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Define a vector
|
||||
#define ecs_vector(T) ecs_vector_t*
|
||||
|
||||
// Define a map
|
||||
#define ecs_map(K, T) ecs_map_t*
|
||||
|
||||
// Indicate that members after this should not be serialized
|
||||
#define ECS_PRIVATE
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Meta description types
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/* Explicit string type */
|
||||
typedef const char* ecs_string_t;
|
||||
|
||||
/* Explicit byte type */
|
||||
typedef uint8_t ecs_byte_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace flecs {
|
||||
using string_t = ecs_string_t;
|
||||
using byte_t = ecs_byte_t;
|
||||
|
||||
// Define a bitmask
|
||||
// In C++ trying to assign multiple flags to a variable of an enum type will
|
||||
// result in a compiler error. Use this template so that the serializer knows
|
||||
// this value is a bitmask, while also keeping the compiler happy.
|
||||
template<typename T>
|
||||
using bitmask = int32_t;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
ECS_ENUM_BOOTSTRAP( ecs_type_kind_t, {
|
||||
EcsPrimitiveType,
|
||||
EcsBitmaskType,
|
||||
EcsEnumType,
|
||||
EcsStructType,
|
||||
EcsArrayType,
|
||||
EcsVectorType,
|
||||
EcsMapType
|
||||
})
|
||||
|
||||
ECS_STRUCT( EcsMetaType, {
|
||||
ecs_type_kind_t kind;
|
||||
ecs_size_t size;
|
||||
int16_t alignment;
|
||||
const char *descriptor;
|
||||
void *alias;
|
||||
})
|
||||
|
||||
ECS_ENUM( ecs_primitive_kind_t, {
|
||||
EcsBool,
|
||||
EcsChar,
|
||||
EcsByte,
|
||||
EcsU8,
|
||||
EcsU16,
|
||||
EcsU32,
|
||||
EcsU64,
|
||||
EcsI8,
|
||||
EcsI16,
|
||||
EcsI32,
|
||||
EcsI64,
|
||||
EcsF32,
|
||||
EcsF64,
|
||||
EcsUPtr,
|
||||
EcsIPtr,
|
||||
EcsString,
|
||||
EcsEntity
|
||||
})
|
||||
|
||||
ECS_STRUCT( EcsPrimitive, {
|
||||
ecs_primitive_kind_t kind;
|
||||
})
|
||||
|
||||
// Define EcsBitmask for both C and C++. Both representations are equivalent in
|
||||
// memory, but allow for a nicer type-safe API in C++
|
||||
#if defined(__cplusplus) && !defined(FLECS_NO_CPP)
|
||||
ECS_STRUCT( EcsBitmask, {
|
||||
flecs::map<int32_t, flecs::string_t> constants;
|
||||
})
|
||||
#else
|
||||
ECS_STRUCT( EcsBitmask, {
|
||||
ecs_map(int32_t, ecs_string_t) constants;
|
||||
})
|
||||
#endif
|
||||
|
||||
// Define EcsEnum for both C and C++. Both representations are equivalent in
|
||||
// memory, but allow for a nicer type-safe API in C++
|
||||
#if defined(__cplusplus) && !defined(FLECS_NO_CPP)
|
||||
ECS_STRUCT( EcsEnum, {
|
||||
flecs::map<int32_t, flecs::string_t> constants;
|
||||
})
|
||||
#else
|
||||
ECS_STRUCT( EcsEnum, {
|
||||
ecs_map(int32_t, ecs_string_t) constants;
|
||||
})
|
||||
#endif
|
||||
|
||||
ECS_STRUCT( EcsMember, {
|
||||
char *name;
|
||||
ecs_entity_t type;
|
||||
})
|
||||
|
||||
// Define EcsStruct for both C and C++. Both representations are equivalent in
|
||||
// memory, but allow for a nicer type-safe API in C++
|
||||
#if defined(__cplusplus) && !defined(FLECS_NO_CPP)
|
||||
ECS_STRUCT( EcsStruct, {
|
||||
flecs::vector<EcsMember> members;
|
||||
bool is_partial;
|
||||
})
|
||||
#else
|
||||
ECS_STRUCT( EcsStruct, {
|
||||
ecs_vector(EcsMember) members;
|
||||
bool is_partial;
|
||||
})
|
||||
#endif
|
||||
|
||||
ECS_STRUCT( EcsArray, {
|
||||
ecs_entity_t element_type;
|
||||
int32_t count;
|
||||
})
|
||||
|
||||
ECS_STRUCT( EcsVector, {
|
||||
ecs_entity_t element_type;
|
||||
})
|
||||
|
||||
ECS_STRUCT( EcsMap, {
|
||||
ecs_entity_t key_type;
|
||||
ecs_entity_t element_type;
|
||||
})
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Type serializer
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ECS_ENUM_C( ecs_type_op_kind_t, {
|
||||
EcsOpHeader,
|
||||
EcsOpPrimitive,
|
||||
EcsOpEnum,
|
||||
EcsOpBitmask,
|
||||
EcsOpPush,
|
||||
EcsOpPop,
|
||||
EcsOpArray,
|
||||
EcsOpVector,
|
||||
EcsOpMap
|
||||
})
|
||||
|
||||
typedef ecs_vector_t ecs_type_op_vector_t;
|
||||
typedef ecs_vector_t ecs_constant_vector_t;
|
||||
|
||||
ECS_STRUCT_C( ecs_type_op_t, {
|
||||
ecs_entity_t type;
|
||||
ecs_type_op_kind_t kind;
|
||||
ecs_size_t size; /* Size of value or element type if array or vector */
|
||||
int16_t alignment; /* Alignment of value */
|
||||
int32_t count; /* Number of array elements or struct members */
|
||||
int32_t offset; /* Offset of value */
|
||||
const char *name; /* Name of value (only used for struct members) */
|
||||
|
||||
ECS_PRIVATE
|
||||
|
||||
/* Instruction-specific data */
|
||||
union {
|
||||
ecs_primitive_kind_t primitive;
|
||||
ecs_ref_t constant;
|
||||
ecs_ref_t collection;
|
||||
|
||||
struct {
|
||||
ecs_ref_t key;
|
||||
ecs_ref_t element;
|
||||
} map;
|
||||
} is;
|
||||
})
|
||||
|
||||
ECS_STRUCT_C( EcsMetaTypeSerializer, {
|
||||
ecs_vector(ecs_type_op_t) ops;
|
||||
})
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Pretty printer
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Convert value to a string. */
|
||||
FLECS_META_API
|
||||
char* ecs_ptr_to_str(
|
||||
ecs_world_t *world,
|
||||
ecs_entity_t type,
|
||||
void* ptr);
|
||||
|
||||
/** Convert value to a string. */
|
||||
FLECS_META_API
|
||||
char* ecs_entity_to_str(
|
||||
ecs_world_t *world,
|
||||
ecs_entity_t entity);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Serialization utilities
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define ECS_MAX_I8 127
|
||||
#define ECS_MIN_I8 -128
|
||||
|
||||
#define ECS_MAX_I16 32767
|
||||
#define ECS_MIN_I16 -32768
|
||||
|
||||
#define ECS_MAX_I32 2147483647
|
||||
#define ECS_MIN_I32 -2147483648
|
||||
|
||||
#define ECS_MAX_I64 9223372036854775807
|
||||
#define ECS_MIN_I64 (-9223372036854775807 - 1)
|
||||
|
||||
#define ECS_MAX_U8 255u
|
||||
#define ECS_MAX_U16 65535u
|
||||
#define ECS_MAX_U32 4294967295u
|
||||
#define ECS_MAX_U64 18446744073709551615u
|
||||
|
||||
#define ECS_MAX_I8_STR "127"
|
||||
#define ECS_MIN_I8_STR "-128"
|
||||
|
||||
#define ECS_MAX_I16_STR "32767"
|
||||
#define ECS_MIN_I16_STR "-32768"
|
||||
|
||||
#define ECS_MAX_I32_STR "2147483647"
|
||||
#define ECS_MIN_I32_STR "-2147483648"
|
||||
|
||||
#define ECS_MAX_I64_STR "9223372036854775807"
|
||||
#define ECS_MIN_I64_STR "-9223372036854775808"
|
||||
|
||||
#define ECS_MAX_U8_STR "255"
|
||||
#define ECS_MAX_U16_STR "65535"
|
||||
#define ECS_MAX_U32_STR "4294967295"
|
||||
#define ECS_MAX_U64_STR "18446744073709551615"
|
||||
|
||||
/** Escape a character */
|
||||
FLECS_META_API
|
||||
char* ecs_chresc(
|
||||
char *out,
|
||||
char in,
|
||||
char delimiter);
|
||||
|
||||
/** Parse an escaped character */
|
||||
FLECS_META_API
|
||||
const char* ecs_chrparse(
|
||||
const char *in,
|
||||
char *out);
|
||||
|
||||
/** Escape a string */
|
||||
FLECS_META_API
|
||||
ecs_size_t ecs_stresc(
|
||||
char *out,
|
||||
ecs_size_t n,
|
||||
char delimiter,
|
||||
const char *in);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Deserialization API
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define ECS_META_MAX_SCOPE_DEPTH (32) /* >32 levels of nesting is not sane */
|
||||
|
||||
typedef struct ecs_meta_scope_t {
|
||||
ecs_entity_t type;
|
||||
ecs_vector_t *ops;
|
||||
int32_t start;
|
||||
int32_t cur_op;
|
||||
int32_t cur_elem;
|
||||
int32_t count;
|
||||
void *base;
|
||||
ecs_vector_t *vector;
|
||||
bool is_collection;
|
||||
} ecs_meta_scope_t;
|
||||
|
||||
typedef struct ecs_meta_cursor_t {
|
||||
const ecs_world_t *world;
|
||||
ecs_meta_scope_t scope[ECS_META_MAX_SCOPE_DEPTH];
|
||||
int32_t depth;
|
||||
} ecs_meta_cursor_t;
|
||||
|
||||
FLECS_META_API
|
||||
ecs_meta_cursor_t ecs_meta_cursor(
|
||||
const ecs_world_t *world,
|
||||
ecs_entity_t type,
|
||||
void *base);
|
||||
|
||||
FLECS_META_API
|
||||
void* ecs_meta_get_ptr(
|
||||
ecs_meta_cursor_t *cursor);
|
||||
|
||||
FLECS_META_API
|
||||
int ecs_meta_next(
|
||||
ecs_meta_cursor_t *cursor);
|
||||
|
||||
FLECS_META_API
|
||||
int ecs_meta_move(
|
||||
ecs_meta_cursor_t *cursor,
|
||||
int32_t pos);
|
||||
|
||||
FLECS_META_API
|
||||
int ecs_meta_move_name(
|
||||
ecs_meta_cursor_t *cursor,
|
||||
const char *name);
|
||||
|
||||
FLECS_META_API
|
||||
int ecs_meta_push(
|
||||
ecs_meta_cursor_t *cursor);
|
||||
|
||||
FLECS_META_API
|
||||
int ecs_meta_pop(
|
||||
ecs_meta_cursor_t *cursor);
|
||||
|
||||
FLECS_META_API
|
||||
int ecs_meta_set_bool(
|
||||
ecs_meta_cursor_t *cursor,
|
||||
bool value);
|
||||
|
||||
FLECS_META_API
|
||||
int ecs_meta_set_char(
|
||||
ecs_meta_cursor_t *cursor,
|
||||
char value);
|
||||
|
||||
FLECS_META_API
|
||||
int ecs_meta_set_int(
|
||||
ecs_meta_cursor_t *cursor,
|
||||
int64_t value);
|
||||
|
||||
FLECS_META_API
|
||||
int ecs_meta_set_uint(
|
||||
ecs_meta_cursor_t *cursor,
|
||||
uint64_t value);
|
||||
|
||||
FLECS_META_API
|
||||
int ecs_meta_set_float(
|
||||
ecs_meta_cursor_t *cursor,
|
||||
double value);
|
||||
|
||||
FLECS_META_API
|
||||
int ecs_meta_set_string(
|
||||
ecs_meta_cursor_t *cursor,
|
||||
const char *value);
|
||||
|
||||
FLECS_META_API
|
||||
int ecs_meta_set_entity(
|
||||
ecs_meta_cursor_t *cursor,
|
||||
ecs_entity_t value);
|
||||
|
||||
FLECS_META_API
|
||||
int ecs_meta_set_null(
|
||||
ecs_meta_cursor_t *cursor);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Module implementation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct FlecsMeta {
|
||||
ECS_DECLARE_COMPONENT(EcsPrimitive);
|
||||
ECS_DECLARE_COMPONENT(EcsEnum);
|
||||
ECS_DECLARE_COMPONENT(EcsBitmask);
|
||||
ECS_DECLARE_COMPONENT(EcsStruct);
|
||||
ECS_DECLARE_COMPONENT(EcsArray);
|
||||
ECS_DECLARE_COMPONENT(EcsVector);
|
||||
ECS_DECLARE_COMPONENT(EcsMap);
|
||||
ECS_DECLARE_COMPONENT(EcsMetaType);
|
||||
ECS_DECLARE_COMPONENT(EcsMetaTypeSerializer);
|
||||
} FlecsMeta;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
FLECS_META_API ECS_COMPONENT_EXTERN(EcsPrimitive);
|
||||
FLECS_META_API ECS_COMPONENT_EXTERN(EcsEnum);
|
||||
FLECS_META_API ECS_COMPONENT_EXTERN(EcsBitmask);
|
||||
FLECS_META_API ECS_COMPONENT_EXTERN(EcsMember);
|
||||
FLECS_META_API ECS_COMPONENT_EXTERN(EcsStruct);
|
||||
FLECS_META_API ECS_COMPONENT_EXTERN(EcsArray);
|
||||
FLECS_META_API ECS_COMPONENT_EXTERN(EcsVector);
|
||||
FLECS_META_API ECS_COMPONENT_EXTERN(EcsMap);
|
||||
FLECS_META_API ECS_COMPONENT_EXTERN(EcsMetaType);
|
||||
FLECS_META_API ECS_COMPONENT_EXTERN(ecs_type_op_kind_t);
|
||||
FLECS_META_API ECS_COMPONENT_EXTERN(ecs_type_op_t);
|
||||
FLECS_META_API ECS_COMPONENT_EXTERN(EcsMetaTypeSerializer);
|
||||
|
||||
FLECS_META_API
|
||||
void FlecsMetaImport(
|
||||
ecs_world_t *world);
|
||||
|
||||
#define FlecsMetaImportHandles(handles)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Macro for inserting metadata in C application
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
FLECS_META_API
|
||||
void ecs_new_meta(
|
||||
ecs_world_t *world,
|
||||
ecs_entity_t component,
|
||||
struct EcsMetaType *meta_type);
|
||||
|
||||
#define ECS_META(world, T)\
|
||||
ECS_COMPONENT(world, T);\
|
||||
ecs_new_meta(world, ecs_entity(T), &__##T##__);
|
||||
|
||||
/** Define a meta component, store in variable outside of the current scope.
|
||||
* Use this macro in a header when defining a component identifier globally.
|
||||
* Must be used together with ECS_COMPONENT_DECLARE.
|
||||
*/
|
||||
#define ECS_META_DEFINE(world, T)\
|
||||
ECS_COMPONENT_DEFINE(world, T);\
|
||||
ecs_new_meta(world, ecs_entity(T), &__##T##__);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// C++ Module implementation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __cplusplus
|
||||
#ifndef FLECS_NO_CPP
|
||||
|
||||
namespace flecs {
|
||||
namespace components {
|
||||
|
||||
class meta {
|
||||
public:
|
||||
using Primitive = EcsPrimitive;
|
||||
using Enum = EcsEnum;
|
||||
using Bitmask = EcsBitmask;
|
||||
using Struct = EcsStruct;
|
||||
using Array = EcsArray;
|
||||
using Vector = EcsVector;
|
||||
using Type = EcsMetaType;
|
||||
using TypeSerializer = EcsMetaTypeSerializer;
|
||||
|
||||
enum TypeKind {
|
||||
PrimitiveType = EcsPrimitiveType,
|
||||
BitmaskType = EcsBitmaskType,
|
||||
EnumType = EcsEnumType,
|
||||
StructType = EcsStructType,
|
||||
ArrayType = EcsArrayType,
|
||||
VectorType = EcsVectorType,
|
||||
MapType = EcsMapType
|
||||
};
|
||||
|
||||
meta(flecs::world& world) {
|
||||
FlecsMetaImport(world);
|
||||
|
||||
world.module<flecs::components::meta>("flecs::components::meta");
|
||||
|
||||
world.component<Primitive>("EcsPrimitive");
|
||||
world.component<Enum>("EcsEnum");
|
||||
world.component<Bitmask>("EcsBitmask");
|
||||
world.component<Struct>("EcsStruct");
|
||||
world.component<Array>("EcsArray");
|
||||
world.component<Vector>("EcsVector");
|
||||
world.component<Type>("EcsMetaType");
|
||||
world.component<TypeSerializer>("EcsMetaTypeSerializer");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Functions for inserting metadata in C++ applications
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Template that injects metadata into ECS
|
||||
template <typename T>
|
||||
flecs::entity meta(flecs::world& world) {
|
||||
flecs::entity e = flecs::component<T>(world, flecs::__meta__<T>::name());
|
||||
e.set<EcsMetaType>({ flecs::__meta__<T>::descriptor() });
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Serialize values to string
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename T>
|
||||
flecs::string pretty_print(flecs::world& world, flecs::entity_t type, T& data) {
|
||||
char *str = ecs_ptr_to_str(world.c_ptr(), type, &data);
|
||||
flecs::string result = flecs::string(str);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
flecs::string pretty_print(flecs::world& world, flecs::entity type, T& data) {
|
||||
return pretty_print(world, type.id(), data);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
flecs::string pretty_print(flecs::world& world, T& data) {
|
||||
entity_t type = _::cpp_type<T>::id();
|
||||
return flecs::pretty_print(world, type, data);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline flecs::string pretty_print<flecs::entity>(flecs::world& world, flecs::entity& entity) {
|
||||
char *str = ecs_entity_to_str(world.c_ptr(), entity.id());
|
||||
flecs::string result = flecs::string(str);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // FLECS_NO_CPP
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // FLECS_META_H
|
|
@ -1,479 +0,0 @@
|
|||
#ifndef FLECS_MONITOR_IMPL
|
||||
#include "flecs_monitor.h"
|
||||
#endif
|
||||
|
||||
typedef struct WorldStats {
|
||||
ecs_world_stats_t stats;
|
||||
} WorldStats;
|
||||
|
||||
typedef struct DeltaTime {
|
||||
ecs_gauge_t frame;
|
||||
ecs_gauge_t minute;
|
||||
int32_t t_frame;
|
||||
int32_t t_minute;
|
||||
} DeltaTime;
|
||||
|
||||
typedef struct PipelineStats {
|
||||
ecs_pipeline_stats_t stats;
|
||||
} PipelineStats;
|
||||
|
||||
static ECS_COMPONENT_DECLARE(WorldStats);
|
||||
static ECS_COMPONENT_DECLARE(DeltaTime);
|
||||
static ECS_COMPONENT_DECLARE(PipelineStats);
|
||||
|
||||
static void add_float_array(
|
||||
ecs_strbuf_t *r,
|
||||
int32_t t_start,
|
||||
const float *values,
|
||||
float scale)
|
||||
{
|
||||
ecs_strbuf_list_push(r, "[", ",");
|
||||
|
||||
int32_t i;
|
||||
for (i = 0; i < ECS_STAT_WINDOW; i ++) {
|
||||
int32_t t = (t_start + i + 1) % ECS_STAT_WINDOW;
|
||||
ecs_strbuf_list_append(r, "%f", values[t] / scale);
|
||||
}
|
||||
|
||||
ecs_strbuf_list_pop(r, "]");
|
||||
}
|
||||
|
||||
static void add_gauge(
|
||||
ecs_strbuf_t *r,
|
||||
const char *name,
|
||||
int32_t t,
|
||||
const ecs_gauge_t *m,
|
||||
bool min_max,
|
||||
float scale)
|
||||
{
|
||||
ecs_strbuf_list_append(r, "\"%s\":", name);
|
||||
ecs_strbuf_list_push(r, "{", ",");
|
||||
ecs_strbuf_list_append(r, "\"avg\":");
|
||||
add_float_array(r, t, m->avg, scale);
|
||||
|
||||
if (min_max) {
|
||||
ecs_strbuf_list_append(r, "\"min\":");
|
||||
add_float_array(r, t, m->min, scale);
|
||||
ecs_strbuf_list_append(r, "\"max\":");
|
||||
add_float_array(r, t, m->max, scale);
|
||||
}
|
||||
|
||||
ecs_strbuf_list_pop(r, "}");
|
||||
}
|
||||
|
||||
static void add_counter(
|
||||
ecs_strbuf_t *r,
|
||||
const char *name,
|
||||
int32_t t,
|
||||
const ecs_counter_t *m,
|
||||
bool min_max,
|
||||
float scale)
|
||||
{
|
||||
add_gauge(r, name, t, &m->rate, min_max, scale);
|
||||
}
|
||||
|
||||
#define add_current(r, name, t, m, scale)\
|
||||
_add_current(r, name, t, (ecs_gauge_t*)m, scale)
|
||||
|
||||
static void _add_current(
|
||||
ecs_strbuf_t *r,
|
||||
const char *name,
|
||||
int32_t t,
|
||||
const ecs_gauge_t *m,
|
||||
float scale)
|
||||
{
|
||||
ecs_strbuf_list_append(r, "\"%s\":%f", name, m->avg[t] / scale);
|
||||
}
|
||||
|
||||
static void add_world_stats(
|
||||
ecs_world_t *world,
|
||||
const ecs_world_info_t *info,
|
||||
ecs_strbuf_t *r)
|
||||
{
|
||||
const WorldStats *s = ecs_get(world, ecs_typeid(WorldStats), WorldStats);
|
||||
if (!s) {
|
||||
return;
|
||||
}
|
||||
|
||||
const DeltaTime *s_dt = ecs_get(world, ecs_typeid(DeltaTime), DeltaTime);
|
||||
if (!s_dt) {
|
||||
return;
|
||||
}
|
||||
|
||||
const ecs_world_stats_t *stats = &s->stats;
|
||||
int32_t t = stats->t;
|
||||
|
||||
float df = stats->frame_count_total.rate.avg[t];
|
||||
if (df == 0.0) {
|
||||
return;
|
||||
}
|
||||
|
||||
ecs_strbuf_list_appendstr(r, "\"world\":");
|
||||
ecs_strbuf_list_push(r, "{", ",");
|
||||
|
||||
ecs_strbuf_list_appendstr(r, "\"current\":");
|
||||
ecs_strbuf_list_push(r, "{", ",");
|
||||
add_current(r, "entity_count", t, &stats->entity_count, 1.0);
|
||||
add_current(r, "component_count", t, &stats->component_count, 1.0);
|
||||
add_current(r, "query_count", t, &stats->query_count, 1.0);
|
||||
add_current(r, "system_count", t, &stats->system_count, 1.0);
|
||||
add_current(r, "table_count", t, &stats->table_count, 1.0);
|
||||
add_current(r, "empty_table_count", t, &stats->empty_table_count, 1.0);
|
||||
add_current(r, "singleton_table_count", t, &stats->singleton_table_count, 1.0);
|
||||
add_current(r, "matched_table_count", t, &stats->matched_table_count, 1.0);
|
||||
add_current(r, "matched_entity_count", t, &stats->matched_entity_count, 1.0);
|
||||
add_current(r, "systems_ran", t, &stats->systems_ran_frame, df);
|
||||
add_current(r, "new_count", t, &stats->new_count, 1.0);
|
||||
add_current(r, "bulk_new_count", t, &stats->bulk_new_count, 1.0);
|
||||
add_current(r, "delete_count", t, &stats->delete_count, 1.0);
|
||||
add_current(r, "clear_count", t, &stats->clear_count, 1.0);
|
||||
add_current(r, "add_count", t, &stats->add_count, 1.0);
|
||||
add_current(r, "remove_count", t, &stats->remove_count, 1.0);
|
||||
add_current(r, "set_count", t, &stats->set_count, 1.0);
|
||||
add_current(r, "discard_count", t, &stats->discard_count, 1.0);
|
||||
ecs_strbuf_list_pop(r, "}");
|
||||
|
||||
ecs_strbuf_list_appendstr(r, "\"history_1m\":");
|
||||
ecs_strbuf_list_push(r, "{", ",");
|
||||
add_gauge(r, "fps", t, &stats->fps, false, 1.0);
|
||||
add_gauge(r, "delta_time", t, &s_dt->minute, true, 1.0);
|
||||
add_counter(r, "frame_time_total", t, &stats->frame_time_total, false, df);
|
||||
add_counter(r, "system_time_total", t, &stats->system_time_total, false, df);
|
||||
add_counter(r, "merge_time_total", t, &stats->merge_time_total, false, df);
|
||||
add_gauge(r, "entity_count", t, &stats->entity_count, false, 1.0);
|
||||
add_gauge(r, "matched_entity_count", t, &stats->matched_entity_count, false, 1.0);
|
||||
add_gauge(r, "table_count", t, &stats->table_count, false, 1.0);
|
||||
add_gauge(r, "empty_table_count", t, &stats->empty_table_count, false, 1.0);
|
||||
add_gauge(r, "singleton_table_count", t, &stats->singleton_table_count, false, 1.0);
|
||||
add_gauge(r, "matched_table_count", t, &stats->matched_table_count, false, 1.0);
|
||||
add_counter(r, "new_count", t, &stats->new_count, false, 1.0);
|
||||
add_counter(r, "bulk_new_count", t, &stats->bulk_new_count, false, 1.0);
|
||||
add_counter(r, "delete_count", t, &stats->delete_count, false, 1.0);
|
||||
add_counter(r, "clear_count", t, &stats->clear_count, false, 1.0);
|
||||
add_counter(r, "add_count", t, &stats->add_count, false, 1.0);
|
||||
add_counter(r, "remove_count", t, &stats->remove_count, false, 1.0);
|
||||
add_counter(r, "set_count", t, &stats->set_count, false, 1.0);
|
||||
add_counter(r, "discard_count", t, &stats->discard_count, false, 1.0);
|
||||
ecs_strbuf_list_pop(r, "}");
|
||||
|
||||
ecs_strbuf_list_pop(r, "}");
|
||||
}
|
||||
|
||||
static void add_signature(
|
||||
ecs_world_t *world,
|
||||
ecs_strbuf_t *r,
|
||||
ecs_entity_t system)
|
||||
{
|
||||
const EcsQuery *q = ecs_get(world, system, EcsQuery);
|
||||
if (q) {
|
||||
ecs_strbuf_list_append(r, "\"signature\":");
|
||||
ecs_strbuf_list_push(r, "[", ",");
|
||||
|
||||
ecs_sig_t *sig = ecs_query_get_sig(q->query);
|
||||
|
||||
ecs_sig_column_t *columns =
|
||||
ecs_vector_first(sig->columns, ecs_sig_column_t);
|
||||
int32_t i, count = ecs_vector_count(sig->columns);
|
||||
|
||||
for (i = 0; i < count; i ++) {
|
||||
ecs_sig_column_t *col = &columns[i];
|
||||
|
||||
if (col->oper_kind != EcsOperOr) {
|
||||
ecs_entity_t component = col->is.component;
|
||||
|
||||
ecs_strbuf_list_next(r);
|
||||
ecs_strbuf_list_push(r, "{", ",");
|
||||
|
||||
if (component & ECS_TRAIT) {
|
||||
ecs_entity_t
|
||||
lo = ecs_entity_t_lo(component & ECS_COMPONENT_MASK),
|
||||
hi = ecs_entity_t_hi(component & ECS_COMPONENT_MASK);
|
||||
|
||||
const char
|
||||
*lo_name = ecs_get_name(world, lo),
|
||||
*hi_name = ecs_get_name(world, hi);
|
||||
|
||||
if (!hi) {
|
||||
ecs_strbuf_list_append(r, "\"name\":\"TRAIT | %s\"", lo_name);
|
||||
} else {
|
||||
if (lo_name) {
|
||||
ecs_strbuf_list_append(r, "\"name\":\"%s FOR %s\"",
|
||||
hi_name, lo_name);
|
||||
} else {
|
||||
ecs_strbuf_list_append(r, "\"name\":\"%s FOR %u\"",
|
||||
hi_name, (uint32_t)lo);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ecs_strbuf_list_append(r, "\"name\":\"%s\"",
|
||||
ecs_get_name(world, col->is.component));
|
||||
}
|
||||
|
||||
ecs_entity_t actual = ecs_get_typeid(world, component);
|
||||
if (!ecs_has(world, actual, EcsComponent)) {
|
||||
ecs_strbuf_list_append(r, "\"tag\":true");
|
||||
}
|
||||
|
||||
if (col->inout_kind == EcsIn) {
|
||||
ecs_strbuf_list_append(r, "\"const\":true");
|
||||
}
|
||||
|
||||
if (col->oper_kind == EcsOperNot) {
|
||||
ecs_strbuf_list_append(r, "\"exclude\":true");
|
||||
}
|
||||
|
||||
if (col->from_kind != EcsFromOwned &&
|
||||
col->from_kind != EcsFromAny &&
|
||||
col->from_kind != EcsFromShared &&
|
||||
col->from_kind != EcsFromEmpty)
|
||||
{
|
||||
ecs_strbuf_list_append(r, "\"ref\":true");
|
||||
}
|
||||
|
||||
if (col->from_kind == EcsFromEmpty) {
|
||||
ecs_strbuf_list_append(r, "\"empty\":true");
|
||||
}
|
||||
|
||||
if (col->from_kind == EcsFromEntity && col->source == component) {
|
||||
ecs_strbuf_list_append(r, "\"singleton\":true");
|
||||
}
|
||||
|
||||
if (col->from_kind == EcsFromParent || col->from_kind == EcsCascade) {
|
||||
ecs_strbuf_list_append(r, "\"parent\":true");
|
||||
}
|
||||
|
||||
ecs_strbuf_list_pop(r, "}");
|
||||
}
|
||||
}
|
||||
|
||||
ecs_strbuf_list_pop(r, "]");
|
||||
}
|
||||
}
|
||||
|
||||
static void add_system(
|
||||
ecs_world_t *world,
|
||||
ecs_strbuf_t *r,
|
||||
const ecs_pipeline_stats_t *stats,
|
||||
ecs_entity_t system,
|
||||
float df)
|
||||
{
|
||||
ecs_system_stats_t *s = ecs_map_get(
|
||||
stats->system_stats, ecs_system_stats_t, system);
|
||||
|
||||
ecs_strbuf_list_next(r);
|
||||
ecs_strbuf_list_push(r, "{", ",");
|
||||
ecs_strbuf_list_append(r, "\"name\":\"%s\"", ecs_get_name(world, system));
|
||||
|
||||
ecs_entity_t module = ecs_get_parent_w_entity(world, system, EcsModule);
|
||||
if (module) {
|
||||
char *module_name = ecs_get_fullpath(world, module);
|
||||
ecs_strbuf_list_append(r, "\"module\":\"%s\"", module_name);
|
||||
ecs_os_free(module_name);
|
||||
}
|
||||
|
||||
add_signature(world, r, system);
|
||||
|
||||
if (s) {
|
||||
int32_t t = s->query_stats.t;
|
||||
ecs_strbuf_list_appendstr(r, "\"current\":");
|
||||
ecs_strbuf_list_push(r, "{", ",");
|
||||
add_current(r, "matched_table_count", t, &s->query_stats.matched_table_count, 1.0);
|
||||
add_current(r, "matched_empty_table_count", t, &s->query_stats.matched_empty_table_count, 1.0);
|
||||
add_current(r, "matched_entity_count", t, &s->query_stats.matched_entity_count, 1.0);
|
||||
add_current(r, "time_spent", t, &s->time_spent, df);
|
||||
add_current(r, "invoke_count", t, &s->invoke_count, df);
|
||||
add_current(r, "active", t, &s->active, 1.0);
|
||||
add_current(r, "enabled", t, &s->enabled, 1.0);
|
||||
ecs_strbuf_list_pop(r, "}");
|
||||
|
||||
ecs_strbuf_list_appendstr(r, "\"history_1m\":");
|
||||
ecs_strbuf_list_push(r, "{", ",");
|
||||
add_gauge(r, "matched_table_count", t, &s->query_stats.matched_table_count, false, 1.0);
|
||||
add_gauge(r, "matched_empty_table_count", t, &s->query_stats.matched_empty_table_count, false, 1.0);
|
||||
add_gauge(r, "matched_entity_count", t, &s->query_stats.matched_entity_count, false, 1.0);
|
||||
add_counter(r, "time_spent", t, &s->time_spent, false, 1.0);
|
||||
add_counter(r, "invoke_count", t, &s->invoke_count, false, 1.0);
|
||||
add_gauge(r, "active", t, &s->active, false, 1.0);
|
||||
add_gauge(r, "enabled", t, &s->enabled, false, 1.0);
|
||||
ecs_strbuf_list_pop(r, "}");
|
||||
}
|
||||
|
||||
ecs_strbuf_list_pop(r, "}");
|
||||
}
|
||||
|
||||
static void add_pipeline_stats(
|
||||
ecs_world_t *world,
|
||||
const ecs_world_info_t *info,
|
||||
ecs_strbuf_t *r)
|
||||
{
|
||||
/* Get number of frames passed in interval */
|
||||
const WorldStats *ws = ecs_get(world, ecs_typeid(WorldStats), WorldStats);
|
||||
if (!ws) {
|
||||
return;
|
||||
}
|
||||
|
||||
const ecs_world_stats_t *wstats = &ws->stats;
|
||||
int32_t t = wstats->t;
|
||||
float df = wstats->frame_count_total.rate.avg[t];
|
||||
if (df == 0.0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const PipelineStats *s = ecs_get(world,
|
||||
ecs_typeid(PipelineStats), PipelineStats);
|
||||
if (!s) {
|
||||
return;
|
||||
}
|
||||
|
||||
const ecs_pipeline_stats_t *stats = &s->stats;
|
||||
int32_t i, count = ecs_vector_count(stats->systems);
|
||||
ecs_entity_t *systems = ecs_vector_first(stats->systems, ecs_entity_t);
|
||||
|
||||
ecs_strbuf_list_appendstr(r, "\"pipeline\":");
|
||||
ecs_strbuf_list_push(r, "{", ",");
|
||||
|
||||
add_current(r, "fps", t, &wstats->fps, 1.0);
|
||||
add_current(r, "frame_time_total", t, &wstats->frame_time_total, df);
|
||||
add_current(r, "system_time_total", t, &wstats->system_time_total, df);
|
||||
add_current(r, "merge_time_total", t, &wstats->merge_time_total, df);
|
||||
|
||||
ecs_strbuf_list_appendstr(r, "\"systems\":");
|
||||
ecs_strbuf_list_push(r, "[", ",");
|
||||
for (i = 0; i < count; i ++) {
|
||||
if (systems[i]) {
|
||||
add_system(world, r, stats, systems[i], df);
|
||||
} else {
|
||||
/* Merge */
|
||||
ecs_strbuf_list_appendstr(r, "null");
|
||||
}
|
||||
}
|
||||
ecs_strbuf_list_pop(r, "]");
|
||||
|
||||
ecs_strbuf_list_pop(r, "}");
|
||||
}
|
||||
|
||||
static bool endpoint_world(
|
||||
ecs_world_t *world,
|
||||
ecs_entity_t entity,
|
||||
EcsHttpEndpoint *endpoint,
|
||||
EcsHttpRequest *request,
|
||||
EcsHttpReply *reply)
|
||||
{
|
||||
ecs_strbuf_t r = ECS_STRBUF_INIT;
|
||||
|
||||
const ecs_world_info_t *info = ecs_get_world_info(world);
|
||||
|
||||
ecs_strbuf_list_push(&r, "{", ",");
|
||||
|
||||
ecs_strbuf_list_append(&r, "\"target_fps\":%f", info->target_fps);
|
||||
|
||||
char param[256];
|
||||
if (ecs_http_get_query_param(
|
||||
request->params, "world", param, sizeof(param)) &&
|
||||
!strcmp(param, "yes"))
|
||||
{
|
||||
add_world_stats(world, info, &r);
|
||||
}
|
||||
|
||||
if (ecs_http_get_query_param(
|
||||
request->params, "pipeline", param, sizeof(param)) &&
|
||||
!strcmp(param, "yes"))
|
||||
{
|
||||
add_pipeline_stats(world, info, &r);
|
||||
}
|
||||
|
||||
ecs_strbuf_list_pop(&r, "}");
|
||||
|
||||
reply->body = ecs_strbuf_get(&r);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void CollectWorldStats(ecs_iter_t *it) {
|
||||
WorldStats *s = ecs_column(it, WorldStats, 1);
|
||||
ecs_get_world_stats(it->world, &s->stats);
|
||||
}
|
||||
|
||||
static void CollectPipelineStats(ecs_iter_t *it) {
|
||||
PipelineStats *s = ecs_column(it, PipelineStats, 1);
|
||||
ecs_get_pipeline_stats(it->world, ecs_get_pipeline(it->world), &s->stats);
|
||||
}
|
||||
|
||||
static void RecordDeltaTime(ecs_iter_t *it) {
|
||||
DeltaTime *s = ecs_column(it, DeltaTime, 1);
|
||||
int32_t t_frame = s->t_frame;
|
||||
s->frame.min[t_frame] = it->delta_time;
|
||||
s->frame.avg[t_frame] = it->delta_time;
|
||||
s->frame.max[t_frame] = it->delta_time;
|
||||
s->t_frame = (t_frame + 1) % ECS_STAT_WINDOW;
|
||||
}
|
||||
|
||||
static void CollectDeltaTime(ecs_iter_t *it) {
|
||||
DeltaTime *s = ecs_column(it, DeltaTime, 1);
|
||||
ecs_gauge_reduce(&s->minute, s->t_minute, &s->frame, s->t_frame);
|
||||
s->t_minute = (s->t_minute + 1) % ECS_STAT_WINDOW;
|
||||
}
|
||||
|
||||
static void RunServer(ecs_iter_t *it) {
|
||||
ecs_world_t *world = it->world;
|
||||
EcsMonitorServer *server = ecs_column(it, EcsMonitorServer, 1);
|
||||
ecs_entity_t ecs_typeid(EcsHttpServer) = ecs_column_entity(it, 2);
|
||||
ecs_entity_t ecs_typeid(EcsHttpEndpoint) = ecs_column_entity(it, 3);
|
||||
|
||||
int32_t i;
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
ecs_entity_t e = it->entities[i];
|
||||
|
||||
ecs_set(world, e, EcsHttpServer, {.port = server[i].port});
|
||||
|
||||
/* Add endpoint to server that returns entity id of server */
|
||||
ecs_entity_t e_metrics = ecs_new_w_entity(world, ECS_CHILDOF | e);
|
||||
ecs_set(world, e_metrics, EcsName, {"e_metrics"});
|
||||
ecs_set(world, e_metrics, EcsHttpEndpoint, {
|
||||
.url = "metrics",
|
||||
.action = endpoint_world,
|
||||
.synchronous = true});
|
||||
}
|
||||
}
|
||||
|
||||
void FlecsMonitorImport(
|
||||
ecs_world_t *world)
|
||||
{
|
||||
ECS_MODULE(world, FlecsMonitor);
|
||||
|
||||
ECS_IMPORT(world, FlecsMeta);
|
||||
ECS_IMPORT(world, FlecsComponentsHttp);
|
||||
|
||||
ecs_set_name_prefix(world, "EcsMonitor");
|
||||
|
||||
ECS_META(world, EcsMonitorServer);
|
||||
|
||||
/* Private components */
|
||||
ECS_COMPONENT_DEFINE(world, WorldStats);
|
||||
ECS_COMPONENT_DEFINE(world, DeltaTime);
|
||||
ECS_COMPONENT_DEFINE(world, PipelineStats);
|
||||
|
||||
ECS_SYSTEM(world, RunServer, EcsOnSet, Server,
|
||||
:flecs.components.http.Server,
|
||||
:flecs.components.http.Endpoint);
|
||||
|
||||
ECS_SYSTEM(world, CollectWorldStats, EcsOnLoad, $WorldStats);
|
||||
ECS_SYSTEM(world, CollectPipelineStats, EcsOnLoad, $PipelineStats);
|
||||
ECS_SYSTEM(world, RecordDeltaTime, EcsOnLoad, $DeltaTime);
|
||||
ECS_SYSTEM(world, CollectDeltaTime, EcsOnLoad, $DeltaTime);
|
||||
|
||||
/* Collect statistics once per second */
|
||||
ecs_set_interval(world, CollectWorldStats, 1.0);
|
||||
ecs_set_interval(world, CollectPipelineStats, 1.0);
|
||||
ecs_set_interval(world, CollectDeltaTime, 1.0);
|
||||
|
||||
/* Initialize singleton entities for statistics components */
|
||||
ecs_set_ptr(world, ecs_typeid(WorldStats), WorldStats, NULL);
|
||||
ecs_set_ptr(world, ecs_typeid(PipelineStats), PipelineStats, NULL);
|
||||
ecs_set_ptr(world, ecs_typeid(DeltaTime), DeltaTime, NULL);
|
||||
|
||||
ECS_EXPORT_COMPONENT(EcsMonitorServer);
|
||||
|
||||
/* Enable system time monitoring */
|
||||
ecs_measure_system_time(world, true);
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
#define flecs_monitor_STATIC
|
||||
#ifndef FLECS_MONITOR_H
|
||||
#define FLECS_MONITOR_H
|
||||
|
||||
/* This generated file contains includes for project dependencies */
|
||||
/*
|
||||
)
|
||||
(.)
|
||||
.|.
|
||||
| |
|
||||
_.--| |--._
|
||||
.-'; ;`-'& ; `&.
|
||||
\ & ; & &_/
|
||||
|"""---...---"""|
|
||||
\ | | | | | | | /
|
||||
`---.|.|.|.---'
|
||||
|
||||
* This file is generated by bake.lang.c for your convenience. Headers of
|
||||
* dependencies will automatically show up in this file. Include bake_config.h
|
||||
* in your main project file. Do not edit! */
|
||||
|
||||
#ifndef FLECS_MONITOR_BAKE_CONFIG_H
|
||||
#define FLECS_MONITOR_BAKE_CONFIG_H
|
||||
|
||||
/* Headers of public dependencies */
|
||||
#include <flecs.h>
|
||||
#include <flecs_meta.h>
|
||||
#include <flecs_components_http.h>
|
||||
|
||||
/* Convenience macro for exporting symbols */
|
||||
#ifndef flecs_monitor_STATIC
|
||||
#if flecs_monitor_EXPORTS && (defined(_MSC_VER) || defined(__MINGW32__))
|
||||
#define FLECS_MONITOR_API __declspec(dllexport)
|
||||
#elif flecs_monitor_EXPORTS
|
||||
#define FLECS_MONITOR_API __attribute__((__visibility__("default")))
|
||||
#elif defined _MSC_VER
|
||||
#define FLECS_MONITOR_API __declspec(dllimport)
|
||||
#else
|
||||
#define FLECS_MONITOR_API
|
||||
#endif
|
||||
#else
|
||||
#define FLECS_MONITOR_API
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
ECS_STRUCT(EcsMonitorServer, {
|
||||
int16_t port;
|
||||
});
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct FlecsMonitor {
|
||||
ECS_DECLARE_COMPONENT(EcsMonitorServer);
|
||||
} FlecsMonitor;
|
||||
|
||||
FLECS_MONITOR_API void FlecsMonitorImport(
|
||||
ecs_world_t *world);
|
||||
|
||||
#define FlecsMonitorImportHandles(handles) \
|
||||
ECS_IMPORT_COMPONENT(handles, EcsMonitorServer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,126 +0,0 @@
|
|||
#ifndef FLECS_PLAYER_IMPL
|
||||
#include "flecs_player.h"
|
||||
#endif
|
||||
|
||||
static
|
||||
void player_start(
|
||||
ecs_world_t *world,
|
||||
void *ctx)
|
||||
{
|
||||
ecs_ref_t *ref = ctx;
|
||||
EcsPlayer *player = (EcsPlayer*)ecs_get_ref_w_entity(world, ref, 0, 0);
|
||||
ecs_assert(player != NULL, ECS_INTERNAL_ERROR, NULL);
|
||||
|
||||
player->snapshot = ecs_snapshot_take(world);
|
||||
player->time_scale = 1.0;
|
||||
|
||||
ecs_set_time_scale(world, 1.0);
|
||||
ecs_set_pipeline(world, player->play_pipeline);
|
||||
|
||||
ecs_os_free(ref);
|
||||
}
|
||||
|
||||
static
|
||||
void player_stop(
|
||||
ecs_world_t *world,
|
||||
void *ctx)
|
||||
{
|
||||
ecs_ref_t *ref = ctx;
|
||||
EcsPlayer *player = (EcsPlayer*)ecs_get_ref_w_entity(world, ref, 0, 0);
|
||||
ecs_assert(player != NULL, ECS_INTERNAL_ERROR, NULL);
|
||||
|
||||
if (player->snapshot) {
|
||||
ecs_snapshot_restore(world, player->snapshot);
|
||||
|
||||
player = (EcsPlayer*)ecs_get_ref_w_entity(world, ref, 0, 0);
|
||||
ecs_set_time_scale(world, 0);
|
||||
ecs_reset_clock(world);
|
||||
player->time_scale = 0;
|
||||
player->state = EcsPlayerStop;
|
||||
player->prev_state = EcsPlayerStop;
|
||||
}
|
||||
|
||||
player->snapshot = NULL;
|
||||
ecs_set_pipeline(world, player->stop_pipeline);
|
||||
|
||||
ecs_os_free(ref);
|
||||
}
|
||||
|
||||
static
|
||||
void EcsSetPlayer(ecs_iter_t *it) {
|
||||
ecs_world_t *world = it->world;
|
||||
|
||||
EcsPlayer *player = ecs_column(it, EcsPlayer, 1);
|
||||
ecs_entity_t ecs_typeid(EcsPlayer) = ecs_column_entity(it, 1);
|
||||
|
||||
int32_t i;
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
EcsPlayerState prev_state = player[i].prev_state;
|
||||
EcsPlayerState state = player[i].state;
|
||||
|
||||
if (prev_state != state) {
|
||||
switch(player[i].state) {
|
||||
case EcsPlayerPause:
|
||||
player[i].time_scale = 0;
|
||||
break;
|
||||
case EcsPlayerPlay:
|
||||
if (prev_state == EcsPlayerStop) {
|
||||
ecs_ref_t *ref = ecs_os_calloc(sizeof(ecs_ref_t));
|
||||
ecs_get_ref(world, ref, it->entities[i], EcsPlayer);
|
||||
ecs_run_post_frame(it->world, player_start, ref);
|
||||
} else {
|
||||
player[i].time_scale = 1.0;
|
||||
}
|
||||
break;
|
||||
case EcsPlayerStop:
|
||||
if (prev_state != EcsPlayerStop) {
|
||||
ecs_ref_t *ref = ecs_os_calloc(sizeof(ecs_ref_t));
|
||||
ecs_get_ref(world, ref, it->entities[i], EcsPlayer);
|
||||
ecs_run_post_frame(world, player_stop, ref);
|
||||
}
|
||||
player[i].time_scale = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
player[i].prev_state = state;
|
||||
|
||||
ecs_set_time_scale(it->world, player[i].time_scale);
|
||||
}
|
||||
}
|
||||
|
||||
void FlecsPlayerImport(
|
||||
ecs_world_t *world)
|
||||
{
|
||||
ECS_MODULE(world, FlecsPlayer);
|
||||
|
||||
ECS_IMPORT(world, FlecsMeta);
|
||||
|
||||
ecs_set_name_prefix(world, "Ecs");
|
||||
|
||||
ECS_META(world, EcsPlayerState);
|
||||
ECS_META(world, EcsPlayer);
|
||||
ECS_META(world, EcsTargetFps);
|
||||
|
||||
ECS_PIPELINE(world, StopPipeline,
|
||||
flecs.pipeline.PreFrame,
|
||||
flecs.pipeline.OnLoad,
|
||||
flecs.pipeline.PostLoad,
|
||||
flecs.pipeline.PreStore,
|
||||
flecs.pipeline.OnStore,
|
||||
flecs.pipeline.PostFrame);
|
||||
|
||||
ECS_SYSTEM(world, EcsSetPlayer, EcsOnSet, EcsPlayer);
|
||||
|
||||
ecs_set(world, EcsWorld, EcsPlayer, {
|
||||
.state = EcsPlayerPlay,
|
||||
.prev_state = EcsPlayerStop,
|
||||
.time_scale = 1,
|
||||
.play_pipeline = ecs_get_pipeline(world),
|
||||
.stop_pipeline = StopPipeline
|
||||
});
|
||||
|
||||
ECS_EXPORT_COMPONENT(EcsPlayer);
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
#define flecs_player_STATIC
|
||||
#ifndef FLECS_PLAYER_H
|
||||
#define FLECS_PLAYER_H
|
||||
|
||||
/* This generated file contains includes for project dependencies */
|
||||
/*
|
||||
)
|
||||
(.)
|
||||
.|.
|
||||
| |
|
||||
_.--| |--._
|
||||
.-'; ;`-'& ; `&.
|
||||
\ & ; & &_/
|
||||
|"""---...---"""|
|
||||
\ | | | | | | | /
|
||||
`---.|.|.|.---'
|
||||
|
||||
* This file is generated by bake.lang.c for your convenience. Headers of
|
||||
* dependencies will automatically show up in this file. Include bake_config.h
|
||||
* in your main project file. Do not edit! */
|
||||
|
||||
#ifndef FLECS_PLAYER_BAKE_CONFIG_H
|
||||
#define FLECS_PLAYER_BAKE_CONFIG_H
|
||||
|
||||
/* Headers of public dependencies */
|
||||
#include <flecs.h>
|
||||
#include <flecs_meta.h>
|
||||
|
||||
/* Convenience macro for exporting symbols */
|
||||
#ifndef flecs_player_STATIC
|
||||
#if flecs_player_EXPORTS && (defined(_MSC_VER) || defined(__MINGW32__))
|
||||
#define FLECS_PLAYER_API __declspec(dllexport)
|
||||
#elif flecs_player_EXPORTS
|
||||
#define FLECS_PLAYER_API __attribute__((__visibility__("default")))
|
||||
#elif defined _MSC_VER
|
||||
#define FLECS_PLAYER_API __declspec(dllimport)
|
||||
#else
|
||||
#define FLECS_PLAYER_API
|
||||
#endif
|
||||
#else
|
||||
#define FLECS_PLAYER_API
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
ECS_ENUM(EcsPlayerState, {
|
||||
EcsPlayerPlay,
|
||||
EcsPlayerPause,
|
||||
EcsPlayerStop
|
||||
});
|
||||
|
||||
ECS_STRUCT(EcsPlayer, {
|
||||
EcsPlayerState state;
|
||||
EcsPlayerState prev_state;
|
||||
float time_scale;
|
||||
ecs_entity_t play_pipeline;
|
||||
ecs_entity_t stop_pipeline;
|
||||
|
||||
ECS_PRIVATE
|
||||
ecs_snapshot_t *snapshot;
|
||||
});
|
||||
|
||||
ECS_STRUCT(EcsTargetFps, {
|
||||
float target_fps;
|
||||
});
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct FlecsPlayer {
|
||||
ECS_DECLARE_COMPONENT(EcsPlayer);
|
||||
} FlecsPlayer;
|
||||
|
||||
FLECS_PLAYER_API
|
||||
void FlecsPlayerImport(
|
||||
ecs_world_t *world);
|
||||
|
||||
#define FlecsPlayerImportHandles(handles)\
|
||||
ECS_IMPORT_COMPONENT(handles, EcsPlayer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,414 +0,0 @@
|
|||
#ifndef FLECS_REST_IMPL
|
||||
#include "flecs_rest.h"
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
static
|
||||
bool parse_filter(
|
||||
ecs_world_t *world,
|
||||
EcsHttpRequest *request,
|
||||
ecs_filter_t *filter)
|
||||
{
|
||||
char buffer[1024];
|
||||
|
||||
if (ecs_http_get_query_param(
|
||||
request->params, "include", buffer, sizeof(buffer)))
|
||||
{
|
||||
filter->include = ecs_type_from_str(world, buffer);
|
||||
filter->include_kind = EcsMatchAny;
|
||||
if (!filter->include) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (ecs_http_get_query_param(
|
||||
request->params, "exclude", buffer, sizeof(buffer)))
|
||||
{
|
||||
filter->exclude = ecs_type_from_str(world, buffer);
|
||||
if (!filter->exclude) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static
|
||||
bool parse_select(
|
||||
ecs_world_t *world,
|
||||
EcsHttpRequest *request,
|
||||
ecs_type_t *select)
|
||||
{
|
||||
char buffer[1024];
|
||||
|
||||
*select = NULL;
|
||||
|
||||
if (ecs_http_get_query_param(
|
||||
request->params, "select", buffer, sizeof(buffer)))
|
||||
{
|
||||
*select = ecs_type_from_str(world, buffer);
|
||||
if (!*select) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static
|
||||
bool parse_entity(
|
||||
ecs_world_t *world,
|
||||
EcsHttpRequest *request,
|
||||
ecs_entity_t *e_out)
|
||||
{
|
||||
ecs_entity_t e = 0;
|
||||
|
||||
if (request->relative_url && strlen(request->relative_url)) {
|
||||
/* Request scope of entity */
|
||||
const char *name = request->relative_url;
|
||||
|
||||
/* If name starts with a number, lookup by entity id */
|
||||
if (isdigit(name[0])) {
|
||||
e = atoi(name);
|
||||
} else {
|
||||
e = ecs_lookup_path_w_sep(world, 0, name, "/", NULL);
|
||||
if (!e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*e_out = e;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static
|
||||
bool endpoint_filter(
|
||||
ecs_world_t *world,
|
||||
ecs_entity_t entity,
|
||||
EcsHttpEndpoint *endpoint,
|
||||
EcsHttpRequest *request,
|
||||
EcsHttpReply *reply)
|
||||
{
|
||||
ecs_filter_t filter = { 0 };
|
||||
ecs_type_t select = NULL;
|
||||
|
||||
if (!parse_filter(world, request, &filter)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!parse_select(world, request, &select)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ecs_iter_t it = ecs_filter_iter(world, &filter);
|
||||
|
||||
reply->body = ecs_iter_to_json(world, &it, ecs_filter_next, select);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static
|
||||
bool endpoint_scope(
|
||||
ecs_world_t *world,
|
||||
ecs_entity_t entity,
|
||||
EcsHttpEndpoint *endpoint,
|
||||
EcsHttpRequest *request,
|
||||
EcsHttpReply *reply)
|
||||
{
|
||||
ecs_entity_t e = 0;
|
||||
ecs_filter_t filter = { 0 };
|
||||
ecs_type_t select = NULL;
|
||||
|
||||
if (!parse_entity(world, request, &e)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!parse_filter(world, request, &filter)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!parse_select(world, request, &select)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ecs_iter_t it = ecs_scope_iter_w_filter(world, e, &filter);
|
||||
|
||||
reply->body = ecs_iter_to_json(world, &it, ecs_scope_next, select);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static
|
||||
bool endpoint_entity_new(
|
||||
ecs_world_t *world,
|
||||
EcsHttpReply *reply,
|
||||
const char *name,
|
||||
ecs_type_t select)
|
||||
{
|
||||
ecs_entity_t e = ecs_new_from_path(world, 0, name);
|
||||
if (select) {
|
||||
ecs_add_type(world, e, select);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static
|
||||
bool endpoint_entity_add(
|
||||
ecs_world_t *world,
|
||||
EcsHttpReply *reply,
|
||||
ecs_entity_t e,
|
||||
ecs_type_t select)
|
||||
{
|
||||
if (select) {
|
||||
ecs_add_type(world, e, select);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static
|
||||
bool endpoint_entity_remove(
|
||||
ecs_world_t *world,
|
||||
EcsHttpReply *reply,
|
||||
ecs_entity_t e,
|
||||
ecs_type_t select)
|
||||
{
|
||||
if (select) {
|
||||
ecs_remove_type(world, e, select);
|
||||
} else {
|
||||
ecs_delete(world, e);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static
|
||||
bool endpoint_entity_get(
|
||||
ecs_world_t *world,
|
||||
EcsHttpReply *reply,
|
||||
ecs_entity_t e,
|
||||
ecs_type_t select)
|
||||
{
|
||||
reply->body = ecs_entity_to_json(world, e, select);
|
||||
return true;
|
||||
}
|
||||
|
||||
static
|
||||
bool endpoint_entity(
|
||||
ecs_world_t *world,
|
||||
ecs_entity_t entity,
|
||||
EcsHttpEndpoint *endpoint,
|
||||
EcsHttpRequest *request,
|
||||
EcsHttpReply *reply)
|
||||
{
|
||||
ecs_entity_t e = 0;
|
||||
ecs_type_t select = NULL;
|
||||
|
||||
if (!parse_select(world, request, &select)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (request->method == EcsHttpPost) {
|
||||
return endpoint_entity_new(world, reply, request->relative_url, select);
|
||||
}
|
||||
|
||||
if (!parse_entity(world, request, &e)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (request->method == EcsHttpGet) {
|
||||
return endpoint_entity_get(world, reply, e, select);
|
||||
} else if (request->method == EcsHttpDelete) {
|
||||
return endpoint_entity_remove(world, reply, e, select);
|
||||
} else if (request->method == EcsHttpPut) {
|
||||
return endpoint_entity_add(world, reply, e, select);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static
|
||||
void serialize_browse_info(
|
||||
ecs_world_t *world,
|
||||
ecs_entity_t parent,
|
||||
ecs_entity_t e,
|
||||
ecs_strbuf_t *str)
|
||||
{
|
||||
ecs_strbuf_list_append(str, "\"id\":%u", (int32_t)e);
|
||||
|
||||
char *type = ecs_type_to_json(world, ecs_get_type(world, e));
|
||||
ecs_strbuf_list_append(str, "\"type\":%s", type);
|
||||
|
||||
const char *name = ecs_get_name(world, e);
|
||||
if (name) {
|
||||
ecs_strbuf_list_append(str, "\"name\":\"%s\"", name);
|
||||
|
||||
char *fullpath = ecs_get_fullpath(world, e);
|
||||
ecs_strbuf_list_append(str, "\"path\":\"%s\"", fullpath);
|
||||
}
|
||||
|
||||
int32_t child_count = ecs_get_child_count(world, e);
|
||||
ecs_strbuf_list_append(str, "\"child_count\":%u", child_count);
|
||||
}
|
||||
|
||||
static
|
||||
bool endpoint_browse(
|
||||
ecs_world_t *world,
|
||||
ecs_entity_t entity,
|
||||
EcsHttpEndpoint *endpoint,
|
||||
EcsHttpRequest *request,
|
||||
EcsHttpReply *reply)
|
||||
{
|
||||
ecs_filter_t filter = { 0 };
|
||||
ecs_entity_t e;
|
||||
|
||||
if (!parse_entity(world, request, &e)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!parse_filter(world, request, &filter)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ecs_iter_t it = ecs_scope_iter_w_filter(world, e, &filter);
|
||||
ecs_strbuf_t str = ECS_STRBUF_INIT;
|
||||
|
||||
ecs_strbuf_list_push(&str, "[", ",");
|
||||
while (ecs_scope_next(&it)) {
|
||||
int32_t i;
|
||||
for (i = 0; i < it.count; i ++) {
|
||||
ecs_strbuf_list_next(&str);
|
||||
ecs_strbuf_list_push(&str, "{", ",");
|
||||
serialize_browse_info(world, e, it.entities[i], &str);
|
||||
ecs_strbuf_list_pop(&str, "}");
|
||||
}
|
||||
}
|
||||
ecs_strbuf_list_pop(&str, "]");
|
||||
|
||||
reply->body = ecs_strbuf_get(&str);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static
|
||||
bool endpoint_info(
|
||||
ecs_world_t *world,
|
||||
ecs_entity_t entity,
|
||||
EcsHttpEndpoint *endpoint,
|
||||
EcsHttpRequest *request,
|
||||
EcsHttpReply *reply)
|
||||
{
|
||||
ecs_entity_t e;
|
||||
|
||||
if (!parse_entity(world, request, &e)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ecs_strbuf_t str = ECS_STRBUF_INIT;
|
||||
ecs_strbuf_list_push(&str, "{", ",");
|
||||
serialize_browse_info(world, e, e, &str);
|
||||
ecs_strbuf_list_pop(&str, "}");
|
||||
|
||||
reply->body = ecs_strbuf_get(&str);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static
|
||||
void EcsRestSetServer(ecs_iter_t *it) {
|
||||
EcsRestServer *server_data = ecs_column(it, EcsRestServer, 1);
|
||||
ecs_entity_t ecs_typeid(EcsHttpServer) = ecs_column_entity(it, 2);
|
||||
ecs_entity_t ecs_typeid(EcsHttpEndpoint) = ecs_column_entity(it, 3);
|
||||
ecs_entity_t EcsRestInitialized = ecs_column_entity(it, 4);
|
||||
|
||||
ecs_world_t *world = it->world;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
ecs_entity_t server = it->entities[i];
|
||||
|
||||
// Get filtered list of entities
|
||||
ecs_set(world, server, EcsHttpServer, {.port = server_data[i].port});
|
||||
|
||||
if (ecs_has_entity(world, server, EcsRestInitialized)) {
|
||||
/* Don't add endpoints more than once */
|
||||
continue;
|
||||
}
|
||||
|
||||
ecs_entity_t e_filter = ecs_new_w_entity(world, ECS_CHILDOF | server);
|
||||
ecs_set(world, e_filter, EcsName, {"e_filter"});
|
||||
ecs_set(world, e_filter, EcsHttpEndpoint, {
|
||||
.url = "filter",
|
||||
.action = endpoint_filter,
|
||||
.synchronous = true,
|
||||
.ctx = NULL
|
||||
});
|
||||
|
||||
// Get filtered list of children
|
||||
ecs_entity_t e_scope = ecs_new_w_entity(world, ECS_CHILDOF | server);
|
||||
ecs_set(world, e_scope, EcsName, {"e_scope"});
|
||||
ecs_set(world, e_scope, EcsHttpEndpoint, {
|
||||
.url = "scope",
|
||||
.action = endpoint_scope,
|
||||
.synchronous = true,
|
||||
.ctx = NULL
|
||||
});
|
||||
|
||||
// Get component data for single entity
|
||||
ecs_entity_t e_entity = ecs_new_w_entity(world, ECS_CHILDOF | server);
|
||||
ecs_set(world, e_entity, EcsName, {"e_entity"});
|
||||
ecs_set(world, e_entity, EcsHttpEndpoint, {
|
||||
.url = "entity",
|
||||
.action = endpoint_entity,
|
||||
.synchronous = true,
|
||||
.ctx = NULL
|
||||
});
|
||||
|
||||
// Browse entity information
|
||||
ecs_entity_t e_browse = ecs_new_w_entity(world, ECS_CHILDOF | server);
|
||||
ecs_set(world, e_browse, EcsName, {"e_browse"});
|
||||
ecs_set(world, e_browse, EcsHttpEndpoint, {
|
||||
.url = "browse",
|
||||
.action = endpoint_browse,
|
||||
.synchronous = true,
|
||||
.ctx = NULL
|
||||
});
|
||||
|
||||
// Browse entity information for single entity
|
||||
ecs_entity_t e_info = ecs_new_w_entity(world, ECS_CHILDOF | server);
|
||||
ecs_set(world, e_info, EcsName, {"e_info"});
|
||||
ecs_set(world, e_info, EcsHttpEndpoint, {
|
||||
.url = "info",
|
||||
.action = endpoint_info,
|
||||
.synchronous = true,
|
||||
.ctx = NULL
|
||||
});
|
||||
|
||||
ecs_add_entity(world, server, EcsRestInitialized);
|
||||
}
|
||||
}
|
||||
|
||||
void FlecsRestImport(
|
||||
ecs_world_t *world)
|
||||
{
|
||||
ECS_MODULE(world, FlecsRest);
|
||||
|
||||
ecs_set_name_prefix(world, "EcsRest");
|
||||
|
||||
ECS_IMPORT(world, FlecsMeta);
|
||||
ECS_IMPORT(world, FlecsComponentsHttp);
|
||||
|
||||
ECS_META(world, EcsRestServer);
|
||||
ECS_TAG(world, EcsRestInitialized);
|
||||
|
||||
ECS_SYSTEM(world, EcsRestSetServer, EcsOnSet, Server,
|
||||
:flecs.components.http.Server,
|
||||
:flecs.components.http.Endpoint,
|
||||
:Initialized);
|
||||
|
||||
ECS_EXPORT_COMPONENT(EcsRestServer);
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
#define flecs_rest_STATIC
|
||||
#ifndef FLECS_SYSTEMS_REST_H
|
||||
#define FLECS_SYSTEMS_REST_H
|
||||
|
||||
/* This generated file contains includes for project dependencies */
|
||||
/*
|
||||
)
|
||||
(.)
|
||||
.|.
|
||||
| |
|
||||
_.--| |--._
|
||||
.-'; ;`-'& ; `&.
|
||||
\ & ; & &_/
|
||||
|"""---...---"""|
|
||||
\ | | | | | | | /
|
||||
`---.|.|.|.---'
|
||||
|
||||
* This file is generated by bake.lang.c for your convenience. Headers of
|
||||
* dependencies will automatically show up in this file. Include bake_config.h
|
||||
* in your main project file. Do not edit! */
|
||||
|
||||
#ifndef FLECS_REST_BAKE_CONFIG_H
|
||||
#define FLECS_REST_BAKE_CONFIG_H
|
||||
|
||||
/* Headers of public dependencies */
|
||||
#include <flecs.h>
|
||||
#include <flecs_components_http.h>
|
||||
#include <flecs_meta.h>
|
||||
#include <flecs_json.h>
|
||||
|
||||
/* Convenience macro for exporting symbols */
|
||||
#ifndef flecs_rest_STATIC
|
||||
#if flecs_rest_EXPORTS && (defined(_MSC_VER) || defined(__MINGW32__))
|
||||
#define FLECS_REST_API __declspec(dllexport)
|
||||
#elif flecs_rest_EXPORTS
|
||||
#define FLECS_REST_API __attribute__((__visibility__("default")))
|
||||
#elif defined _MSC_VER
|
||||
#define FLECS_REST_API __declspec(dllimport)
|
||||
#else
|
||||
#define FLECS_REST_API
|
||||
#endif
|
||||
#else
|
||||
#define FLECS_REST_API
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
ECS_STRUCT(EcsRestServer, {
|
||||
int16_t port;
|
||||
});
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct FlecsRest {
|
||||
ECS_DECLARE_COMPONENT(EcsRestServer);
|
||||
} FlecsRest;
|
||||
|
||||
FLECS_REST_API
|
||||
void FlecsRestImport(
|
||||
ecs_world_t *world);
|
||||
|
||||
#define FlecsRestImportHandles(handles) \
|
||||
ECS_IMPORT_COMPONENT(handles, EcsRestServer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#ifndef FLECS_NO_CPP
|
||||
|
||||
namespace flecs {
|
||||
|
||||
class rest : public FlecsRest {
|
||||
public:
|
||||
using Server = EcsRestServer;
|
||||
|
||||
rest(flecs::world& world) {
|
||||
FlecsRestImport(world.c_ptr());
|
||||
|
||||
flecs::module<flecs::rest>(world, "flecs::rest");
|
||||
|
||||
flecs::component<Server>(world, "Server");
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // FLECS_NO_CPP
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -1,88 +0,0 @@
|
|||
#define flecs_systems_civetweb_STATIC
|
||||
#ifndef FLECS_SYSTEMS_CIVETWEB_H
|
||||
#define FLECS_SYSTEMS_CIVETWEB_H
|
||||
|
||||
/*
|
||||
)
|
||||
(.)
|
||||
.|.
|
||||
| |
|
||||
_.--| |--._
|
||||
.-'; ;`-'& ; `&.
|
||||
\ & ; & &_/
|
||||
|"""---...---"""|
|
||||
\ | | | | | | | /
|
||||
`---.|.|.|.---'
|
||||
|
||||
* This file is generated by bake.lang.c for your convenience. Headers of
|
||||
* dependencies will automatically show up in this file. Include bake_config.h
|
||||
* in your main project file. Do not edit! */
|
||||
|
||||
#ifndef FLECS_SYSTEMS_CIVETWEB_BAKE_CONFIG_H
|
||||
#define FLECS_SYSTEMS_CIVETWEB_BAKE_CONFIG_H
|
||||
|
||||
/* Headers of public dependencies */
|
||||
#include <flecs.h>
|
||||
#include <flecs_components_http.h>
|
||||
|
||||
/* Convenience macro for exporting symbols */
|
||||
#ifndef flecs_systems_civetweb_STATIC
|
||||
#if flecs_systems_civetweb_EXPORTS && (defined(_MSC_VER) || defined(__MINGW32__))
|
||||
#define FLECS_SYSTEMS_CIVETWEB_API __declspec(dllexport)
|
||||
#elif flecs_systems_civetweb_EXPORTS
|
||||
#define FLECS_SYSTEMS_CIVETWEB_API __attribute__((__visibility__("default")))
|
||||
#elif defined _MSC_VER
|
||||
#define FLECS_SYSTEMS_CIVETWEB_API __declspec(dllimport)
|
||||
#else
|
||||
#define FLECS_SYSTEMS_CIVETWEB_API
|
||||
#endif
|
||||
#else
|
||||
#define FLECS_SYSTEMS_CIVETWEB_API
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct FlecsSystemsCivetweb {
|
||||
ECS_DECLARE_ENTITY(CivetServer);
|
||||
} FlecsSystemsCivetweb;
|
||||
|
||||
FLECS_SYSTEMS_CIVETWEB_API
|
||||
void FlecsSystemsCivetwebImport(
|
||||
ecs_world_t *world);
|
||||
|
||||
#define FlecsSystemsCivetwebImportHandles(handles)\
|
||||
ECS_IMPORT_ENTITY(handles, CivetServer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#ifndef FLECS_NO_CPP
|
||||
|
||||
namespace flecs {
|
||||
namespace systems {
|
||||
|
||||
class civetweb : public FlecsSystemsCivetweb {
|
||||
public:
|
||||
|
||||
civetweb(flecs::world& world) {
|
||||
FlecsSystemsCivetwebImport(world.c_ptr());
|
||||
|
||||
flecs::module<flecs::systems::civetweb>(
|
||||
world, "flecs::systems::civetweb");
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // FLECS_NO_CPP
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue