Skip to content

Commit

Permalink
#1082 Don't throw error when cloning entity with an entity name
Browse files Browse the repository at this point in the history
  • Loading branch information
SanderMertens committed Dec 17, 2023
1 parent 5e6f674 commit 1653495
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 16 deletions.
20 changes: 13 additions & 7 deletions flecs.c
Original file line number Diff line number Diff line change
Expand Up @@ -6085,22 +6085,28 @@ ecs_entity_t ecs_clone(
goto done;
}

ecs_type_t src_type = src_table->type;
ecs_table_diff_t diff = { .added = src_type };
ecs_table_t *dst_table = src_table;
if (src_table->flags & EcsTableHasName) {
dst_table = ecs_table_remove_id(world, src_table,
ecs_pair_t(EcsIdentifier, EcsName));
}

ecs_type_t dst_type = dst_table->type;
ecs_table_diff_t diff = { .added = dst_type };
ecs_record_t *dst_r = flecs_entities_get(world, dst);
flecs_new_entity(world, dst, dst_r, src_table, &diff, true, true);
flecs_new_entity(world, dst, dst_r, dst_table, &diff, true, true);
int32_t row = ECS_RECORD_TO_ROW(dst_r->row);

if (copy_value) {
flecs_table_move(world, dst, src, src_table,
flecs_table_move(world, dst, src, dst_table,
row, src_table, ECS_RECORD_TO_ROW(src_r->row), true);
int32_t i, count = src_table->column_count;
int32_t i, count = dst_table->column_count;
for (i = 0; i < count; i ++) {
ecs_type_t type = {
.array = &src_table->data.columns[i].id,
.array = &dst_table->data.columns[i].id,
.count = 1
};
flecs_notify_on_set(world, src_table, row, 1, &type, true);
flecs_notify_on_set(world, dst_table, row, 1, &type, true);
}
}

Expand Down
4 changes: 4 additions & 0 deletions flecs.h
Original file line number Diff line number Diff line change
Expand Up @@ -5242,6 +5242,10 @@ const ecs_entity_t* ecs_bulk_new_w_id(
* This operation clones the components of one entity into another entity. If
* no destination entity is provided, a new entity will be created. Component
* values are not copied unless copy_value is true.
*
* If the source entity has a name, it will not be copied to the destination
* entity. This is to prevent having two entities with the same name under the
* same parent, which is not allowed.
*
* @param world The world.
* @param dst The entity to copy the components to.
Expand Down
4 changes: 4 additions & 0 deletions include/flecs.h
Original file line number Diff line number Diff line change
Expand Up @@ -2412,6 +2412,10 @@ const ecs_entity_t* ecs_bulk_new_w_id(
* This operation clones the components of one entity into another entity. If
* no destination entity is provided, a new entity will be created. Component
* values are not copied unless copy_value is true.
*
* If the source entity has a name, it will not be copied to the destination
* entity. This is to prevent having two entities with the same name under the
* same parent, which is not allowed.
*
* @param world The world.
* @param dst The entity to copy the components to.
Expand Down
20 changes: 13 additions & 7 deletions src/entity.c
Original file line number Diff line number Diff line change
Expand Up @@ -2682,22 +2682,28 @@ ecs_entity_t ecs_clone(
goto done;
}

ecs_type_t src_type = src_table->type;
ecs_table_diff_t diff = { .added = src_type };
ecs_table_t *dst_table = src_table;
if (src_table->flags & EcsTableHasName) {
dst_table = ecs_table_remove_id(world, src_table,
ecs_pair_t(EcsIdentifier, EcsName));
}

ecs_type_t dst_type = dst_table->type;
ecs_table_diff_t diff = { .added = dst_type };
ecs_record_t *dst_r = flecs_entities_get(world, dst);
flecs_new_entity(world, dst, dst_r, src_table, &diff, true, true);
flecs_new_entity(world, dst, dst_r, dst_table, &diff, true, true);
int32_t row = ECS_RECORD_TO_ROW(dst_r->row);

if (copy_value) {
flecs_table_move(world, dst, src, src_table,
flecs_table_move(world, dst, src, dst_table,
row, src_table, ECS_RECORD_TO_ROW(src_r->row), true);
int32_t i, count = src_table->column_count;
int32_t i, count = dst_table->column_count;
for (i = 0; i < count; i ++) {
ecs_type_t type = {
.array = &src_table->data.columns[i].id,
.array = &dst_table->data.columns[i].id,
.count = 1
};
flecs_notify_on_set(world, src_table, row, 1, &type, true);
flecs_notify_on_set(world, dst_table, row, 1, &type, true);
}
}

Expand Down
3 changes: 2 additions & 1 deletion test/api/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -953,7 +953,8 @@
"tag",
"tag_w_value",
"1_tag_1_component",
"1_tag_1_component_w_value"
"1_tag_1_component_w_value",
"clone_w_name"
]
}, {
"id": "ComponentLifecycle",
Expand Down
28 changes: 28 additions & 0 deletions test/api/src/Clone.c
Original file line number Diff line number Diff line change
Expand Up @@ -348,3 +348,31 @@ void Clone_1_tag_1_component_w_value(void) {

ecs_fini(world);
}

void Clone_clone_w_name(void) {
ecs_world_t *world = ecs_mini();

ECS_COMPONENT(world, Position);
ECS_COMPONENT(world, Velocity);

ecs_entity_t t = ecs_new_entity(world, "template");
ecs_set(world, t, Position, {10, 20});
ecs_set(world, t, Velocity, {1, 2});

ecs_entity_t i = ecs_clone(world, 0, t, true);
test_assert(ecs_has(world, i, Position));
test_assert(ecs_has(world, i, Velocity));
test_assert(!ecs_has_pair(world, i, ecs_id(EcsIdentifier), EcsName));

const Position *p = ecs_get(world, i, Position);
test_assert(p != NULL);
test_int(p->x, 10);
test_int(p->y, 20);

const Velocity *v = ecs_get(world, i, Velocity);
test_assert(v != NULL);
test_int(v->x, 1);
test_int(v->y, 2);

ecs_fini(world);
}
7 changes: 6 additions & 1 deletion test/api/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,7 @@ void Clone_tag(void);
void Clone_tag_w_value(void);
void Clone_1_tag_1_component(void);
void Clone_1_tag_1_component_w_value(void);
void Clone_clone_w_name(void);

// Testsuite 'ComponentLifecycle'
void ComponentLifecycle_setup(void);
Expand Down Expand Up @@ -6101,6 +6102,10 @@ bake_test_case Clone_testcases[] = {
{
"1_tag_1_component_w_value",
Clone_1_tag_1_component_w_value
},
{
"clone_w_name",
Clone_clone_w_name
}
};

Expand Down Expand Up @@ -13139,7 +13144,7 @@ static bake_test_suite suites[] = {
"Clone",
NULL,
NULL,
14,
15,
Clone_testcases
},
{
Expand Down

0 comments on commit 1653495

Please sign in to comment.