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",
"variant": "cpp",
"format": "cpp"
}
},
"cmake.ignoreCMakeListsMissing": true
}

View File

@@ -19,7 +19,7 @@ struct scene_data {
Ref<PackedScene> packed_scene;
String path;
Ref<ResourceInteractiveLoader> loader;
std::vector<int> buildings;
std::vector<String> buildings;
};
struct CSceneData {
@@ -420,43 +420,43 @@ bool BuildingsData::has_scene(const String &key) const
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());
assert(e.is_valid());
CSceneData *d = e.get_mut<CSceneData>();
assert(d);
std::vector<int>::iterator b = d->sd.buildings.begin();
std::vector<int>::iterator h = d->sd.buildings.end();
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, 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());
assert(e.is_valid());
CSceneData *d = e.get_mut<CSceneData>();
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.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)) {
flecs::entity e = ecs.entity(key.ascii().ptr());
String path = building_data[key];
print_line("Requesting " + itos(item) + " " + path);
print_line("Requesting " + (bkey) + " " + path);
struct scene_data sd;
sd.path = path;
sd.loader = ResourceLoader::load_interactive(
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.push_back(item);
sd.buildings.push_back(bkey);
e.set<CSceneData>({ sd });
assert(e.get_mut<CSceneData>());
}
@@ -488,19 +488,57 @@ int BuildingsData::scene_get_item_count(const String &key) const
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());
if (!e.is_valid())
return -1;
return "";
if (!e.get<CSceneData>())
return -1;
return "";
assert(e.is_valid());
const CSceneData *d = e.get<CSceneData>();
assert(d);
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)
{
if (has_scene(key)) {

View File

@@ -28,12 +28,20 @@ public:
public:
void get_scene_keys_list(List<String> *keys) const;
bool has_scene(const String &key) const;
void remove_scene_item(const String &key, int item);
void add_scene_item(const String &key, int item);
void create_scene_data(const String &key, int item);
void remove_scene_item(const String &key, const String &bkey);
void add_scene_item(const String &key, const String &bkey);
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;
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:
Error scene_loader_poll(const String &key);
@@ -47,6 +55,7 @@ public:
/* Data for each building in a world */
private:
std::vector<struct building> buildings;
HashMap<String, Node *> item_nodes;
public:
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)
{
String id = data()->get_building(item).id;
const String &bkey = data()->item_nodes_get_key(item);
if (id == "empty")
return;
switch (type) {
case 0:
if (!data()->has_scene(id))
data()->create_scene_data(id, item);
data()->create_scene_data(id, bkey);
else
data()->add_scene_item(id, item);
data()->add_scene_item(id, bkey);
break;
case 1:
case 1: {
print_line("Removing " + itos(item));
if (data()->has_scene(id)) {
data()->remove_scene_item(id, item);
if (item_nodes.has(item)) {
item_nodes[item]->queue_delete();
item_nodes.erase(item);
}
data()->remove_scene_item(id, bkey);
data()->item_nodes_delete_node(bkey);
}
break;
} break;
}
}
@@ -202,12 +200,13 @@ void StreamWorld::update_items()
continue;
}
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;
Node *psc =
data()->scene_get_packed_scene(key)->instance();
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);
psp->set_global_transform(
data()->get_building(
@@ -223,11 +222,9 @@ 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);
for (i = index; i < (int)data()->get_building_count(); i++) {
item_nodes[i] = item_nodes[i + 1];
}
item_nodes.erase(data()->get_building_count());
data()->item_nodes_item_removed(key);
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())
return;
data()->update_building_transform(id, args[1]);
if (item_nodes.has(id)) {
Spatial *bnode =
Object::cast_to<Spatial>(item_nodes[id]);
const String &key = data()->item_nodes_get_key(id);
Node *node = data()->item_nodes_get_node(key);
Spatial *bnode = Object::cast_to<Spatial>(node);
if (bnode)
bnode->set_global_transform(args[1]);
}
} else if (command == "checkpoint")
data()->checkpoint();
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--) {
int index = erased_indices[i];
unload_building(index);
String key = data()->item_nodes_get_key(index);
data()->destroy_building(index);
for (j = index; j < data()->get_building_count(); j++)
item_nodes[j] = item_nodes[j + 1];
item_nodes.erase(data()->get_building_count());
data()->item_nodes_item_removed(key);
}
update_items();
} else if (command == "remove_generated_stuff") {
@@ -474,10 +470,9 @@ void StreamWorld::remove_generated_stuff()
for (i = erased_indices.size() - 1; i >= 0; i--) {
int index = erased_indices[i];
unload_building(index);
String key = data()->item_nodes_get_key(index);
data()->destroy_building(index);
for (j = index; j < (int)data()->get_building_count(); j++)
item_nodes[j] = item_nodes[j + 1];
item_nodes.erase(data()->get_building_count());
data()->item_nodes_item_removed(key);
}
update_items();
}

View File

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