Adapted ECS for building instances

This commit is contained in:
2024-09-29 18:36:11 +03:00
parent 0d425391ce
commit 20807366d1
3 changed files with 236 additions and 24 deletions

View File

@@ -1,3 +1,5 @@
#undef NDEBUG
#include <cassert>
#include <algorithm>
#include <core/os/memory.h>
#include <core/io/json.h>
@@ -19,7 +21,12 @@ struct scene_data {
Ref<PackedScene> packed_scene;
String path;
Ref<ResourceInteractiveLoader> loader;
std::vector<String> buildings;
// std::vector<String> buildings;
};
struct CBuildingInstance {
String key;
Node *node;
};
struct CSceneData {
@@ -426,11 +433,28 @@ void BuildingsData::remove_scene_item(const String &key, const String &bkey)
assert(e.is_valid());
CSceneData *d = e.get_mut<CSceneData>();
assert(d);
#if 0
std::vector<String>::iterator b = d->sd.buildings.begin();
std::vector<String>::iterator h = d->sd.buildings.end();
// if (item_nodes.has(item))
// item_nodes[item]->queue_delete();
d->sd.buildings.erase(std::remove(b, h, bkey), d->sd.buildings.end());
#endif
flecs::query_builder<const CBuildingInstance> qb =
ecs.query_builder<const CBuildingInstance>().with(
flecs::ChildOf, e);
flecs::query<const CBuildingInstance> q = qb.build();
uint64_t key_hash = bkey.hash64();
flecs::entity em = q.find([key_hash](const CBuildingInstance &bi) {
return bi.key.hash64() == key_hash;
});
if (em.is_valid()) {
CBuildingInstance *bi = em.get_mut<CBuildingInstance>();
if (bi->node)
bi->node->queue_delete();
bi->node = nullptr;
em.destruct();
}
}
void BuildingsData::add_scene_item(const String &key, const String &bkey)
@@ -439,9 +463,19 @@ void BuildingsData::add_scene_item(const String &key, const String &bkey)
assert(e.is_valid());
CSceneData *d = e.get_mut<CSceneData>();
assert(d);
#if 0
if (std::find(d->sd.buildings.begin(), d->sd.buildings.end(), bkey) ==
d->sd.buildings.end())
d->sd.buildings.push_back(bkey);
#endif
String ename = "bi:" + bkey;
flecs::entity ce = e.lookup(ename.ascii().ptr());
if (ce.is_valid())
ce.destruct();
ce = ecs.entity(ename.ascii().ptr());
ce.child_of(e);
ce.set<CBuildingInstance>({ bkey, nullptr });
print_line("child name: " + String(ce.name()));
}
void BuildingsData::create_scene_data(const String &key, const String &bkey)
@@ -454,11 +488,21 @@ void BuildingsData::create_scene_data(const String &key, const String &bkey)
sd.path = path;
sd.loader = ResourceLoader::load_interactive(
path, "PackedScene", true);
#if 0
if (std::find(sd.buildings.begin(), sd.buildings.end(), bkey) ==
sd.buildings.end())
sd.buildings.push_back(bkey);
#endif
e.set<CSceneData>({ sd });
assert(e.get_mut<CSceneData>());
String ename = "bi:" + bkey;
flecs::entity ce = e.lookup(ename.ascii().ptr());
if (ce.is_valid())
ce.destruct();
ce = ecs.entity(ename.ascii().ptr());
ce.child_of(e);
ce.set<CBuildingInstance>({ bkey, nullptr });
print_line("child name: " + String(ce.name()));
}
}
@@ -485,46 +529,183 @@ int BuildingsData::scene_get_item_count(const String &key) const
assert(e.is_valid());
const CSceneData *d = e.get<CSceneData>();
assert(d);
return d->sd.buildings.size();
// return d->sd.buildings.size();
flecs::query_builder<const CBuildingInstance> qb =
ecs.query_builder<const CBuildingInstance>().with(
flecs::ChildOf, e);
flecs::query<const CBuildingInstance> q = qb.build();
int result;
q.run([&result](flecs::iter &it) {
it.next();
result = it.count();
it.fini();
});
// assert(result == d->sd.buildings.size());
print_line("scene_get_item_count: " + itos(result));
return result;
}
String BuildingsData::scene_get_item(const String &key, int index) 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 "";
return List<String>();
if (!e.get<CSceneData>())
return "";
return List<String>();
assert(e.is_valid());
const CSceneData *d = e.get<CSceneData>();
assert(d);
return d->sd.buildings[index];
flecs::query_builder<const CBuildingInstance> qb =
ecs.query_builder<const CBuildingInstance>().with(
flecs::ChildOf, e);
flecs::query<const CBuildingInstance> q = qb.build();
q.each([&ret](flecs::entity me, const CBuildingInstance &ib) {
ret.push_back(ib.key);
});
return ret;
}
void BuildingsData::set_scene_item_node(const String &key, const String &bkey,
Node *node)
{
flecs::entity e = ecs.lookup(key.ascii().ptr());
assert(e.is_valid());
CSceneData *d = e.get_mut<CSceneData>();
assert(d);
#if 0
if (std::find(d->sd.buildings.begin(), d->sd.buildings.end(), bkey) ==
d->sd.buildings.end())
d->sd.buildings.push_back(bkey);
#endif
String ename = "bi:" + bkey;
flecs::entity ce = e.lookup(ename.ascii().ptr());
assert(ce.is_valid());
CBuildingInstance *bi = ce.get_mut<CBuildingInstance>();
assert(bi);
assert(bi->key == bkey);
bi->node = node;
}
bool BuildingsData::has_scene_item(const String &key, const String &bkey) const
{
flecs::entity e = ecs.lookup(key.ascii().ptr());
assert(e.is_valid());
CSceneData *d = e.get_mut<CSceneData>();
assert(d);
String ename = "bi:" + bkey;
flecs::entity ce = e.lookup(ename.ascii().ptr());
return ce.is_valid();
}
Node *BuildingsData::get_scene_item_node(const String &key,
const String &bkey) const
{
flecs::entity e = ecs.lookup(key.ascii().ptr());
assert(e.is_valid());
CSceneData *d = e.get_mut<CSceneData>();
assert(d);
String ename = "bi:" + bkey;
flecs::entity ce = e.lookup(ename.ascii().ptr());
assert(ce.is_valid());
CBuildingInstance *bi = ce.get_mut<CBuildingInstance>();
assert(bi);
assert(bi->key == bkey);
return bi->node;
}
void BuildingsData::item_nodes_delete_node(const String &key)
{
#if 0
if (item_nodes.has(key)) {
item_nodes[key]->queue_delete();
item_nodes.erase(key);
}
#endif
flecs::query_builder<const CBuildingInstance> qb =
ecs.query_builder<const CBuildingInstance>();
flecs::query<const CBuildingInstance> q = qb.build();
uint64_t key_hash = key.hash64();
flecs::entity e = q.find(
[key_hash](flecs::entity me, const CBuildingInstance &ib) {
return ib.key.hash64() == key_hash;
});
assert(e.is_valid());
CBuildingInstance *ib = e.get_mut<CBuildingInstance>();
if (ib->node)
ib->node->queue_delete();
ib->node = nullptr;
}
#if 0
bool BuildingsData::item_nodes_exists(const String &key) const
{
#if 0
bool result = false;
return item_nodes.has(key);
flecs::query_builder<const CBuildingInstance> qb =
ecs.query_builder<const CBuildingInstance>();
flecs::query<const CBuildingInstance> q = qb.build();
uint64_t key_hash = key.hash64();
q.run([key_hash, &result](flecs::iter &it) {
while (it.next()) {
auto em = it.field<flecs::entity>(0);
auto ib = it.field<const CBuildingInstance>(1);
if (ib->key.hash64() == key_hash) {
result = true;
it.fini();
break;
}
}
});
return result;
#endif
String ename = "bi:" + key;
flecs::entity ce = ecs.lookup(ename.ascii().ptr());
bool result = ce.is_valid();
if (!result)
return result;
const CBuildingInstance *bi = ce.get<CBuildingInstance>();
if (!bi)
return false;
if (bi->node)
return true;
return false;
}
void BuildingsData::item_nodes_set_node(const String &key, Node *node)
{
item_nodes[key] = node;
String ename = "bi:" + key;
print_line(ename);
flecs::entity ce = ecs.lookup(ename.ascii().ptr());
assert(ce.is_valid());
CBuildingInstance *bi = ce.get_mut<CBuildingInstance>();
assert(bi);
bi->node = node;
}
#endif
void BuildingsData::item_nodes_item_removed(const String &key)
{
int i;
#if 0
if (item_nodes[key])
item_nodes[key]->queue_delete();
item_nodes.erase(key);
#endif
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;
});
assert(e.is_valid());
CBuildingInstance *bi = e.get_mut<CBuildingInstance>();
assert(bi);
if (bi->node) {
bi->node->queue_delete();
}
bi->node = nullptr;
}
String BuildingsData::item_nodes_get_key(int item) const
@@ -532,11 +713,34 @@ String BuildingsData::item_nodes_get_key(int item) const
return buildings[item].key;
}
#if 0
Node *BuildingsData::item_nodes_get_node(const String &key) const
{
if (!item_nodes_exists(key))
return nullptr;
return item_nodes[key];
// return item_nodes[key];
String ename = "bi:" + key;
flecs::entity ce = ecs.lookup(ename.ascii().ptr());
assert(ce.is_valid());
CBuildingInstance *bi = ce.get_mut<CBuildingInstance>();
assert(bi);
return bi->node;
}
#endif
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;
});
if (e.is_valid())
return e.get<CBuildingInstance>()->node;
else
return nullptr;
}
Error BuildingsData::scene_loader_poll(const String &key)

View File

@@ -33,12 +33,17 @@ public:
void create_scene_data(const String &key, const String &bkey);
Ref<PackedScene> scene_get_packed_scene(const String &key) const;
int scene_get_item_count(const String &key) const;
String scene_get_item(const String &key, int index) const;
// String scene_get_item(const String &key, int index) const;
List<String> scene_get_items(const String &key) const;
void set_scene_item_node(const String &key, const String &bkey,
Node *node);
bool has_scene_item(const String &key, const String &bkey) const;
Node *get_scene_item_node(const String &key, const String &bkey) const;
public:
void item_nodes_delete_node(const String &key);
bool item_nodes_exists(const String &key) const;
void item_nodes_set_node(const String &key, Node *node);
// bool item_nodes_exists(const String &key) const;
// void item_nodes_set_node(const String &key, Node *node);
void item_nodes_item_removed(const String &key);
Node *item_nodes_get_node(const String &key) const;
String item_nodes_get_key(int item) const;
@@ -55,7 +60,7 @@ public:
/* Data for each building in a world */
private:
std::vector<struct building> buildings;
HashMap<String, Node *> item_nodes;
// HashMap<String, Node *> item_nodes;
public:
int get_building_count() const;

View File

@@ -181,7 +181,6 @@ void StreamWorld::request_item(int type, int item)
print_line("Removing " + itos(item));
if (data()->has_scene(id)) {
data()->remove_scene_item(id, bkey);
data()->item_nodes_delete_node(bkey);
}
} break;
}
@@ -189,7 +188,6 @@ void StreamWorld::request_item(int type, int item)
void StreamWorld::update_items()
{
int i;
List<String> keys;
data()->get_scene_keys_list(&keys);
List<String>::Element *e = keys.front();
@@ -199,19 +197,24 @@ void StreamWorld::update_items()
e = e->next();
continue;
}
for (i = 0; i < (int)data()->scene_get_item_count(key); i++) {
const String &bkey = data()->scene_get_item(key, i);
if (data()->item_nodes_exists(bkey))
const List<String> &items = data()->scene_get_items(key);
const List<String>::Element *be = items.front();
while (be) {
const String &bkey = be->get();
if (data()->has_scene_item(key, bkey) &&
data()->get_scene_item_node(key, bkey)) {
be = be->next();
continue;
}
Node *psc =
data()->scene_get_packed_scene(key)->instance();
Spatial *psp = Object::cast_to<Spatial>(psc);
data()->item_nodes_set_node(bkey, psc);
current_scene->add_child(psp);
psp->set_global_transform(
data()->get_building(
data()->scene_get_item(key, i))
.xform);
// data()->item_nodes_set_node(bkey, psc);
data()->set_scene_item_node(key, bkey, psc);
current_scene->call_deferred("add_child", psp);
psp->call_deferred("set_global_transform",
data()->get_building(bkey).xform);
be = be->next();
}
e = e->next();
}