Skip to content

Commit 687a602

Browse files
committed
entity: add clone_entity utility - close #1351
1 parent 4887299 commit 687a602

2 files changed

Lines changed: 58 additions & 0 deletions

File tree

‎src/entt/entity/utility.hpp‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef ENTT_ENTITY_UTILITY_HPP
22
#define ENTT_ENTITY_UTILITY_HPP
33

4+
#include "../config/config.h"
45
#include "../core/fwd.hpp"
56
#include "../core/type_traits.hpp"
67
#include "../stl/memory.hpp"
@@ -248,6 +249,27 @@ struct sigh_helper<Registry, Type> final: sigh_helper<Registry> {
248249
template<typename Registry>
249250
sigh_helper(Registry &) -> sigh_helper<Registry>;
250251

252+
/**
253+
* @brief Clones an entity and all its components.
254+
* @tparam Entity A valid entity type.
255+
* @tparam Args Registry type template parameters.
256+
* @param ref A valid reference to a registry.
257+
* @param src Source entity to copy from.
258+
* @return The newly created entity that is a copy of the given one, if any.
259+
*/
260+
template<typename Entity, typename... Args>
261+
[[nodiscard]] Entity clone_entity(basic_registry<Entity, Args...> &ref, const Entity src) {
262+
const auto dst = ref.create();
263+
264+
for([[maybe_unused]] auto [id, storage]: ref.storage()) {
265+
if(storage.contains(src)) {
266+
storage.push(dst, storage.value(src));
267+
}
268+
}
269+
270+
return dst;
271+
}
272+
251273
} // namespace entt
252274

253275
#endif

‎test/entt/entity/utility.cpp‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,3 +165,39 @@ TEST_F(SighHelper, Functionalities) {
165165

166166
ASSERT_EQ(counter, 6);
167167
}
168+
169+
TEST(CloneEntity, NullEntity) {
170+
entt::registry registry{};
171+
const entt::entity entity = entt::null;
172+
const auto other = entt::clone_entity(registry, entity);
173+
174+
ASSERT_NE(entity, other);
175+
ASSERT_TRUE(registry.valid(other));
176+
ASSERT_TRUE(registry.orphan(other));
177+
}
178+
179+
TEST(CloneEntity, EmptyEntity) {
180+
entt::registry registry{};
181+
const auto entity = registry.create();
182+
const auto other = entt::clone_entity(registry, entity);
183+
184+
ASSERT_NE(entity, other);
185+
ASSERT_TRUE(registry.valid(other));
186+
ASSERT_TRUE(registry.orphan(other));
187+
}
188+
189+
TEST(CloneEntity, ValidEntity) {
190+
entt::registry registry{};
191+
const auto entity = registry.create();
192+
193+
registry.emplace<char>(entity, 'c');
194+
registry.emplace<int>(entity, 1);
195+
196+
const auto other = entt::clone_entity(registry, entity);
197+
198+
ASSERT_NE(entity, other);
199+
ASSERT_TRUE(registry.valid(other));
200+
ASSERT_TRUE((registry.all_of<char, int>(other)));
201+
ASSERT_EQ(registry.get<char>(other), 'c');
202+
ASSERT_EQ(registry.get<int>(other), 1);
203+
}

0 commit comments

Comments
 (0)