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)
{
buildings[index].xform = xform;
buildings_[index].xform = 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;
String rkey;
int id = -1;
for (i = 0; i < (int)buildings.size(); i++) {
for (i = 0; i < (int)buildings_.size(); i++) {
Vector3 o = xform.origin;
Vector3 m = buildings[i].xform.origin;
Vector3 m = buildings_[i].xform.origin;
float mdst = o.distance_squared_to(m);
if (dst > mdst) {
dst = mdst;
@@ -127,8 +127,8 @@ int BuildingsData::get_building_by_key(const String &key) const
{
int i, index = -1;
uint64_t key_hash = key.hash64();
for (i = 0; i < (int)buildings.size(); i++) {
if (key_hash == buildings[i].key_hash) {
for (i = 0; i < (int)buildings_.size(); i++) {
if (key_hash == buildings_[i].key_hash) {
index = i;
break;
}
@@ -164,7 +164,7 @@ void BuildingsData::read_buildings_json(const String &buildings_path)
if (!entry.has("key")) // legacy
entry["key"] = key;
building::from_dict(&b, json[key]);
buildings.push_back(b);
buildings_.push_back(b);
e = e->next();
}
#if 0
@@ -181,7 +181,7 @@ void BuildingsData::read_buildings_json(const String &buildings_path)
}
#endif
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)
@@ -195,9 +195,9 @@ void BuildingsData::save_buildings_json(const String &buildings_path)
fa->store_string(buildings_json);
fa->close();
Dictionary json;
for (i = 0; i < (int)buildings.size(); i++) {
String key = buildings[i].key;
Dictionary dict = buildings[i].to_dict();
for (i = 0; i < (int)buildings_.size(); i++) {
String key = buildings_[i].key;
Dictionary dict = buildings_[i].to_dict();
dict["index"] = i;
json[key] = dict;
}
@@ -205,7 +205,7 @@ void BuildingsData::save_buildings_json(const String &buildings_path)
fa = FileAccess::open(store_path, FileAccess::WRITE);
fa->store_string(json_string);
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)
@@ -286,11 +286,11 @@ void BuildingsData::filter_generated_stuff()
ERR_FAIL_COND_MSG(result != OK, "Failed to load config");
Array gen_prefixes = config.get_value("lines", "gen_prefixes");
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++) {
String prefix = gen_prefixes[j];
if (buildings[i].id.begins_with(prefix)) {
buildings[i].generated = true;
if (buildings_[i].id.begins_with(prefix)) {
buildings_[i].generated = true;
break;
}
}
@@ -325,7 +325,7 @@ void BuildingsData::checkpoint()
{
struct checkpoint_data cp;
cp.building_data = building_data;
cp.buildings = buildings;
cp.buildings = buildings_;
undo_log.push_back(cp);
while ((int)undo_log.size() > undo_log_size)
undo_log.erase(undo_log.begin());
@@ -334,7 +334,7 @@ void BuildingsData::undo()
{
struct checkpoint_data cp = *undo_log.end();
building_data = cp.building_data;
buildings = cp.buildings;
buildings_ = cp.buildings;
}
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> ret;
int i;
flecs::entity e = ecs.lookup(key.ascii().ptr());
if (!e.is_valid())
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)
{
int i;
flecs::query_builder<const CBuildingInstance> qb =
ecs.query_builder<const CBuildingInstance>();
flecs::query<const CBuildingInstance> q = qb.build();
Node *ret;
uint64_t key_hash = key.hash64();
flecs::entity e = q.find([key_hash](const CBuildingInstance &bi) {
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
{
return buildings[item].key;
return buildings_[item].key;
}
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 =
ecs.query_builder<const CBuildingInstance>();
flecs::query<const CBuildingInstance> q = qb.build();
Node *ret;
uint64_t key_hash = key.hash64();
flecs::entity e = q.find([key_hash](const CBuildingInstance &bi) {
return bi.key.hash64() == key_hash;
@@ -685,34 +681,44 @@ void BuildingsData::scene_update()
int BuildingsData::get_building_count() const
{
return buildings.size();
return buildings_.size();
}
const struct BuildingsData::building &
BuildingsData::get_building(int index) const
{
assert(index >= 0 && index < buildings.size());
return buildings[index];
assert(index >= 0 && index < get_building_count());
const String key = item_nodes_get_key(index);
return get_building(key);
}
const struct BuildingsData::building &
BuildingsData::get_building(const String &building_key) const
{
int index = get_building_by_key(building_key);
assert(index >= 0 && index < buildings.size());
return buildings[index];
assert(index >= 0 && index < get_building_count());
return buildings_[index];
}
struct BuildingsData::building &BuildingsData::get_building(int index)
{
assert(index >= 0 && index < buildings.size());
return buildings[index];
assert(index >= 0 && index < get_building_count());
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)
{
assert(index >= 0 && index < buildings.size());
return &buildings[index];
assert(index >= 0 && index < get_building_count());
return &buildings_[index];
}
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 index = buildings.size();
buildings.push_back(building);
int index = get_building_count();
buildings_.push_back(building);
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)
{
assert(building);
@@ -737,7 +774,7 @@ int BuildingsData::create_building(const building *building)
bool BuildingsData::destroy_building(int index)
{
assert(index >= 0 && index < buildings.size());
buildings.erase(buildings.begin() + index);
assert(index >= 0 && index < get_building_count());
buildings_.erase(buildings_.begin() + index);
return true;
}

View File

@@ -59,14 +59,58 @@ public:
HashMap<String, AABB> building_aabbs;
/* Data for each building in a world */
private:
std::vector<struct building> buildings;
std::vector<struct building> buildings_;
struct building *get_building_ptr(int index);
public:
int get_building_count() 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_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 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)
{
// TODO: implement
int i;
unload_building(index);
String key = data()->item_nodes_get_key(index);
data()->destroy_building(index);
@@ -341,7 +340,7 @@ void StreamWorld::run_command(const String &command, const Array &args)
std::vector<int> erased_indices;
erased_indices.reserve(data()->get_building_count());
String prefix = args[0];
int i, j;
int i;
for (i = 0; i < (int)data()->get_building_count(); i++) {
if (data()->get_building(i).id.begins_with(prefix))
erased_indices.push_back(i);
@@ -465,7 +464,7 @@ void StreamWorld::remove_generated_stuff()
{
std::vector<int> erased_indices;
erased_indices.reserve(data()->get_building_count());
int i, j;
int i;
for (i = 0; i < data()->get_building_count(); i++) {
if (data()->get_building(i).generated)
erased_indices.push_back(i);