17#include "entt/entity/fwd.hpp"
22#include <hpp/utility.hpp>
31 entt::handle
handle(*
const_cast<entt::handle::registry_type*
>(chandle.registry()), chandle.entity());
39 auto* base = entities.data();
42 static_assert(
sizeof(
entity_data<entt::handle>) ==
sizeof(entt::handle),
"entity_data<entt::handle> and entt::handle must have the same size");
43 static_assert(
alignof(
entity_data<entt::handle>) ==
alignof(entt::handle),
"entity_data<entt::handle> and entt::handle must have the same alignment");
45 auto* first_handle =
reinterpret_cast<const entt::handle*
>(base);
48 hpp::span<const entt::handle> handles{first_handle, entities.size()};
81 if(callbacks && callbacks->callback)
83 callbacks->callback(
as_span(entities));
151 id_comp->generate_if_nil();
152 load_ctx.mapping_by_prefab_uid[id_comp->id].handle = obj;
158 for(
auto& entity_uuid : prefab_comp->removed_entities)
160 load_ctx.mapping_by_prefab_uid[entity_uuid].handle = {};
168 for(
auto child : trans_comp->get_children())
180 for(
auto& [uid, mapping] : load_ctx.mapping_by_prefab_uid)
182 if(!mapping.consumed && mapping.handle)
185 mapping.handle.destroy();
191auto is_parent(entt::const_handle potential_parent, entt::const_handle child) ->
bool
193 if(!potential_parent)
206 auto parent = transform->get_parent();
212 if(parent == potential_parent)
220auto find_root(entt::const_handle e) -> entt::const_handle
227 if(!transform || !transform->get_parent())
231 e = transform->get_parent();
236auto are_related(entt::const_handle lhs, entt::const_handle rhs) ->
bool
255 ctx->push_segment(
id->id.to_string());
278template<
typename Archive>
281 entt::handle::entity_type
id = obj.valid() ? obj.entity() : entt::null;
282 try_save(ar, ser20::make_nvp(
"id",
id));
285template<
typename Archive>
293 try_save(ar, ser20::make_nvp(
"prefab_uid", id_comp.id));
297 try_save(ar, ser20::make_nvp(
"prefab_uid", hpp::uuid{}));
301template<
typename Archive>
308 try_save(ar, ser20::make_nvp(
"uid", id_comp.id));
312 try_save(ar, ser20::make_nvp(
"uid", hpp::uuid{}));
316template<
typename Archive>
320 if(save_ctx.is_saving_to_prefab())
324 if(!save_ctx.is_cloning())
334template<
typename Archive>
337 entt::handle::entity_type
id{};
338 bool valid =
try_load(ar, ser20::make_nvp(
"id",
id));
340 valid &=
id != entt::null &&
id != entt::handle::entity_type(0);
344 auto it = load_ctx.mapping_by_eid.find(
id);
345 if(it != load_ctx.mapping_by_eid.end())
352 load_ctx.mapping_by_eid[
id] = obj;
357 if(flags == entity_flags::resolve_with_existing)
359 entt::handle check_entity(*load_ctx.reg,
id);
363 load_ctx.mapping_by_eid[
id] = obj;
373 obj = entt::handle(*load_ctx.reg, load_ctx.reg->create());
374 load_ctx.mapping_by_eid[
id] = obj;
384template<
typename Archive>
388 try_load(ar, ser20::make_nvp(
"prefab_uid", uid));
392 auto it = load_ctx.mapping_by_prefab_uid.find(uid);
393 if(it != load_ctx.mapping_by_prefab_uid.end())
396 obj = it->second.handle;
397 it->second.consumed =
true;
404template<
typename Archive>
408 if(!
try_load(ar, ser20::make_nvp(
"uid", uuid)))
417 auto it = load_ctx.mapping_by_uid.find(uuid);
418 if(it != load_ctx.mapping_by_uid.end())
424 load_ctx.mapping_by_uid[uuid] = obj;
428 if(flags == entity_flags::resolve_with_existing)
435 obj = entt::handle(*load_ctx.reg, e);
436 load_ctx.mapping_by_uid[uuid] = obj;
443 obj = entt::handle(*load_ctx.reg, load_ctx.reg->create());
444 load_ctx.mapping_by_uid[uuid] = obj;
449template<
typename Archive>
454 if(load_ctx.is_updating_prefab())
458 if(!valid && !load_ctx.is_cloning())
472template<
typename Component>
475 if constexpr(std::is_same_v<Component, prefab_component>)
480 if(save_ctx.is_saving_to_prefab())
485 else if constexpr(std::is_same_v<Component, prefab_id_component>)
490 if(save_ctx.is_cloning())
492 if(save_ctx.get_clone_mode() != clone_mode_t::cloning_prefab_instance)
501template<
typename Component>
504 if constexpr(std::is_same_v<Component, id_component>)
510 if(load_ctx.is_updating_prefab())
545 entt::const_handle to_save = obj.handle;
549 bool is_saving_single = save_ctx.save_source.valid();
553 bool save_source_is_parent =
is_parent(save_ctx.save_source, obj.handle);
556 if(!save_source_is_parent)
558 if(save_ctx.is_saving_to_prefab())
568 flags = entity_flags::resolve_with_existing;
573 if(!save_ctx.is_saving_to_prefab())
575 flags = entity_flags::resolve_with_existing;
580 try_save(ar, ser20::make_nvp(
"flags", flags));
589 try_load(ar, ser20::make_nvp(
"flags", flags));
601 hpp::for_each_tuple_type<unravel::all_serializeable_components>(
611 auto component = obj.entity.try_get<ctype>();
613 const auto type = entt::resolve<ctype>();
629 hpp::for_each_tuple_type<unravel::all_serializeable_components>(
640 auto component_type = entt::resolve<ctype>();
644 auto has_name =
"has_" +
name;
645 auto pretty_has_name =
"Has" + pretty_name;
648 bool has_component =
false;
650 bool success_has_component =
false;
657 if(!success_has_component)
668 auto& component = obj.entity.get_or_emplace<ctype>();
670 bool success_component =
false;
679 if(!success_component)
691 if constexpr(std::is_same_v<ctype, id_component>)
693 auto& comp = obj.entity.get_or_emplace<ctype>();
694 comp.generate_if_nil();
696 if constexpr(std::is_same_v<ctype, tag_component>)
698 auto& comp = obj.entity.get_or_emplace<ctype>();
701 if constexpr(std::is_same_v<ctype, layer_component>)
703 auto& comp = obj.entity.get_or_emplace<ctype>();
715 if(load_ctx.is_cloning())
717 if(load_ctx.get_clone_mode() != clone_mode_t::cloning_prefab_instance)
726 id_comp->regenerate_id();
736 try_save(ar, ser20::make_nvp(
"components", obj.components));
749 obj.components.entity = e;
750 try_load(ar, ser20::make_nvp(
"components", obj.components));
772 entities.emplace_back(data);
774 entities.reserve(entities.size() +
children.size());
777 flatten_hierarchy(child, entities);
781template<
typename Archive>
782void save_to_archive(Archive& ar, entt::const_handle obj)
794 std::vector<entity_data<entt::const_handle>> entities;
795 flatten_hierarchy(obj, entities);
797 try_save(ar, ser20::make_nvp(
"entities", entities));
799 static const std::string
version =
"1.0.0";
810template<
typename Archive>
811auto load_from_archive_impl(Archive& ar, entt::registry& registry) -> entt::handle
813 std::vector<entity_data<entt::handle>> entities;
814 try_load(ar, ser20::make_nvp(
"entities", entities));
819 entt::handle result{};
820 if(!entities.empty())
822 result = entities.front().components.entity;
826 load_ctx.entities.reserve(load_ctx.entities.size() + entities.size());
827 std::move(entities.begin(), entities.end(), std::back_inserter(load_ctx.entities));
832template<
typename Archive>
833void load_from_archive_start(Archive& ar, entt::registry& registry, entt::handle& e)
837 e = load_from_archive_impl(ar, registry);
842template<
typename Archive>
843auto load_from_archive_start(Archive& ar, entt::registry& registry) -> entt::handle
847 auto obj = load_from_archive_impl(ar, registry);
854template<
typename Archive>
855void load_from_archive(Archive& ar, entt::handle& obj)
857 obj = load_from_archive_start(ar, *obj.registry());
860template<
typename Archive>
861void save_to_archive(Archive& ar,
const entt::registry& reg)
867 [&](
auto e,
auto&& comp1,
auto&& comp2)
874 [&](
auto e,
auto&& comp1,
auto&& comp2)
876 save_to_archive(ar, entt::const_handle(reg, e));
882template<
typename Archive>
883void load_from_archive(Archive& ar, entt::registry& reg)
890 for(
size_t i = 0;
i <
count; ++
i)
892 entt::handle
e(reg, reg.create());
894 load_from_archive(ar, e);
911 save_to_archive(ar, obj);
913 catch(
const std::exception& e)
915 APPLOG_ERROR(
"Failed to save entity to stream: {}", e.what());
920void save_to_file(
const std::string& absolute_path, entt::const_handle obj)
924 std::ofstream stream(absolute_path);
928 save_ctx.save_source = obj;
929 save_ctx.to_prefab =
true;
933 save_ctx.to_prefab =
false;
934 save_ctx.save_source = {};
946 save_to_archive(ar, obj);
952 std::ofstream stream(absolute_path, std::ios::binary);
956 save_ctx.save_source = obj;
957 save_ctx.to_prefab =
true;
960 save_ctx.to_prefab =
false;
961 save_ctx.save_source = {};
974 load_from_archive(ar, obj);
976 catch(
const std::exception& e)
978 APPLOG_ERROR(
"Failed to load entity from view: {}", e.what());
991 load_from_archive(ar, obj);
993 catch(
const std::exception& e)
995 APPLOG_ERROR(
"Failed to load entity from stream: {}", e.what());
1003 if(!
input.is_open())
1018 load_from_archive(ar, obj);
1020 catch(
const std::exception& e)
1022 APPLOG_ERROR(
"Failed to load entity from stream: {}", e.what());
1030 if(!
input.is_open())
1038 entt::registry& registry,
1039 entt::handle& obj) ->
bool
1062 load_from_archive_start(ar, registry, obj);
1075 catch(
const std::exception& e)
1094 for(
auto child : transform->get_children())
1118 obj = load_from_archive_start(ar, registry);
1127 catch(
const std::exception& e)
1146 std::istream stream(&buffer);
1155 obj = load_from_archive_start(ar, registry);
1164 catch(
const std::exception& e)
1187 for(
auto child : transform_comp->get_children())
1207 save_ctx.save_source = src_obj;
1208 save_ctx.to_prefab =
false;
1209 save_ctx.clone_mode = clone_mode;
1210 std::stringstream ss;
1214 save_ctx.to_prefab =
false;
1215 save_ctx.save_source = {};
1222 load_ctx.clone_mode = clone_mode;
1240 save_to_archive(ar, *scn.
registry);
1242 catch(
const std::exception& e)
1244 APPLOG_ERROR(
"Failed to save scene to stream: {}", e.what());
1252 std::ofstream stream(absolute_path);
1264 save_to_archive(ar, *scn.
registry);
1266 catch(
const std::exception& e)
1268 APPLOG_ERROR(
"Failed to save scene to stream: {}", e.what());
1274 std::ofstream stream(absolute_path, std::ios::binary);
1287 load_from_archive(ar, *scn.
registry);
1289 catch(
const std::exception& e)
1291 APPLOG_ERROR(
"Failed to load scene from view: {}", e.what());
1307 load_from_archive(ar, *scn.
registry);
1309 catch(
const std::exception& e)
1311 APPLOG_ERROR(
"Failed to load scene from stream: {}", e.what());
1318 if(!
input.is_open())
1336 load_from_archive(ar, *scn.
registry);
1338 catch(
const std::exception& e)
1340 APPLOG_ERROR(
"Failed to load scene from stream: {}", e.what());
1347 if(!
input.is_open())
1367 load_from_archive(ar, *scn.registry);
1369 catch(
const std::exception& e)
1371 APPLOG_ERROR(
"Failed to load scene from prefab: {}", e.what());
1384 std::istream stream(&buffer);
1405 [&](
auto e,
auto&& comp1,
auto&& comp2)
1407 std::stringstream ss;
1410 auto e_clone = dst_scene.
registry->create();
stdio-backed input stream. Accepts std::ios open flags (e.g. std::ios::binary) when opening a
#define APPLOG_ERROR(...)
auto get_pretty_name(const meta_type &t) -> std::string
auto get_name(const meta_type &t) -> std::string
auto load_entity_from_prefab_uid(Archive &ar, entt::handle &obj, entity_flags flags) -> bool
auto load_entity_from_uuid(Archive &ar, entt::handle &obj, entity_flags flags) -> bool
void load_entity(Archive &ar, entt::handle &obj, entity_flags flags)
auto load_entity_from_id(Archive &ar, entt::handle &obj, entity_flags flags) -> bool
auto create_oarchive_associative(std::ostream &stream)
BinaryInputArchive iarchive_binary_t
void save_entity_uuid(Archive &ar, const entt::const_handle &obj)
auto create_iarchive_associative(std::istream &stream)
auto should_load_component(const entt::handle &obj) -> bool
simd::JSONOutputArchive oarchive_associative_t
auto should_save_component(const entt::const_handle &obj) -> bool
BinaryOutputArchive oarchive_binary_t
simd::JSONInputArchive iarchive_associative_t
void save_entity(Archive &ar, const entt::const_handle &obj, entity_flags flags)
void save_entity_id(Archive &ar, const entt::const_handle &obj)
void save_entity_prefab_uid(Archive &ar, const entt::const_handle &obj)
auto get_path_context() -> path_context *
auto push_save_context() -> bool
void regenerate_entity_uids(entt::handle obj)
auto are_related(entt::const_handle lhs, entt::const_handle rhs) -> bool
void save_to_stream_bin(std::ostream &stream, entt::const_handle obj)
void load_from(Stream &stream, T &scn)
auto push_entity_path(entt::const_handle obj) -> bool
void clone_scene_from_stream(const scene &src_scene, scene &dst_scene)
thread_local post_load_callbacks * post_load_callbacks_ptr
void pop_load_context(bool push_result)
void save_to_file_bin(const std::string &absolute_path, const animation_clip &obj)
auto get_post_load_callbacks() -> const post_load_callbacks *
auto push_load_context(entt::registry ®istry) -> bool
void pop_on_load_callbacks()
void pop_entity_path(bool pushed)
auto is_parent(entt::const_handle potential_parent, entt::const_handle child) -> bool
thread_local load_context * load_ctx_ptr
auto get_save_context() -> save_context &
void load_from_file(const std::string &absolute_path, animation_clip &obj)
auto get_load_context() -> load_context &
void save_to_file(const std::string &absolute_path, const animation_clip &obj)
auto load_from_prefab_bin(const asset_handle< prefab > &pfb, entt::registry ®istry) -> entt::handle
void add_to_uid_mapping(entt::handle &obj, bool recursive=true)
auto load_from_stream(std::istream &stream, entt::handle e, script_component::script_object &obj) -> bool
void load_from_stream_bin(std::istream &stream, entt::handle &obj)
auto load_from_prefab_out(const asset_handle< prefab > &pfb, entt::registry ®istry, entt::handle &obj) -> bool
thread_local save_context * save_ctx_ptr
void load_from_file_bin(const std::string &absolute_path, animation_clip &obj)
void pop_save_context(bool push_result)
std::tuple< id_component, tag_component, layer_component, prefab_component, prefab_id_component, transform_component, test_component, model_component, animation_component, bone_component, submesh_component, camera_component, volume_component, auto_exposure_component, tonemapping_component, assao_component, bloom_component, fxaa_component, taa_component, ssr_component, ssil_component, light_component, skylight_component, reflection_probe_component, physics_component, character_controller_component, audio_source_component, audio_listener_component, text_component, particle_emitter_component, ui_document_component, script_component > all_serializeable_components
auto has_prefab_component(const entt::const_handle &obj) -> bool
auto find_root(entt::const_handle e) -> entt::const_handle
auto const_handle_cast(entt::const_handle chandle) -> entt::handle
@ cloning_prefab_instance
void load_from_view(std::string_view view, entt::handle &obj)
void push_on_load_callbacks(const post_load_callbacks &callbacks)
void emit_on_load(entt::registry ®, entt::entity e)
auto as_span(const std::vector< entity_data< entt::handle > > &entities) -> hpp::span< const entt::handle >
void cleanup_uid_mapping()
auto load_from_prefab(const asset_handle< prefab > &pfb, entt::registry ®istry) -> entt::handle
void clone_entity_from_stream(entt::const_handle src_obj, entt::handle &dst_obj)
auto save_to_stream(std::ostream &stream, entt::const_handle e, const script_component::script_object &obj) -> bool
#define SAVE_INSTANTIATE(cls, Archive)
auto try_save(Archive &ar, ser20::NameValuePair< T > &&t, const hpp::source_location &loc=hpp::source_location::current()) -> bool
auto try_serialize_direct(Archive &ar, ser20::NameValuePair< T > &&t, const hpp::source_location &loc=hpp::source_location::current()) -> bool
#define LOAD_INSTANTIATE(cls, Archive)
#define LOAD_FUNCTION_NAME
auto serialize_check(const std::string &name, F &&serialize_callback) -> bool
auto try_load(Archive &ar, ser20::NameValuePair< T > &&t, const hpp::source_location &loc=hpp::source_location::current()) -> bool
#define SAVE_FUNCTION_NAME
Thread-safe handle to an asset.
auto get_stream_buf() const -> membuf
entity_components< Entity > components
hpp::uuid id
The unique identifier for the entity.
Component that provides a unique identifier (UUID) for an entity.
std::vector< entity_data< entt::handle > > entities
Component that holds a reference to a prefab asset and tracks property overrides.
asset_handle< prefab > source
Handle to the prefab asset.
Component that provides a unique identifier (UUID) for a prefab.
Represents a generic prefab with a buffer for serialized data.
fs::stream_buffer< std::vector< uint8_t > > buffer
Buffer to store serialized data of the prefab.
Root component structure for the ACE framework, serves as the base component.
Represents a scene in the ACE framework, managing entities and their relationships.
void unload()
Unloads the scene, removing all entities.
std::unique_ptr< entt::registry > registry
The registry that manages all entities in the scene.
auto create_handle(entt::entity e) -> entt::handle
Creates an entity in the scene.
YAML input and output archives.