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; int i;
float dst = Math_INF; float dst = Math_INF;
@@ -111,7 +112,7 @@ int BuildingsData::get_closest_building(const Transform &xform)
id = i; id = i;
} }
} }
return id; return buildings_[id].key;
} }
void BuildingsData::cleanup() void BuildingsData::cleanup()

View File

@@ -61,10 +61,10 @@ public:
private: private:
std::vector<struct building> buildings_; std::vector<struct building> buildings_;
struct building *get_building_ptr(int index); struct building *get_building_ptr(int index);
public:
const struct building &get_building(int index) const; const struct building &get_building(int index) const;
struct building &get_building(int index); struct building &get_building(int index);
public:
struct building &get_building(const String &building_key); struct building &get_building(const String &building_key);
const struct building &get_building(const String &building_key) const; const struct building &get_building(const String &building_key) const;
struct callme { struct callme {
@@ -135,8 +135,9 @@ public:
void undo(); void undo();
void fill_door_locations(); void fill_door_locations();
void build_building_aabbs(); void build_building_aabbs();
void update_building_transform(int index, const Transform &xform); void update_building_transform(const String &key,
int get_closest_building(const Transform &xform); const Transform &xform);
String get_closest_building(const Transform &xform);
static BuildingsData *get_singleton(); static BuildingsData *get_singleton();
static void cleanup(); static void cleanup();
int get_building_by_key(const String &key) const; 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 curve_offset, float normal_offset,
float y_rotation) float y_rotation)
{ {
int index = BuildingsData::get_singleton()->get_building_by_key(key);
if (index < 0)
return;
struct line_building_data lb; struct line_building_data lb;
lb.building_key = key; lb.building_key = key;
lb.building_key_hash = key.hash64(); 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; lb.y_rotation = y_rotation;
lines[line].buildings.push_back(lb); lines[line].buildings.push_back(lb);
// TODO: save/load // 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) 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: " + print_line("assign_close_buildings: processing: " +
itos(BuildingsData::get_singleton()->get_building_count()) + itos(BuildingsData::get_singleton()->get_building_count()) +
" buildings"); " buildings");
for (i = 0; List<String> bkeys;
i < (int)BuildingsData::get_singleton()->get_building_count(); BuildingsData::get_singleton()->get_building_keys_list(&bkeys);
i++) { List<String>::Element *e;
for (e = bkeys.front(); e; e = e->next()) {
float dst = Math_INF; float dst = Math_INF;
float result_offset = 0.0f; float result_offset = 0.0f;
float side = 0.0f; float side = 0.0f;
String building_key; String building_key;
/* FIXME: use proper function */
String bkey = e->get();
struct BuildingsData::building &data = struct BuildingsData::building &data =
BuildingsData::get_singleton()->get_building(i); BuildingsData::get_singleton()->get_building(bkey);
// manually placed // manually placed
if (!data.generated) if (!data.generated)
continue; continue;
// already assigned to another line // already assigned to another line
const String &building_line = BuildingsData::get_singleton() const String &building_line = BuildingsData::get_singleton()
->get_building(i) ->get_building(bkey)
.line_name; .line_name;
if (building_line != line && building_line != "") if (building_line != line && building_line != "")
continue; continue;
@@ -694,64 +694,47 @@ void RoadLinesData::update_buildings_from_lines()
const uint64_t &building_key_hash = const uint64_t &building_key_hash =
lines[line].buildings[i].building_key_hash; lines[line].buildings[i].building_key_hash;
bool found = false; bool found = false;
int index = -1; int index = bd->get_building_by_key(
for (j = 0; j < (int)bd->get_building_count(); j++) { lines[line].buildings[i].building_key);
if (bd->get_building(j).key_hash == if (index >= 0)
building_key_hash) { found = true;
found = true; if (found) {
index = j;
break;
}
struct BuildingsData::building &b = struct BuildingsData::building &b =
bd->get_building(index); bd->get_building(lines[line]
if (found) { .buildings[i]
Vector3 pt = get_point_by_offsets( .building_key);
line, Vector3 pt = get_point_by_offsets(
lines[line] line,
.buildings[i] lines[line].buildings[i].line_offset,
.line_offset, lines[line].buildings[i].normal_offset);
lines[line] Basis basis = Basis().rotated(
.buildings[i] Vector3(0, 1, 0),
.normal_offset); lines[line].buildings[i].y_rotation);
Basis basis = Basis().rotated( b.xform.origin = pt;
Vector3(0, 1, 0), b.xform.basis = basis;
lines[line] Array args;
.buildings[i] args.push_back(index);
.y_rotation); EditorEvent::get_singleton()->event.emit(
b.xform.origin = pt; "building_updated", args);
b.xform.basis = basis; } else {
Array args; Vector3 pt = get_point_by_offsets(
args.push_back(index); line,
EditorEvent::get_singleton()->event.emit( lines[line].buildings[i].line_offset,
"building_updated", args); lines[line].buildings[i].normal_offset);
} else { Basis basis = Basis().rotated(
Vector3 pt = get_point_by_offsets( Vector3(0, 1, 0),
line, lines[line].buildings[i].y_rotation);
lines[line] struct BuildingsData::building nb;
.buildings[i] Dictionary data;
.line_offset, data["id"] = lines[line].buildings[i].id;
lines[line] data["xform"] = Transform(basis, pt);
.buildings[i] BuildingsData::building::from_dict(&nb, data);
.normal_offset); index = bd->get_building_count();
Basis basis = Basis().rotated( bd->create_building(nb);
Vector3(0, 1, 0), Array args;
lines[line] args.push_back(index);
.buildings[i] EditorEvent::get_singleton()->event.emit(
.y_rotation); "building_created", args);
struct BuildingsData::building nb;
Dictionary data;
data["id"] =
lines[line].buildings[i].id;
data["xform"] = Transform(basis, pt);
BuildingsData::building::from_dict(
&nb, data);
index = bd->get_building_count();
bd->create_building(nb);
Array args;
args.push_back(index);
EditorEvent::get_singleton()->event.emit(
"building_created", args);
}
} }
} }
e = e->next(); e = e->next();

View File

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

View File

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