Adapted ECS for building instances
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user