Skip to content

Commit c7473ab

Browse files
author
GsLogiMaker
committed
Refactor set_name
1 parent b5598d8 commit c7473ab

File tree

4 files changed

+81
-37
lines changed

4 files changed

+81
-37
lines changed

cpp/src/entity.cpp

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -525,44 +525,13 @@ Ref<GFEntity> GFEntity::get_target_for(const Variant rel, int index) const {
525525
}
526526

527527
Ref<GFEntity> GFEntity::set_name(const String name_) {
528+
GFWorld* w = get_world();
528529
ecs_entity_t parent = ecs_get_parent(
529-
get_world()->raw(),
530+
w->raw(),
530531
get_id()
531532
);
532533

533-
if (ecs_lookup_child(
534-
get_world()->raw(),
535-
parent,
536-
name_.utf8()
537-
) == 0) {
538-
// No name conflicts, set name and return
539-
ecs_set_name(get_world()->raw(), get_id(), name_.utf8());
540-
return Ref(this);
541-
}
542-
543-
int trailing_digits = 0;
544-
for (int i=0; i != name_.length(); i++) {
545-
char32_t digit = name_[name_.length()-i-1];
546-
if (digit >= '0' && digit >= '9') {
547-
trailing_digits++;
548-
} else {
549-
break;
550-
}
551-
}
552-
553-
String number = name_.substr(name_.length()-1-trailing_digits);
554-
String base_name = name_.substr(0, name_.length()-1-trailing_digits);
555-
String name = name_;
556-
do {
557-
int name_int = number.to_int();
558-
name_int += 1;
559-
number = String::num_uint64(name_int);
560-
name = base_name + number;
561-
} while (ecs_lookup_child(
562-
get_world()->raw(),
563-
parent,
564-
name.utf8()
565-
));
534+
String name = w->entity_unique_name(parent, name_);
566535

567536
ecs_set_name(get_world()->raw(), get_id(), name.utf8());
568537
return Ref(this);

cpp/src/world.cpp

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "godot_cpp/classes/text_server_manager.hpp"
88
#include "godot_cpp/classes/wrapped.hpp"
99
#include "godot_cpp/variant/packed_string_array.hpp"
10+
#include "godot_cpp/variant/string.hpp"
1011
#include "godot_cpp/variant/utility_functions.hpp"
1112
#include "observer_builder.h"
1213
#include "pair.h"
@@ -778,6 +779,48 @@ Variant::Type GFWorld::id_to_variant_type(ecs_entity_t id) {
778779
return type;
779780
}
780781

782+
// ----------------------------------------------
783+
// --- Maybe expose later ---
784+
// ----------------------------------------------
785+
786+
String GFWorld::entity_unique_name(ecs_entity_t parent, String g_name) const {
787+
if (ecs_lookup_child(
788+
raw(),
789+
parent,
790+
g_name.utf8()
791+
) == 0) {
792+
// No name conflicts, set name and return
793+
return g_name;
794+
}
795+
796+
// Find have many digits are at the end of the name
797+
int trailing_digits = 0;
798+
for (int i=0; i != g_name.length(); i++) {
799+
char32_t digit = g_name[g_name.length()-i-1];
800+
if (digit >= '0' && digit <= '9') {
801+
trailing_digits++;
802+
} else {
803+
break;
804+
}
805+
}
806+
807+
String number = g_name.substr(g_name.length()-trailing_digits);
808+
String base_name = g_name.substr(0, g_name.length()-trailing_digits);
809+
String name = String();
810+
do {
811+
int name_int = number.to_int();
812+
name_int += 1;
813+
number = String::num_uint64(name_int);
814+
name = base_name + number;
815+
} while (ecs_lookup_child(
816+
raw(),
817+
parent,
818+
name.utf8()
819+
));
820+
821+
return name;
822+
}
823+
781824
// ----------------------------------------------
782825
// --- Unexposed ---
783826
// ----------------------------------------------
@@ -1063,15 +1106,19 @@ bool GFWorld::id_has_child(ecs_entity_t parent, const char* child_name) const {
10631106

10641107
bool GFWorld::id_set_parent(ecs_entity_t id, ecs_entity_t parent) const {
10651108
CHECK_ENTITY_ALIVE(id, this, false,
1066-
"Failed to set parent\nChild is not alive\n"
1109+
"Failed to set parent\n Child is not alive\n"
10671110
);
10681111
CHECK_ENTITY_ALIVE(parent, this, false,
1069-
"Failed to set parent\nParent is not alive\n"
1112+
"Failed to set parent\n Parent is not alive\n"
10701113
);
10711114

10721115
// TODO: Handle name conflicts rather than throw error
1116+
String new_name = String();
1117+
if (id_has_child(parent, ecs_get_name(raw(), id))) {
1118+
new_name = entity_unique_name(parent, ecs_get_name(raw(), id));
1119+
}
10731120
CHECK_NOT_HAS_CHILD(parent, ecs_get_name(raw(), id), this, false,
1074-
"Failed to set parent\n"
1121+
"Failed to set parent\n "
10751122
);
10761123

10771124
ecs_add_id(raw(), id, ecs_childof(parent));

cpp/src/world.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ namespace godot {
6363
String id_to_text(ecs_entity_t) const;
6464
static Variant::Type id_to_variant_type(ecs_entity_t);
6565

66+
// **************************************
67+
// *** Maybe expose later ***
68+
// **************************************
69+
70+
String entity_unique_name(ecs_entity_t parent, String) const;
71+
6672
// **************************************
6773
// *** Unexposed ***
6874
// **************************************

unittests/test_entities.gd

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,28 @@ func test_clear():
377377

378378
assert_false(e.has(tag))
379379

380+
func test_set_name():
381+
# Entities should get a unique name when
382+
# their name is explicitely set.
383+
var e1:= GFEntity.new_in_world(world).set_name("E1")
384+
var e2:= GFEntity.new_in_world(world).set_name("E1")
385+
var e3:= GFEntity.new_in_world(world).set_name("E1")
386+
assert_eq(e1.get_name(), "E1")
387+
assert_eq(e1.get_name(), "E2")
388+
assert_eq(e1.get_name(), "E3")
389+
390+
# Entities should make get a unique name
391+
# when moved to a parent.
392+
var parent:= GFEntity.new_in_world(world)
393+
var child_1:= GFEntity.new_in_world(world) \
394+
.set_name("Child") \
395+
.set_parent(parent)
396+
var child_2:= GFEntity.new_in_world(world) \
397+
.set_name("Child") \
398+
.set_parent(parent)
399+
assert_eq(child_1.get_name(), "Child")
400+
assert_eq(child_2.get_name(), "Child1")
401+
380402
#endregion
381403

382404
#region Classes

0 commit comments

Comments
 (0)