From 04175594d4ccc56dc6986d270a289bf02cc6ba12 Mon Sep 17 00:00:00 2001 From: Vladyslav Hrytsenko Date: Wed, 28 Sep 2022 20:10:40 +0300 Subject: [PATCH] code: added caching function to ecs_get_mut --- code/foundation/src/ecs/components.h | 11 +++++- .../src/ecs/modules/system_furnace.c | 4 +-- .../foundation/src/ecs/modules/system_items.c | 22 ++++++------ .../src/ecs/modules/system_vehicle.c | 8 +++-- code/foundation/src/ents/items.c | 2 +- code/foundation/src/world/world.c | 34 ++++++++++++++----- code/foundation/src/world/world.h | 1 + 7 files changed, 56 insertions(+), 26 deletions(-) diff --git a/code/foundation/src/ecs/components.h b/code/foundation/src/ecs/components.h index 120fdf4..dd11c67 100644 --- a/code/foundation/src/ecs/components.h +++ b/code/foundation/src/ecs/components.h @@ -2,9 +2,18 @@ #include "flecs/flecs.h" #include "gen/assets.h" +#define ecs_get_mut_ex(world, entity, T) \ + (ECS_CAST(T*, world_component_cached(world, entity, ecs_id(T)))) + +#define ecs_get_if(world, entity, T) \ + (world_entity_valid(entity) ? ecs_get(world, entity, T) : NULL) + +#define ecs_get_mut_if_ex(world, entity, component) \ + (ecs_get_if(world, entity, component) ? ecs_get_mut_ex(world, entity, component) : NULL) + #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) + (ecs_get(world, entity, component) ? ecs_get_mut(world, entity, component) : NULL) #endif #define ITEMS_INVENTORY_SIZE 9 diff --git a/code/foundation/src/ecs/modules/system_furnace.c b/code/foundation/src/ecs/modules/system_furnace.c index bc8f8cf..ac9eb2c 100644 --- a/code/foundation/src/ecs/modules/system_furnace.c +++ b/code/foundation/src/ecs/modules/system_furnace.c @@ -10,7 +10,7 @@ void FurnaceCook(ecs_iter_t *it) { Item *item = item_get_data(item_slot_ent); const Fuel *fuel = 0; - if ((fuel = ecs_get(it->world, item_slot_ent, Fuel))) { + if ((fuel = ecs_get_if(it->world, item_slot_ent, Fuel))) { if (fuel->kind == d->asset) { furnace[i].burn_time += fuel->kind; item_despawn(item_slot_ent); @@ -27,7 +27,7 @@ void FurnaceCook(ecs_iter_t *it) { furnace[i].processed_item = 0; } else { const Ingredient *ing = 0; - if ((ing = ecs_get(it->world, item_slot_ent, Ingredient))) { + if ((ing = ecs_get_if(it->world, item_slot_ent, Ingredient))) { if (ing->producer == d->asset) { furnace[i].processed_item = ing->product; furnace[i].cook_time = game_time() + game_rules.furnace_cook_time; diff --git a/code/foundation/src/ecs/modules/system_items.c b/code/foundation/src/ecs/modules/system_items.c index 3a3fde1..e67ea95 100644 --- a/code/foundation/src/ecs/modules/system_items.c +++ b/code/foundation/src/ecs/modules/system_items.c @@ -13,9 +13,9 @@ void PickItem(ecs_iter_t *it) { for (size_t j = 0; j < ents_count; j++) { Item *drop = 0; uint64_t ent_id = ents[j]; - if ((drop = ecs_get_mut_if(it->world, ent_id, Item))) { - Position *p2 = ecs_get_mut(it->world, ent_id, Position); - Velocity *v2 = ecs_get_mut(it->world, ent_id, Velocity); + if ((drop = ecs_get_mut_if_ex(it->world, ent_id, Item))) { + Position *p2 = ecs_get_mut_ex(it->world, ent_id, Position); + Velocity *v2 = ecs_get_mut_ex(it->world, ent_id, Velocity); float dx = p2->x - p[i].x; float dy = p2->y - p[i].y; @@ -69,7 +69,7 @@ void DropItem(ecs_iter_t *it) { if (in[i].storage_action){ if (world_entity_valid(in[i].storage_ent)){ ItemContainer *ic = 0; - if ((ic = ecs_get_mut_if(it->world, in[i].storage_ent, ItemContainer))){ + if ((ic = ecs_get_mut_if_ex(it->world, in[i].storage_ent, ItemContainer))){ items = ic->items; }else{ continue; @@ -98,10 +98,10 @@ void DropItem(ecs_iter_t *it) { item_show(item_slot_ent, true); - Position *ipos = ecs_get_mut(it->world, item_slot_ent, Position); + Position *ipos = ecs_get_mut_ex(it->world, item_slot_ent, Position); entity_set_position(item_slot_ent, p[i].x, p[i].y); - Velocity *v = ecs_get_mut(it->world, item_slot_ent, Velocity); + Velocity *v = ecs_get_mut_ex(it->world, item_slot_ent, Velocity); v->x = in[i].mx * 800.0f; v->y = in[i].my * 800.0f; @@ -133,7 +133,7 @@ void DropItem(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))) { +// if ((drop = ecs_get_mut_if_ex(it->world, ents[j], ItemDrop))) { // if (drop->kind != item->kind || (ecs_entity_t)ents[j] == it->entities[i] || drop->quantity == 0 || item->quantity == 0) // continue; @@ -164,7 +164,7 @@ void SwapItems(ecs_iter_t *it) { if (in[i].storage_action){ if (world_entity_valid(in[i].storage_ent)){ ItemContainer *ic = 0; - if ((ic = ecs_get_mut_if(it->world, in[i].storage_ent, ItemContainer))){ + if ((ic = ecs_get_mut_if_ex(it->world, in[i].storage_ent, ItemContainer))){ items = ic->items; }else{ continue; @@ -190,7 +190,7 @@ void SwapItems(ecs_iter_t *it) { }else{ if (world_entity_valid(in[i].storage_ent)){ ItemContainer *ic = 0; - if ((ic = ecs_get_mut_if(it->world, in[i].storage_ent, ItemContainer))){ + if ((ic = ecs_get_mut_if_ex(it->world, in[i].storage_ent, ItemContainer))){ from_ent = &ic->items[in[i].swap_from]; from = item_get_data(*from_ent); }else{ @@ -343,8 +343,8 @@ void HarvestIntoContainers(ecs_iter_t *it) { for (size_t j = 0; j < ents_count; j++) { Item *drop = 0; - if ((drop = ecs_get_mut_if(it->world, ents[j], Item))) { - Position *p2 = ecs_get_mut(it->world, ents[j], Position); + if ((drop = ecs_get_mut_if_ex(it->world, ents[j], Item))) { + Position *p2 = ecs_get_mut_ex(it->world, ents[j], Position); uint64_t ent_id = ents[j]; float dx = p2->x - p[i].x; diff --git a/code/foundation/src/ecs/modules/system_vehicle.c b/code/foundation/src/ecs/modules/system_vehicle.c index afe5fce..6833958 100644 --- a/code/foundation/src/ecs/modules/system_vehicle.c +++ b/code/foundation/src/ecs/modules/system_vehicle.c @@ -10,7 +10,7 @@ void LeaveVehicle(ecs_iter_t *it) { if (!in[i].use) continue; Vehicle *veh = 0; - if ((veh = ecs_get_mut_if(it->world, vehp->veh, Vehicle))) { + if ((veh = ecs_get_mut_if_ex(it->world, vehp->veh, Vehicle))) { for (int k = 0; k < 4; k++) { if (veh->seats[k] == it->entities[i]) { veh->seats[k] = 0; @@ -50,7 +50,9 @@ void EnterVehicle(ecs_iter_t *it) { if (has_entered_veh) break; - if ((veh = ecs_get_mut_if(it->world, ents[j], Vehicle))) { + veh = ecs_get_mut_if_ex(it->world, ents[j], Vehicle); + + if ((veh = ecs_get_mut_if_ex(it->world, ents[j], Vehicle))) { Position const* p2 = ecs_get(it->world, ents[j], Position); float dx = p2->x - p[i].x; @@ -151,7 +153,7 @@ void VehicleHandling(ecs_iter_t *it) { // NOTE(zaklaus): Update passenger position { - Velocity *v2 = ecs_get_mut(it->world, pe, Velocity); + Velocity *v2 = ecs_get_mut_ex(it->world, pe, Velocity); entity_set_position(pe, p[i].x, p[i].y); *v2 = v[i]; } diff --git a/code/foundation/src/ents/items.c b/code/foundation/src/ents/items.c index b202714..81a76eb 100644 --- a/code/foundation/src/ents/items.c +++ b/code/foundation/src/ents/items.c @@ -72,7 +72,7 @@ Item *item_get_data(uint64_t ent) { if (!world_entity_valid(ent)) return NULL; // if (ecs_get(world_ecs(), ent, ItemAlreadyEdited)) return NULL; // ecs_add(world_ecs(), ent, ItemAlreadyEdited); - return ecs_get_mut_if(world_ecs(), ent, Item); + return ecs_get_mut_if_ex(world_ecs(), ent, Item); } const Item *item_get_data_const(uint64_t ent) { diff --git a/code/foundation/src/world/world.c b/code/foundation/src/world/world.c index f20bae5..a50d7b3 100644 --- a/code/foundation/src/world/world.c +++ b/code/foundation/src/world/world.c @@ -17,9 +17,11 @@ #define ECO2D_STREAM_ACTIONFILTER 1 ZPL_TABLE(static, world_snapshot, world_snapshot_, entity_view); +ZPL_TABLE(static, world_component_cache, world_component_cache_, zpl_uintptr); // TODO(inlife): not use for long static world_data world = {0}; static world_snapshot streamer_snapshot; +static world_component_cache component_cache; entity_view *world_build_entity_view(int64_t e) { entity_view *cached_ev = world_snapshot_get(&streamer_snapshot, e); @@ -74,7 +76,7 @@ entity_view *world_build_entity_view(int64_t e) { view.has_items = true; for (int i = 0; i < ITEMS_INVENTORY_SIZE; i += 1) { - const Item *it = ecs_get(world_ecs(), inv->items[i], Item); + const Item *it = ecs_get_if(world_ecs(), inv->items[i], Item); view.items[i] = it ? *it : (Item){0}; } @@ -90,7 +92,7 @@ entity_view *world_build_entity_view(int64_t e) { view.has_storage_items = true; for (int i = 0; i < ITEMS_CONTAINER_SIZE; i += 1) { - const Item *it = ecs_get(world_ecs(), ic->items[i], Item); + const Item *it = ecs_get_if(world_ecs(), ic->items[i], Item); view.storage_items[i] = it ? *it : (Item){0}; } @@ -247,6 +249,7 @@ void world_init_mapping(void) { world.block_mapping = zpl_malloc(sizeof(block_id*)*zpl_square(world.chunk_amount)); world.outer_block_mapping = zpl_malloc(sizeof(block_id*)*zpl_square(world.chunk_amount)); world_snapshot_init(&streamer_snapshot, zpl_heap()); + world_component_cache_init(&component_cache, zpl_heap()); } static inline @@ -303,6 +306,7 @@ int32_t world_destroy(void) { zpl_mfree(world.block_mapping); zpl_mfree(world.outer_block_mapping); world_snapshot_destroy(&streamer_snapshot); + world_component_cache_destroy(&component_cache); zpl_memset(&world, 0, sizeof(world)); zpl_printf("[INFO] World was destroyed.\n"); return WORLD_ERROR_NONE; @@ -340,17 +344,13 @@ static void world_tracker_update(uint8_t ticker, float freq, uint8_t radius) { } } - // NOTE(zaklaus): clear out our streaming snapshot - // TODO(zaklaus): move this to zpl - { - zpl_array_clear(streamer_snapshot.hashes); - zpl_array_clear(streamer_snapshot.entries); - } + world_snapshot_clear(&streamer_snapshot); } } int32_t world_update() { profile (PROF_UPDATE_SYSTEMS) { + world_component_cache_clear(&component_cache); ecs_progress(world.ecs, 0.0f); } @@ -600,3 +600,21 @@ bool world_entity_valid(ecs_entity_t e) { if (!e) return false; return ecs_is_alive(world_ecs(), e); } + +void * world_component_cached(ecs_world_t *world, ecs_entity_t entity, ecs_id_t id) { + // return ecs_get_mut_id(world, entity, id); + + static char buffer[256] = {0}; + zpl_snprintf(buffer, 256, "%llu_%llu", entity, id); + + uint64_t uid = zpl_crc64(buffer, zpl_strlen(buffer)); + zpl_uintptr *value = world_component_cache_get(&component_cache, uid); + + if (!value) { + void *the_value = ecs_get_mut_id(world, entity, id); + world_component_cache_set(&component_cache, uid, (zpl_uintptr)the_value); + value = world_component_cache_get(&component_cache, uid); + } + + return (void *)*value; +} diff --git a/code/foundation/src/world/world.h b/code/foundation/src/world/world.h index 3d714fa..8b80865 100644 --- a/code/foundation/src/world/world.h +++ b/code/foundation/src/world/world.h @@ -114,3 +114,4 @@ int64_t *world_chunk_fetch_entities_realpos(float x, float y, size_t *ents_len); int64_t *world_chunk_query_entities(int64_t e, size_t *ents_len, int8_t radius); bool world_entity_valid(ecs_entity_t e); +void *world_component_cached(ecs_world_t *world, ecs_entity_t entity, ecs_id_t id);