Refactor building access keys

This commit is contained in:
2024-09-29 01:59:55 +03:00
parent e19dbd7a4f
commit 0d425391ce
5 changed files with 88 additions and 46 deletions

View File

@@ -68,5 +68,6 @@
"typeinfo": "cpp", "typeinfo": "cpp",
"variant": "cpp", "variant": "cpp",
"format": "cpp" "format": "cpp"
} },
"cmake.ignoreCMakeListsMissing": true
} }

View File

@@ -19,7 +19,7 @@ struct scene_data {
Ref<PackedScene> packed_scene; Ref<PackedScene> packed_scene;
String path; String path;
Ref<ResourceInteractiveLoader> loader; Ref<ResourceInteractiveLoader> loader;
std::vector<int> buildings; std::vector<String> buildings;
}; };
struct CSceneData { struct CSceneData {
@@ -420,43 +420,43 @@ bool BuildingsData::has_scene(const String &key) const
return e.is_valid(); return e.is_valid();
} }
void BuildingsData::remove_scene_item(const String &key, int item) void BuildingsData::remove_scene_item(const String &key, const String &bkey)
{ {
flecs::entity e = ecs.lookup(key.ascii().ptr()); flecs::entity e = ecs.lookup(key.ascii().ptr());
assert(e.is_valid()); assert(e.is_valid());
CSceneData *d = e.get_mut<CSceneData>(); CSceneData *d = e.get_mut<CSceneData>();
assert(d); assert(d);
std::vector<int>::iterator b = d->sd.buildings.begin(); std::vector<String>::iterator b = d->sd.buildings.begin();
std::vector<int>::iterator h = d->sd.buildings.end(); std::vector<String>::iterator h = d->sd.buildings.end();
// if (item_nodes.has(item)) // if (item_nodes.has(item))
// item_nodes[item]->queue_delete(); // item_nodes[item]->queue_delete();
d->sd.buildings.erase(std::remove(b, h, item), d->sd.buildings.end()); d->sd.buildings.erase(std::remove(b, h, bkey), d->sd.buildings.end());
} }
void BuildingsData::add_scene_item(const String &key, int item) void BuildingsData::add_scene_item(const String &key, const String &bkey)
{ {
flecs::entity e = ecs.lookup(key.ascii().ptr()); flecs::entity e = ecs.lookup(key.ascii().ptr());
assert(e.is_valid()); assert(e.is_valid());
CSceneData *d = e.get_mut<CSceneData>(); CSceneData *d = e.get_mut<CSceneData>();
assert(d); assert(d);
if (std::find(d->sd.buildings.begin(), d->sd.buildings.end(), item) == if (std::find(d->sd.buildings.begin(), d->sd.buildings.end(), bkey) ==
d->sd.buildings.end()) d->sd.buildings.end())
d->sd.buildings.push_back(item); d->sd.buildings.push_back(bkey);
} }
void BuildingsData::create_scene_data(const String &key, int item) void BuildingsData::create_scene_data(const String &key, const String &bkey)
{ {
if (!has_scene(key)) { if (!has_scene(key)) {
flecs::entity e = ecs.entity(key.ascii().ptr()); flecs::entity e = ecs.entity(key.ascii().ptr());
String path = building_data[key]; String path = building_data[key];
print_line("Requesting " + itos(item) + " " + path); print_line("Requesting " + (bkey) + " " + path);
struct scene_data sd; struct scene_data sd;
sd.path = path; sd.path = path;
sd.loader = ResourceLoader::load_interactive( sd.loader = ResourceLoader::load_interactive(
path, "PackedScene", true); path, "PackedScene", true);
if (std::find(sd.buildings.begin(), sd.buildings.end(), item) == if (std::find(sd.buildings.begin(), sd.buildings.end(), bkey) ==
sd.buildings.end()) sd.buildings.end())
sd.buildings.push_back(item); sd.buildings.push_back(bkey);
e.set<CSceneData>({ sd }); e.set<CSceneData>({ sd });
assert(e.get_mut<CSceneData>()); assert(e.get_mut<CSceneData>());
} }
@@ -488,19 +488,57 @@ int BuildingsData::scene_get_item_count(const String &key) const
return d->sd.buildings.size(); return d->sd.buildings.size();
} }
int BuildingsData::scene_get_item(const String &key, int index) const String BuildingsData::scene_get_item(const String &key, int index) const
{ {
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 -1; return "";
if (!e.get<CSceneData>()) if (!e.get<CSceneData>())
return -1; return "";
assert(e.is_valid()); assert(e.is_valid());
const CSceneData *d = e.get<CSceneData>(); const CSceneData *d = e.get<CSceneData>();
assert(d); assert(d);
return d->sd.buildings[index]; return d->sd.buildings[index];
} }
void BuildingsData::item_nodes_delete_node(const String &key)
{
if (item_nodes.has(key)) {
item_nodes[key]->queue_delete();
item_nodes.erase(key);
}
}
bool BuildingsData::item_nodes_exists(const String &key) const
{
return item_nodes.has(key);
}
void BuildingsData::item_nodes_set_node(const String &key, Node *node)
{
item_nodes[key] = node;
}
void BuildingsData::item_nodes_item_removed(const String &key)
{
int i;
if (item_nodes[key])
item_nodes[key]->queue_delete();
item_nodes.erase(key);
}
String BuildingsData::item_nodes_get_key(int item) const
{
return buildings[item].key;
}
Node *BuildingsData::item_nodes_get_node(const String &key) const
{
if (!item_nodes_exists(key))
return nullptr;
return item_nodes[key];
}
Error BuildingsData::scene_loader_poll(const String &key) Error BuildingsData::scene_loader_poll(const String &key)
{ {
if (has_scene(key)) { if (has_scene(key)) {

View File

@@ -28,12 +28,20 @@ public:
public: public:
void get_scene_keys_list(List<String> *keys) const; void get_scene_keys_list(List<String> *keys) const;
bool has_scene(const String &key) const; bool has_scene(const String &key) const;
void remove_scene_item(const String &key, int item); void remove_scene_item(const String &key, const String &bkey);
void add_scene_item(const String &key, int item); void add_scene_item(const String &key, const String &bkey);
void create_scene_data(const String &key, int item); void create_scene_data(const String &key, const String &bkey);
Ref<PackedScene> scene_get_packed_scene(const String &key) const; Ref<PackedScene> scene_get_packed_scene(const String &key) const;
int scene_get_item_count(const String &key) const; int scene_get_item_count(const String &key) const;
int scene_get_item(const String &key, int index) const; String scene_get_item(const String &key, int index) 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);
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;
private: private:
Error scene_loader_poll(const String &key); Error scene_loader_poll(const String &key);
@@ -47,6 +55,7 @@ public:
/* 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;
HashMap<String, Node *> item_nodes;
public: public:
int get_building_count() const; int get_building_count() const;

View File

@@ -167,25 +167,23 @@ void StreamWorld::unload_building(int id)
void StreamWorld::request_item(int type, int item) void StreamWorld::request_item(int type, int item)
{ {
String id = data()->get_building(item).id; String id = data()->get_building(item).id;
const String &bkey = data()->item_nodes_get_key(item);
if (id == "empty") if (id == "empty")
return; return;
switch (type) { switch (type) {
case 0: case 0:
if (!data()->has_scene(id)) if (!data()->has_scene(id))
data()->create_scene_data(id, item); data()->create_scene_data(id, bkey);
else else
data()->add_scene_item(id, item); data()->add_scene_item(id, bkey);
break; break;
case 1: case 1: {
print_line("Removing " + itos(item)); print_line("Removing " + itos(item));
if (data()->has_scene(id)) { if (data()->has_scene(id)) {
data()->remove_scene_item(id, item); data()->remove_scene_item(id, bkey);
if (item_nodes.has(item)) { data()->item_nodes_delete_node(bkey);
item_nodes[item]->queue_delete();
item_nodes.erase(item);
}
} }
break; } break;
} }
} }
@@ -202,12 +200,13 @@ void StreamWorld::update_items()
continue; continue;
} }
for (i = 0; i < (int)data()->scene_get_item_count(key); i++) { for (i = 0; i < (int)data()->scene_get_item_count(key); i++) {
if (item_nodes.has(data()->scene_get_item(key, i))) const String &bkey = data()->scene_get_item(key, i);
if (data()->item_nodes_exists(bkey))
continue; continue;
Node *psc = Node *psc =
data()->scene_get_packed_scene(key)->instance(); data()->scene_get_packed_scene(key)->instance();
Spatial *psp = Object::cast_to<Spatial>(psc); Spatial *psp = Object::cast_to<Spatial>(psc);
item_nodes[data()->scene_get_item(key, i)] = psc; data()->item_nodes_set_node(bkey, psc);
current_scene->add_child(psp); current_scene->add_child(psp);
psp->set_global_transform( psp->set_global_transform(
data()->get_building( data()->get_building(
@@ -223,11 +222,9 @@ void StreamWorld::remove_building(int index)
// TODO: implement // TODO: implement
int i; int i;
unload_building(index); unload_building(index);
String key = data()->item_nodes_get_key(index);
data()->destroy_building(index); data()->destroy_building(index);
for (i = index; i < (int)data()->get_building_count(); i++) { data()->item_nodes_item_removed(key);
item_nodes[i] = item_nodes[i + 1];
}
item_nodes.erase(data()->get_building_count());
update_items(); update_items();
} }
@@ -275,11 +272,11 @@ void StreamWorld::run_command(const String &command, const Array &args)
if (id < 0 || id >= (int)data()->get_building_count()) if (id < 0 || id >= (int)data()->get_building_count())
return; return;
data()->update_building_transform(id, args[1]); data()->update_building_transform(id, args[1]);
if (item_nodes.has(id)) { const String &key = data()->item_nodes_get_key(id);
Spatial *bnode = Node *node = data()->item_nodes_get_node(key);
Object::cast_to<Spatial>(item_nodes[id]); Spatial *bnode = Object::cast_to<Spatial>(node);
if (bnode)
bnode->set_global_transform(args[1]); bnode->set_global_transform(args[1]);
}
} else if (command == "checkpoint") } else if (command == "checkpoint")
data()->checkpoint(); data()->checkpoint();
else if (command == "undo") else if (command == "undo")
@@ -351,10 +348,9 @@ void StreamWorld::run_command(const String &command, const Array &args)
for (i = erased_indices.size() - 1; i >= 0; i--) { for (i = erased_indices.size() - 1; i >= 0; i--) {
int index = erased_indices[i]; int index = erased_indices[i];
unload_building(index); unload_building(index);
String key = data()->item_nodes_get_key(index);
data()->destroy_building(index); data()->destroy_building(index);
for (j = index; j < data()->get_building_count(); j++) data()->item_nodes_item_removed(key);
item_nodes[j] = item_nodes[j + 1];
item_nodes.erase(data()->get_building_count());
} }
update_items(); update_items();
} else if (command == "remove_generated_stuff") { } else if (command == "remove_generated_stuff") {
@@ -474,10 +470,9 @@ void StreamWorld::remove_generated_stuff()
for (i = erased_indices.size() - 1; i >= 0; i--) { for (i = erased_indices.size() - 1; i >= 0; i--) {
int index = erased_indices[i]; int index = erased_indices[i];
unload_building(index); unload_building(index);
String key = data()->item_nodes_get_key(index);
data()->destroy_building(index); data()->destroy_building(index);
for (j = index; j < (int)data()->get_building_count(); j++) data()->item_nodes_item_removed(key);
item_nodes[j] = item_nodes[j + 1];
item_nodes.erase(data()->get_building_count());
} }
update_items(); update_items();
} }

View File

@@ -16,7 +16,6 @@ private:
VoxelLodTerrain *terrain; VoxelLodTerrain *terrain;
Node *current_scene; Node *current_scene;
ConfigFile config; ConfigFile config;
HashMap<int, Node *> item_nodes;
using tile_key_t = std::tuple<int, int>; using tile_key_t = std::tuple<int, int>;
struct tile_hash : public std::unary_function<key_t, std::size_t> { struct tile_hash : public std::unary_function<key_t, std::size_t> {
std::size_t operator()(const tile_key_t &k) const std::size_t operator()(const tile_key_t &k) const