code: added caching function to ecs_get_mut

isolation
Vladyslav Hrytsenko 2022-09-28 20:10:40 +03:00
parent 0be5d87ede
commit 04175594d4
7 changed files with 56 additions and 26 deletions

View File

@ -2,9 +2,18 @@
#include "flecs/flecs.h" #include "flecs/flecs.h"
#include "gen/assets.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 #ifndef ecs_get_mut_if
#define ecs_get_mut_if(world, entity, component)\ #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 #endif
#define ITEMS_INVENTORY_SIZE 9 #define ITEMS_INVENTORY_SIZE 9

View File

@ -10,7 +10,7 @@ void FurnaceCook(ecs_iter_t *it) {
Item *item = item_get_data(item_slot_ent); Item *item = item_get_data(item_slot_ent);
const Fuel *fuel = 0; 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) { if (fuel->kind == d->asset) {
furnace[i].burn_time += fuel->kind; furnace[i].burn_time += fuel->kind;
item_despawn(item_slot_ent); item_despawn(item_slot_ent);
@ -27,7 +27,7 @@ void FurnaceCook(ecs_iter_t *it) {
furnace[i].processed_item = 0; furnace[i].processed_item = 0;
} else { } else {
const Ingredient *ing = 0; 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) { if (ing->producer == d->asset) {
furnace[i].processed_item = ing->product; furnace[i].processed_item = ing->product;
furnace[i].cook_time = game_time() + game_rules.furnace_cook_time; furnace[i].cook_time = game_time() + game_rules.furnace_cook_time;

View File

@ -13,9 +13,9 @@ void PickItem(ecs_iter_t *it) {
for (size_t j = 0; j < ents_count; j++) { for (size_t j = 0; j < ents_count; j++) {
Item *drop = 0; Item *drop = 0;
uint64_t ent_id = ents[j]; uint64_t ent_id = ents[j];
if ((drop = ecs_get_mut_if(it->world, ent_id, Item))) { if ((drop = ecs_get_mut_if_ex(it->world, ent_id, Item))) {
Position *p2 = ecs_get_mut(it->world, ent_id, Position); Position *p2 = ecs_get_mut_ex(it->world, ent_id, Position);
Velocity *v2 = ecs_get_mut(it->world, ent_id, Velocity); Velocity *v2 = ecs_get_mut_ex(it->world, ent_id, Velocity);
float dx = p2->x - p[i].x; float dx = p2->x - p[i].x;
float dy = p2->y - p[i].y; float dy = p2->y - p[i].y;
@ -69,7 +69,7 @@ void DropItem(ecs_iter_t *it) {
if (in[i].storage_action){ if (in[i].storage_action){
if (world_entity_valid(in[i].storage_ent)){ if (world_entity_valid(in[i].storage_ent)){
ItemContainer *ic = 0; 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; items = ic->items;
}else{ }else{
continue; continue;
@ -98,10 +98,10 @@ void DropItem(ecs_iter_t *it) {
item_show(item_slot_ent, true); 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); 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->x = in[i].mx * 800.0f;
v->y = in[i].my * 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++) { // for (size_t j = 0; j < ents_count; j++) {
// ItemDrop *drop = 0; // 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) // if (drop->kind != item->kind || (ecs_entity_t)ents[j] == it->entities[i] || drop->quantity == 0 || item->quantity == 0)
// continue; // continue;
@ -164,7 +164,7 @@ void SwapItems(ecs_iter_t *it) {
if (in[i].storage_action){ if (in[i].storage_action){
if (world_entity_valid(in[i].storage_ent)){ if (world_entity_valid(in[i].storage_ent)){
ItemContainer *ic = 0; 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; items = ic->items;
}else{ }else{
continue; continue;
@ -190,7 +190,7 @@ void SwapItems(ecs_iter_t *it) {
}else{ }else{
if (world_entity_valid(in[i].storage_ent)){ if (world_entity_valid(in[i].storage_ent)){
ItemContainer *ic = 0; 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_ent = &ic->items[in[i].swap_from];
from = item_get_data(*from_ent); from = item_get_data(*from_ent);
}else{ }else{
@ -343,8 +343,8 @@ void HarvestIntoContainers(ecs_iter_t *it) {
for (size_t j = 0; j < ents_count; j++) { for (size_t j = 0; j < ents_count; j++) {
Item *drop = 0; Item *drop = 0;
if ((drop = ecs_get_mut_if(it->world, ents[j], Item))) { if ((drop = ecs_get_mut_if_ex(it->world, ents[j], Item))) {
Position *p2 = ecs_get_mut(it->world, ents[j], Position); Position *p2 = ecs_get_mut_ex(it->world, ents[j], Position);
uint64_t ent_id = ents[j]; uint64_t ent_id = ents[j];
float dx = p2->x - p[i].x; float dx = p2->x - p[i].x;

View File

@ -10,7 +10,7 @@ void LeaveVehicle(ecs_iter_t *it) {
if (!in[i].use) continue; if (!in[i].use) continue;
Vehicle *veh = 0; 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++) { for (int k = 0; k < 4; k++) {
if (veh->seats[k] == it->entities[i]) { if (veh->seats[k] == it->entities[i]) {
veh->seats[k] = 0; veh->seats[k] = 0;
@ -50,7 +50,9 @@ void EnterVehicle(ecs_iter_t *it) {
if (has_entered_veh) break; 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); Position const* p2 = ecs_get(it->world, ents[j], Position);
float dx = p2->x - p[i].x; float dx = p2->x - p[i].x;
@ -151,7 +153,7 @@ void VehicleHandling(ecs_iter_t *it) {
// NOTE(zaklaus): Update passenger position // 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); entity_set_position(pe, p[i].x, p[i].y);
*v2 = v[i]; *v2 = v[i];
} }

View File

@ -72,7 +72,7 @@ Item *item_get_data(uint64_t ent) {
if (!world_entity_valid(ent)) return NULL; if (!world_entity_valid(ent)) return NULL;
// if (ecs_get(world_ecs(), ent, ItemAlreadyEdited)) return NULL; // if (ecs_get(world_ecs(), ent, ItemAlreadyEdited)) return NULL;
// ecs_add(world_ecs(), ent, ItemAlreadyEdited); // 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) { const Item *item_get_data_const(uint64_t ent) {

View File

@ -17,9 +17,11 @@
#define ECO2D_STREAM_ACTIONFILTER 1 #define ECO2D_STREAM_ACTIONFILTER 1
ZPL_TABLE(static, world_snapshot, world_snapshot_, entity_view); 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_data world = {0};
static world_snapshot streamer_snapshot; static world_snapshot streamer_snapshot;
static world_component_cache component_cache;
entity_view *world_build_entity_view(int64_t e) { entity_view *world_build_entity_view(int64_t e) {
entity_view *cached_ev = world_snapshot_get(&streamer_snapshot, 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; view.has_items = true;
for (int i = 0; i < ITEMS_INVENTORY_SIZE; i += 1) { 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}; 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; view.has_storage_items = true;
for (int i = 0; i < ITEMS_CONTAINER_SIZE; i += 1) { 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}; 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.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.outer_block_mapping = zpl_malloc(sizeof(block_id*)*zpl_square(world.chunk_amount));
world_snapshot_init(&streamer_snapshot, zpl_heap()); world_snapshot_init(&streamer_snapshot, zpl_heap());
world_component_cache_init(&component_cache, zpl_heap());
} }
static inline static inline
@ -303,6 +306,7 @@ int32_t world_destroy(void) {
zpl_mfree(world.block_mapping); zpl_mfree(world.block_mapping);
zpl_mfree(world.outer_block_mapping); zpl_mfree(world.outer_block_mapping);
world_snapshot_destroy(&streamer_snapshot); world_snapshot_destroy(&streamer_snapshot);
world_component_cache_destroy(&component_cache);
zpl_memset(&world, 0, sizeof(world)); zpl_memset(&world, 0, sizeof(world));
zpl_printf("[INFO] World was destroyed.\n"); zpl_printf("[INFO] World was destroyed.\n");
return WORLD_ERROR_NONE; 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 world_snapshot_clear(&streamer_snapshot);
// TODO(zaklaus): move this to zpl
{
zpl_array_clear(streamer_snapshot.hashes);
zpl_array_clear(streamer_snapshot.entries);
}
} }
} }
int32_t world_update() { int32_t world_update() {
profile (PROF_UPDATE_SYSTEMS) { profile (PROF_UPDATE_SYSTEMS) {
world_component_cache_clear(&component_cache);
ecs_progress(world.ecs, 0.0f); ecs_progress(world.ecs, 0.0f);
} }
@ -600,3 +600,21 @@ bool world_entity_valid(ecs_entity_t e) {
if (!e) return false; if (!e) return false;
return ecs_is_alive(world_ecs(), e); 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;
}

View File

@ -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); int64_t *world_chunk_query_entities(int64_t e, size_t *ents_len, int8_t radius);
bool world_entity_valid(ecs_entity_t e); bool world_entity_valid(ecs_entity_t e);
void *world_component_cached(ecs_world_t *world, ecs_entity_t entity, ecs_id_t id);