Started implementing data model friendly to ECS

This commit is contained in:
2024-10-01 03:58:15 +03:00
parent 97172fff8d
commit b2bcfd0253
3 changed files with 121 additions and 41 deletions

View File

@@ -93,7 +93,7 @@ void BuildingsData::build_building_aabbs()
void BuildingsData::update_building_transform(int index, const Transform &xform) void BuildingsData::update_building_transform(int index, const Transform &xform)
{ {
buildings[index].xform = xform; buildings_[index].xform = xform;
} }
int BuildingsData::get_closest_building(const Transform &xform) int BuildingsData::get_closest_building(const Transform &xform)
@@ -102,9 +102,9 @@ int BuildingsData::get_closest_building(const Transform &xform)
float dst = Math_INF; float dst = Math_INF;
String rkey; String rkey;
int id = -1; int id = -1;
for (i = 0; i < (int)buildings.size(); i++) { for (i = 0; i < (int)buildings_.size(); i++) {
Vector3 o = xform.origin; Vector3 o = xform.origin;
Vector3 m = buildings[i].xform.origin; Vector3 m = buildings_[i].xform.origin;
float mdst = o.distance_squared_to(m); float mdst = o.distance_squared_to(m);
if (dst > mdst) { if (dst > mdst) {
dst = mdst; dst = mdst;
@@ -127,8 +127,8 @@ int BuildingsData::get_building_by_key(const String &key) const
{ {
int i, index = -1; int i, index = -1;
uint64_t key_hash = key.hash64(); uint64_t key_hash = key.hash64();
for (i = 0; i < (int)buildings.size(); i++) { for (i = 0; i < (int)buildings_.size(); i++) {
if (key_hash == buildings[i].key_hash) { if (key_hash == buildings_[i].key_hash) {
index = i; index = i;
break; break;
} }
@@ -164,7 +164,7 @@ void BuildingsData::read_buildings_json(const String &buildings_path)
if (!entry.has("key")) // legacy if (!entry.has("key")) // legacy
entry["key"] = key; entry["key"] = key;
building::from_dict(&b, json[key]); building::from_dict(&b, json[key]);
buildings.push_back(b); buildings_.push_back(b);
e = e->next(); e = e->next();
} }
#if 0 #if 0
@@ -181,7 +181,7 @@ void BuildingsData::read_buildings_json(const String &buildings_path)
} }
#endif #endif
filter_generated_stuff(); filter_generated_stuff();
print_line("entries count: " + itos(buildings.size())); print_line("entries count: " + itos(buildings_.size()));
} }
void BuildingsData::save_buildings_json(const String &buildings_path) void BuildingsData::save_buildings_json(const String &buildings_path)
@@ -195,9 +195,9 @@ void BuildingsData::save_buildings_json(const String &buildings_path)
fa->store_string(buildings_json); fa->store_string(buildings_json);
fa->close(); fa->close();
Dictionary json; Dictionary json;
for (i = 0; i < (int)buildings.size(); i++) { for (i = 0; i < (int)buildings_.size(); i++) {
String key = buildings[i].key; String key = buildings_[i].key;
Dictionary dict = buildings[i].to_dict(); Dictionary dict = buildings_[i].to_dict();
dict["index"] = i; dict["index"] = i;
json[key] = dict; json[key] = dict;
} }
@@ -205,7 +205,7 @@ void BuildingsData::save_buildings_json(const String &buildings_path)
fa = FileAccess::open(store_path, FileAccess::WRITE); fa = FileAccess::open(store_path, FileAccess::WRITE);
fa->store_string(json_string); fa->store_string(json_string);
fa->close(); fa->close();
print_line("entries count: " + itos(buildings.size())); print_line("entries count: " + itos(buildings_.size()));
} }
void BuildingsData::building::from_dict(building *b, const Dictionary &dict) void BuildingsData::building::from_dict(building *b, const Dictionary &dict)
@@ -286,11 +286,11 @@ void BuildingsData::filter_generated_stuff()
ERR_FAIL_COND_MSG(result != OK, "Failed to load config"); ERR_FAIL_COND_MSG(result != OK, "Failed to load config");
Array gen_prefixes = config.get_value("lines", "gen_prefixes"); Array gen_prefixes = config.get_value("lines", "gen_prefixes");
int i, j; int i, j;
for (i = 0; i < (int)buildings.size(); i++) { for (i = 0; i < (int)buildings_.size(); i++) {
for (j = 0; j < (int)gen_prefixes.size(); j++) { for (j = 0; j < (int)gen_prefixes.size(); j++) {
String prefix = gen_prefixes[j]; String prefix = gen_prefixes[j];
if (buildings[i].id.begins_with(prefix)) { if (buildings_[i].id.begins_with(prefix)) {
buildings[i].generated = true; buildings_[i].generated = true;
break; break;
} }
} }
@@ -325,7 +325,7 @@ void BuildingsData::checkpoint()
{ {
struct checkpoint_data cp; struct checkpoint_data cp;
cp.building_data = building_data; cp.building_data = building_data;
cp.buildings = buildings; cp.buildings = buildings_;
undo_log.push_back(cp); undo_log.push_back(cp);
while ((int)undo_log.size() > undo_log_size) while ((int)undo_log.size() > undo_log_size)
undo_log.erase(undo_log.begin()); undo_log.erase(undo_log.begin());
@@ -334,7 +334,7 @@ void BuildingsData::undo()
{ {
struct checkpoint_data cp = *undo_log.end(); struct checkpoint_data cp = *undo_log.end();
building_data = cp.building_data; building_data = cp.building_data;
buildings = cp.buildings; buildings_ = cp.buildings;
} }
void BuildingsData::fill_door_locations() void BuildingsData::fill_door_locations()
@@ -529,7 +529,6 @@ int BuildingsData::scene_get_item_count(const String &key) const
List<String> BuildingsData::scene_get_items(const String &key) const List<String> BuildingsData::scene_get_items(const String &key) const
{ {
List<String> ret; List<String> ret;
int i;
flecs::entity e = ecs.lookup(key.ascii().ptr()); flecs::entity e = ecs.lookup(key.ascii().ptr());
if (!e.is_valid()) if (!e.is_valid())
return List<String>(); return List<String>();
@@ -606,11 +605,9 @@ void BuildingsData::item_nodes_delete_node(const String &key)
void BuildingsData::item_nodes_item_removed(const String &key) void BuildingsData::item_nodes_item_removed(const String &key)
{ {
int i;
flecs::query_builder<const CBuildingInstance> qb = flecs::query_builder<const CBuildingInstance> qb =
ecs.query_builder<const CBuildingInstance>(); ecs.query_builder<const CBuildingInstance>();
flecs::query<const CBuildingInstance> q = qb.build(); flecs::query<const CBuildingInstance> q = qb.build();
Node *ret;
uint64_t key_hash = key.hash64(); uint64_t key_hash = key.hash64();
flecs::entity e = q.find([key_hash](const CBuildingInstance &bi) { flecs::entity e = q.find([key_hash](const CBuildingInstance &bi) {
return bi.key.hash64() == key_hash; return bi.key.hash64() == key_hash;
@@ -626,7 +623,7 @@ void BuildingsData::item_nodes_item_removed(const String &key)
String BuildingsData::item_nodes_get_key(int item) const String BuildingsData::item_nodes_get_key(int item) const
{ {
return buildings[item].key; return buildings_[item].key;
} }
Node *BuildingsData::item_nodes_get_node(const String &key) const Node *BuildingsData::item_nodes_get_node(const String &key) const
@@ -634,7 +631,6 @@ Node *BuildingsData::item_nodes_get_node(const String &key) const
flecs::query_builder<const CBuildingInstance> qb = flecs::query_builder<const CBuildingInstance> qb =
ecs.query_builder<const CBuildingInstance>(); ecs.query_builder<const CBuildingInstance>();
flecs::query<const CBuildingInstance> q = qb.build(); flecs::query<const CBuildingInstance> q = qb.build();
Node *ret;
uint64_t key_hash = key.hash64(); uint64_t key_hash = key.hash64();
flecs::entity e = q.find([key_hash](const CBuildingInstance &bi) { flecs::entity e = q.find([key_hash](const CBuildingInstance &bi) {
return bi.key.hash64() == key_hash; return bi.key.hash64() == key_hash;
@@ -685,34 +681,44 @@ void BuildingsData::scene_update()
int BuildingsData::get_building_count() const int BuildingsData::get_building_count() const
{ {
return buildings.size(); return buildings_.size();
} }
const struct BuildingsData::building & const struct BuildingsData::building &
BuildingsData::get_building(int index) const BuildingsData::get_building(int index) const
{ {
assert(index >= 0 && index < buildings.size()); assert(index >= 0 && index < get_building_count());
return buildings[index]; const String key = item_nodes_get_key(index);
return get_building(key);
} }
const struct BuildingsData::building & const struct BuildingsData::building &
BuildingsData::get_building(const String &building_key) const BuildingsData::get_building(const String &building_key) const
{ {
int index = get_building_by_key(building_key); int index = get_building_by_key(building_key);
assert(index >= 0 && index < buildings.size()); assert(index >= 0 && index < get_building_count());
return buildings[index]; return buildings_[index];
} }
struct BuildingsData::building &BuildingsData::get_building(int index) struct BuildingsData::building &BuildingsData::get_building(int index)
{ {
assert(index >= 0 && index < buildings.size()); assert(index >= 0 && index < get_building_count());
return buildings[index]; const String key = item_nodes_get_key(index);
return get_building(key);
}
struct BuildingsData::building &
BuildingsData::get_building(const String &building_key)
{
int index = get_building_by_key(building_key);
assert(index >= 0 && index < get_building_count());
return buildings_[index];
} }
struct BuildingsData::building *BuildingsData::get_building_ptr(int index) struct BuildingsData::building *BuildingsData::get_building_ptr(int index)
{ {
assert(index >= 0 && index < buildings.size()); assert(index >= 0 && index < get_building_count());
return &buildings[index]; return &buildings_[index];
} }
int BuildingsData::create_building(const Dictionary &dict) int BuildingsData::create_building(const Dictionary &dict)
@@ -724,11 +730,42 @@ int BuildingsData::create_building(const Dictionary &dict)
int BuildingsData::create_building(const struct building &building) int BuildingsData::create_building(const struct building &building)
{ {
int index = buildings.size(); int index = get_building_count();
buildings.push_back(building); buildings_.push_back(building);
return index; return index;
} }
void BuildingsData::for_each_building(callme &c)
{
List<String> keys;
get_building_keys_list(&keys);
List<String>::Element *e = keys.front();
while (e) {
c(e->get());
e = e->next();
}
}
void BuildingsData::for_each_building(void (*func)(const String &key,
void *data),
void *data)
{
List<String> keys;
get_building_keys_list(&keys);
List<String>::Element *e = keys.front();
while (e) {
func(e->get(), data);
e = e->next();
}
}
void BuildingsData::get_building_keys_list(List<String> *keys)
{
int i;
for (i = 0; i < get_building_count(); i++)
keys->push_back(buildings_[i].key);
}
int BuildingsData::create_building(const building *building) int BuildingsData::create_building(const building *building)
{ {
assert(building); assert(building);
@@ -737,7 +774,7 @@ int BuildingsData::create_building(const building *building)
bool BuildingsData::destroy_building(int index) bool BuildingsData::destroy_building(int index)
{ {
assert(index >= 0 && index < buildings.size()); assert(index >= 0 && index < get_building_count());
buildings.erase(buildings.begin() + index); buildings_.erase(buildings_.begin() + index);
return true; return true;
} }

View File

@@ -59,14 +59,58 @@ public:
HashMap<String, AABB> building_aabbs; HashMap<String, AABB> building_aabbs;
/* Data for each building in a world */ /* Data for each building in a world */
private: private:
std::vector<struct building> buildings; std::vector<struct building> buildings_;
struct building *get_building_ptr(int index);
public: public:
int get_building_count() const;
const struct building &get_building(int index) const; const struct building &get_building(int index) const;
const struct building &get_building(const String &building_key) const;
struct building &get_building(int index); struct building &get_building(int index);
struct building *get_building_ptr(int index); struct building &get_building(const String &building_key);
const struct building &get_building(const String &building_key) const;
struct callme {
class H {};
H *obj;
void (H::*method)(const String &key, void *data);
void *data;
callme(H *obj, void (H::*method)(const String &key, void *data),
void *data)
: obj(obj)
, method(method)
, data(data)
{
}
void operator()(const String &key)
{
(obj->*method)(key, data);
}
};
template <class T>
void set_foreach_method(T *obj,
void (T::*method)(const String &key,
void *data),
struct callme &c)
{
c.obj = reinterpret_cast<callme::H *>(obj);
c.method = reinterpret_cast<void (callme::H::*)(const String &,
void *)>(obj);
}
void for_each_building(struct callme &c);
template <typename Func> void for_each_building(Func &&func, void *data)
{
List<String> keys;
get_building_keys_list(&keys);
List<String>::Element *e = keys.front();
while (e) {
func(e->get(), data);
e = e->next();
}
}
void for_each_building(void (*func)(const String &key, void *data),
void *data);
void get_building_keys_list(List<String> *keys);
int get_building_count() const;
int create_building(const Dictionary &dict); int create_building(const Dictionary &dict);
int create_building(const struct building &building); int create_building(const struct building &building);
int create_building(const struct building *building); int create_building(const struct building *building);

View File

@@ -223,7 +223,6 @@ void StreamWorld::update_items()
void StreamWorld::remove_building(int index) void StreamWorld::remove_building(int index)
{ {
// TODO: implement // TODO: implement
int i;
unload_building(index); unload_building(index);
String key = data()->item_nodes_get_key(index); String key = data()->item_nodes_get_key(index);
data()->destroy_building(index); data()->destroy_building(index);
@@ -341,7 +340,7 @@ void StreamWorld::run_command(const String &command, const Array &args)
std::vector<int> erased_indices; std::vector<int> erased_indices;
erased_indices.reserve(data()->get_building_count()); erased_indices.reserve(data()->get_building_count());
String prefix = args[0]; String prefix = args[0];
int i, j; int i;
for (i = 0; i < (int)data()->get_building_count(); i++) { for (i = 0; i < (int)data()->get_building_count(); i++) {
if (data()->get_building(i).id.begins_with(prefix)) if (data()->get_building(i).id.begins_with(prefix))
erased_indices.push_back(i); erased_indices.push_back(i);
@@ -465,7 +464,7 @@ void StreamWorld::remove_generated_stuff()
{ {
std::vector<int> erased_indices; std::vector<int> erased_indices;
erased_indices.reserve(data()->get_building_count()); erased_indices.reserve(data()->get_building_count());
int i, j; int i;
for (i = 0; i < data()->get_building_count(); i++) { for (i = 0; i < data()->get_building_count(); i++) {
if (data()->get_building(i).generated) if (data()->get_building(i).generated)
erased_indices.push_back(i); erased_indices.push_back(i);