Refactor more for string key access to buildings

This commit is contained in:
2024-10-01 05:27:15 +03:00
parent 9705200853
commit 5e6bcedd09
5 changed files with 117 additions and 105 deletions

View File

@@ -91,12 +91,13 @@ void BuildingsData::build_building_aabbs()
}
}
void BuildingsData::update_building_transform(int index, const Transform &xform)
void BuildingsData::update_building_transform(const String &key,
const Transform &xform)
{
buildings_[index].xform = xform;
get_building(key).xform = xform;
}
int BuildingsData::get_closest_building(const Transform &xform)
String BuildingsData::get_closest_building(const Transform &xform)
{
int i;
float dst = Math_INF;
@@ -111,7 +112,7 @@ int BuildingsData::get_closest_building(const Transform &xform)
id = i;
}
}
return id;
return buildings_[id].key;
}
void BuildingsData::cleanup()

View File

@@ -61,10 +61,10 @@ public:
private:
std::vector<struct building> buildings_;
struct building *get_building_ptr(int index);
public:
const struct building &get_building(int index) const;
struct building &get_building(int index);
public:
struct building &get_building(const String &building_key);
const struct building &get_building(const String &building_key) const;
struct callme {
@@ -135,8 +135,9 @@ public:
void undo();
void fill_door_locations();
void build_building_aabbs();
void update_building_transform(int index, const Transform &xform);
int get_closest_building(const Transform &xform);
void update_building_transform(const String &key,
const Transform &xform);
String get_closest_building(const Transform &xform);
static BuildingsData *get_singleton();
static void cleanup();
int get_building_by_key(const String &key) const;

View File

@@ -523,9 +523,6 @@ void RoadLinesData::line_add_building(const String &line, const String &key,
float curve_offset, float normal_offset,
float y_rotation)
{
int index = BuildingsData::get_singleton()->get_building_by_key(key);
if (index < 0)
return;
struct line_building_data lb;
lb.building_key = key;
lb.building_key_hash = key.hash64();
@@ -534,7 +531,7 @@ void RoadLinesData::line_add_building(const String &line, const String &key,
lb.y_rotation = y_rotation;
lines[line].buildings.push_back(lb);
// TODO: save/load
BuildingsData::get_singleton()->get_building(index).line_name = line;
BuildingsData::get_singleton()->get_building(key).line_name = line;
}
void RoadLinesData::assign_close_buildings(const String &line)
@@ -553,21 +550,24 @@ void RoadLinesData::assign_close_buildings(const String &line)
print_line("assign_close_buildings: processing: " +
itos(BuildingsData::get_singleton()->get_building_count()) +
" buildings");
for (i = 0;
i < (int)BuildingsData::get_singleton()->get_building_count();
i++) {
List<String> bkeys;
BuildingsData::get_singleton()->get_building_keys_list(&bkeys);
List<String>::Element *e;
for (e = bkeys.front(); e; e = e->next()) {
float dst = Math_INF;
float result_offset = 0.0f;
float side = 0.0f;
String building_key;
/* FIXME: use proper function */
String bkey = e->get();
struct BuildingsData::building &data =
BuildingsData::get_singleton()->get_building(i);
BuildingsData::get_singleton()->get_building(bkey);
// manually placed
if (!data.generated)
continue;
// already assigned to another line
const String &building_line = BuildingsData::get_singleton()
->get_building(i)
->get_building(bkey)
.line_name;
if (building_line != line && building_line != "")
continue;
@@ -694,30 +694,22 @@ void RoadLinesData::update_buildings_from_lines()
const uint64_t &building_key_hash =
lines[line].buildings[i].building_key_hash;
bool found = false;
int index = -1;
for (j = 0; j < (int)bd->get_building_count(); j++) {
if (bd->get_building(j).key_hash ==
building_key_hash) {
int index = bd->get_building_by_key(
lines[line].buildings[i].building_key);
if (index >= 0)
found = true;
index = j;
break;
}
struct BuildingsData::building &b =
bd->get_building(index);
if (found) {
struct BuildingsData::building &b =
bd->get_building(lines[line]
.buildings[i]
.building_key);
Vector3 pt = get_point_by_offsets(
line,
lines[line]
.buildings[i]
.line_offset,
lines[line]
.buildings[i]
.normal_offset);
lines[line].buildings[i].line_offset,
lines[line].buildings[i].normal_offset);
Basis basis = Basis().rotated(
Vector3(0, 1, 0),
lines[line]
.buildings[i]
.y_rotation);
lines[line].buildings[i].y_rotation);
b.xform.origin = pt;
b.xform.basis = basis;
Array args;
@@ -727,24 +719,16 @@ void RoadLinesData::update_buildings_from_lines()
} else {
Vector3 pt = get_point_by_offsets(
line,
lines[line]
.buildings[i]
.line_offset,
lines[line]
.buildings[i]
.normal_offset);
lines[line].buildings[i].line_offset,
lines[line].buildings[i].normal_offset);
Basis basis = Basis().rotated(
Vector3(0, 1, 0),
lines[line]
.buildings[i]
.y_rotation);
lines[line].buildings[i].y_rotation);
struct BuildingsData::building nb;
Dictionary data;
data["id"] =
lines[line].buildings[i].id;
data["id"] = lines[line].buildings[i].id;
data["xform"] = Transform(basis, pt);
BuildingsData::building::from_dict(
&nb, data);
BuildingsData::building::from_dict(&nb, data);
index = bd->get_building_count();
bd->create_building(nb);
Array args;
@@ -753,7 +737,6 @@ void RoadLinesData::update_buildings_from_lines()
"building_created", args);
}
}
}
e = e->next();
}
}

View File

@@ -796,10 +796,11 @@ void RoadLinesEditor::move_cursor_to_closest_building()
{
print_line("move_cursor_to_closest_building");
Vector3 pt = get_cursor_position();
int index = BuildingsData::get_singleton()->get_closest_building(
const String &key =
BuildingsData::get_singleton()->get_closest_building(
Transform(Basis(), pt));
const Transform &xform =
BuildingsData::get_singleton()->get_building(index).xform;
BuildingsData::get_singleton()->get_building(key).xform;
set_cursor_position(xform.origin);
Spatial *cursor = get_as_node<Spatial>(cursor_name);
if (!cursor->is_visible())

View File

@@ -16,7 +16,24 @@
void StreamWorld::create_tilemap()
{
int i;
data()->for_each_building(
[this](const String &key, void *hdata) {
int tile_x = data()->get_building(key).xform.origin.x /
tile_size;
int tile_z = data()->get_building(key).xform.origin.z /
tile_size;
std::tuple<int, int> tkey =
std::make_tuple(tile_x, tile_z);
int index = data()->get_building_by_key(key);
if (tiles.find(tkey) != tiles.end())
tiles[tkey].push_back(index);
else {
std::vector<int> data = { index };
tiles[tkey] = data;
}
},
nullptr);
#if 0
for (i = 0; i < (int)data()->get_building_count(); i++) {
int tile_x = data()->get_building(i).xform.origin.x / tile_size;
int tile_z = data()->get_building(i).xform.origin.z / tile_size;
@@ -28,6 +45,7 @@ void StreamWorld::create_tilemap()
tiles[key] = data;
}
}
#endif
print_line("Tile count: " + itos(tiles.size()));
}
@@ -137,7 +155,7 @@ void StreamWorld::load_tile(int tx, int ty)
const std::vector<int> &items = tiles[key];
for (i = 0; i < (int)items.size(); i++) {
print_line("load item: " + itos(i) + ": " + itos(items[i]) +
": " + data()->get_building(items[i]).id);
": " /* + data()->get_building(items[i]).id */);
load_building(items[i]);
}
}
@@ -149,7 +167,7 @@ void StreamWorld::erase_tile(int tx, int ty)
const std::vector<int> &items = tiles[key];
for (i = 0; i < (int)items.size(); i++) {
print_line("unload item: " + itos(i) + ": " + itos(items[i]) +
": " + data()->get_building(items[i]).id);
": " /* + data()->get_building(items[i]).id */);
unload_building(items[i]);
}
}
@@ -166,8 +184,8 @@ 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);
String id = data()->get_building(bkey).id;
if (id == "empty")
return;
switch (type) {
@@ -238,15 +256,15 @@ void StreamWorld::run_command(const String &command, const Array &args)
return;
}
const Transform &xform = args[0];
int id = data()->get_closest_building(xform);
String key = data()->get_closest_building(xform);
Array ret_data;
ret_data.resize(5);
ret_data[0] = data()->get_building(id).xform;
ret_data[0] = data()->get_building(key).xform;
ret_data[1] = xform.origin.distance_squared_to(
data()->get_building(id).xform.origin);
ret_data[2] = data()->get_building(id).key;
ret_data[3] = id;
ret_data[4] = data()->get_building(id).id;
data()->get_building(key).xform.origin);
ret_data[2] = key;
ret_data[3] = data()->get_building_by_key(key);
ret_data[4] = data()->get_building(key).id;
emit_signal("command_result", command, ret_data);
} else if (command == "get_building_id_for_key") {
if (args.size() == 0) {
@@ -254,15 +272,9 @@ void StreamWorld::run_command(const String &command, const Array &args)
return;
}
String key = args[1];
uint64_t khash = key.hash64();
Array ret_data;
ret_data.resize(1);
int id = -1, i;
for (i = 0; i < (int)data()->get_building_count(); i++)
if (data()->get_building(i).key.hash64() == khash) {
id = i;
break;
}
int id = data()->get_building_by_key(key);
ret_data[0] = id;
emit_signal("command_result", command, ret_data);
} else if (command == "update_building_transform") {
@@ -273,8 +285,8 @@ void StreamWorld::run_command(const String &command, const Array &args)
int id = args[0];
if (id < 0 || id >= (int)data()->get_building_count())
return;
data()->update_building_transform(id, args[1]);
const String &key = data()->item_nodes_get_key(id);
data()->update_building_transform(key, args[1]);
Node *node = data()->item_nodes_get_node(key);
Spatial *bnode = Object::cast_to<Spatial>(node);
if (bnode)
@@ -306,9 +318,10 @@ void StreamWorld::run_command(const String &command, const Array &args)
print_error("unknown building type: " + new_type);
return;
}
String old_type = data()->get_building(id).id;
String key = data()->item_nodes_get_key(id);
String old_type = data()->get_building(key).id;
unload_building(id);
data()->get_building(id).id = new_type;
data()->get_building(key).id = new_type;
load_building(id);
update_items();
print_line("changed building: " + itos(id) +
@@ -341,10 +354,18 @@ void StreamWorld::run_command(const String &command, const Array &args)
erased_indices.reserve(data()->get_building_count());
String prefix = args[0];
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);
data()->for_each_building(
[&erased_indices, prefix](const String &key,
void *data) {
if (data()->get_building(key).id.begins_with(
prefix)) {
int index = data()->get_building_by_key(
key);
assert(index >= 0);
erased_indices.push_back(index);
}
},
nullptr);
print_line("delete buildings: " + itos(erased_indices.size()) +
" prefix: " + prefix);
for (i = erased_indices.size() - 1; i >= 0; i--) {
@@ -465,10 +486,15 @@ void StreamWorld::remove_generated_stuff()
std::vector<int> erased_indices;
erased_indices.reserve(data()->get_building_count());
int i;
for (i = 0; i < data()->get_building_count(); i++) {
if (data()->get_building(i).generated)
erased_indices.push_back(i);
data()->for_each_building(
[&erased_indices](const String &key, void *mdata) {
if (data()->get_building(key).generated) {
int index = data()->get_building_by_key(key);
assert(index >= 0);
erased_indices.push_back(index);
}
},
nullptr);
for (i = erased_indices.size() - 1; i >= 0; i--) {
int index = erased_indices[i];
unload_building(index);