15#include "entt/entity/fwd.hpp"
20#include <hpp/utility.hpp>
28 entt::handle
handle(*
const_cast<entt::handle::registry_type*
>(chandle.registry()), chandle.entity());
32template<
typename Entity>
38template<
typename Entity>
47 auto* base = entities.data();
52 auto* first_handle =
reinterpret_cast<const entt::handle*
>(
reinterpret_cast<const std::uint8_t*
>(base) + offset);
55 hpp::span<const entt::handle> handles{first_handle, entities.size()};
123 id_comp->generate_if_nil();
124 load_ctx.mapping_by_uid[id_comp->id].handle = obj;
130 for(
auto& entity_uuid : prefab_comp->removed_entities)
132 load_ctx.mapping_by_uid[entity_uuid].handle = {};
140 for(
auto child : trans_comp->get_children())
152 for(
auto& [uid, mapping] : load_ctx.mapping_by_uid)
154 if(!mapping.consumed && mapping.handle)
157 mapping.handle.destroy();
163auto is_parent(entt::const_handle potential_parent, entt::const_handle child) ->
bool
165 if(!potential_parent)
178 auto parent = transform->get_parent();
184 if(parent == potential_parent)
192auto find_root(entt::const_handle e) -> entt::const_handle
199 if(!transform || !transform->get_parent())
203 e = transform->get_parent();
208auto are_related(entt::const_handle lhs, entt::const_handle rhs) ->
bool
227 ctx->push_segment(id->id.to_string());
250template<
typename Archive>
253 entt::handle::entity_type
id = obj.valid() ? obj.entity() : entt::null;
254 try_save(ar, ser20::make_nvp(
"id",
id));
257template<
typename Archive>
265 try_save(ar, ser20::make_nvp(
"prefab_uid", id_comp.id));
269 try_save(ar, ser20::make_nvp(
"prefab_uid", hpp::uuid{}));
273template<
typename Archive>
277 if(save_ctx.is_saving_to_prefab())
285template<
typename Archive>
288 entt::handle::entity_type
id{};
289 bool valid =
try_load(ar, ser20::make_nvp(
"id",
id));
291 valid &=
id != entt::null &&
id != entt::handle::entity_type(0);
295 auto it = load_ctx.mapping_by_eid.find(
id);
296 if(it != load_ctx.mapping_by_eid.end())
303 load_ctx.mapping_by_eid[id] = obj;
308 if(flags == entity_flags::resolve_with_existing)
310 entt::handle check_entity(*load_ctx.reg,
id);
314 load_ctx.mapping_by_eid[id] = obj;
324 obj = entt::handle(*load_ctx.reg, load_ctx.reg->create());
325 load_ctx.mapping_by_eid[id] = obj;
335template<
typename Archive>
339 try_load(ar, ser20::make_nvp(
"prefab_uid", uid));
343 auto it = load_ctx.mapping_by_uid.find(uid);
344 if(it != load_ctx.mapping_by_uid.end())
347 obj = it->second.handle;
348 it->second.consumed =
true;
355template<
typename Archive>
360 if(load_ctx.is_updating_prefab())
376template<
typename Component>
379 if constexpr(std::is_same_v<Component, prefab_component>)
384 if(save_ctx.is_saving_to_prefab())
389 else if constexpr(std::is_same_v<Component, prefab_id_component>)
394 if(save_ctx.is_cloning())
396 if(save_ctx.get_clone_mode() != clone_mode_t::cloning_prefab_instance)
405template<
typename Component>
447 entt::const_handle to_save = obj.handle;
451 bool is_saving_single = save_ctx.save_source.valid();
455 bool save_source_is_parent =
is_parent(save_ctx.save_source, obj.handle);
458 if(!save_source_is_parent)
460 if(save_ctx.is_saving_to_prefab())
470 flags = entity_flags::resolve_with_existing;
475 if(!save_ctx.is_saving_to_prefab())
477 flags = entity_flags::resolve_with_existing;
482 try_save(ar, ser20::make_nvp(
"flags", flags));
491 try_load(ar, ser20::make_nvp(
"flags", flags));
503 hpp::for_each_tuple_type<unravel::all_serializeable_components>(
513 auto component = obj.entity.try_get<ctype>();
515 const auto type = entt::resolve<ctype>();
531 hpp::for_each_tuple_type<unravel::all_serializeable_components>(
542 auto component_type = entt::resolve<ctype>();
546 auto has_name =
"has_" +
name;
547 auto pretty_has_name =
"Has" + pretty_name;
550 bool has_component =
false;
552 bool success_has_component =
false;
559 if(!success_has_component)
570 auto& component = obj.entity.get_or_emplace<ctype>();
572 bool success_component =
false;
581 if(!success_component)
591 if constexpr(std::is_same_v<ctype, tag_component>)
593 auto& comp = obj.entity.get_or_emplace<ctype>();
596 if constexpr(std::is_same_v<ctype, layer_component>)
598 auto& comp = obj.entity.get_or_emplace<ctype>();
608 if(load_ctx.is_cloning())
610 if(load_ctx.get_clone_mode() != clone_mode_t::cloning_prefab_instance)
619 id_comp->regenerate_id();
629 try_save(ar, ser20::make_nvp(
"components", obj.components));
642 obj.components.entity = e;
643 try_load(ar, ser20::make_nvp(
"components", obj.components));
665 entities.emplace_back(data);
667 entities.reserve(entities.size() + children.size());
668 for(
const auto& child : children)
670 flatten_hierarchy(child, entities);
674template<
typename Archive>
675void save_to_archive(Archive& ar, entt::const_handle obj)
687 std::vector<entity_data<entt::const_handle>> entities;
688 flatten_hierarchy(obj, entities);
690 try_save(ar, ser20::make_nvp(
"entities", entities));
692 static const std::string
version =
"1.0.0";
703template<
typename Archive>
704auto load_from_archive_impl(Archive& ar, entt::registry& registry) -> entt::handle
706 std::vector<entity_data<entt::handle>> entities;
707 try_load(ar, ser20::make_nvp(
"entities", entities));
712 entt::handle result{};
713 if(!entities.empty())
715 result = entities.front().components.entity;
719 auto& ev = ctx.get_cached<
events>();
728 rsys.on_play_begin(span, dt);
735template<
typename Archive>
736void load_from_archive_start(Archive& ar, entt::registry& registry, entt::handle& e)
740 e = load_from_archive_impl(ar, registry);
745template<
typename Archive>
746auto load_from_archive_start(Archive& ar, entt::registry& registry) -> entt::handle
750 auto obj = load_from_archive_impl(ar, registry);
757template<
typename Archive>
758void load_from_archive(Archive& ar, entt::handle& obj)
760 obj = load_from_archive_start(ar, *obj.registry());
763template<
typename Archive>
764void save_to_archive(Archive& ar,
const entt::registry& reg)
770 [&](
auto e,
auto&& comp1,
auto&& comp2)
777 [&](
auto e,
auto&& comp1,
auto&& comp2)
779 save_to_archive(ar, entt::const_handle(reg, e));
785template<
typename Archive>
786void load_from_archive(Archive& ar, entt::registry& reg)
794 for(
size_t i = 0;
i <
count; ++
i)
796 entt::handle
e(reg, reg.create());
797 load_from_archive(ar, e);
814 save_to_archive(ar, obj);
816 catch(
const ser20::Exception& e)
818 APPLOG_ERROR(
"Failed to save entity to stream: {}", e.what());
823void save_to_file(
const std::string& absolute_path, entt::const_handle obj)
827 std::ofstream stream(absolute_path);
831 save_ctx.save_source = obj;
832 save_ctx.to_prefab =
true;
836 save_ctx.to_prefab =
false;
837 save_ctx.save_source = {};
849 save_to_archive(ar, obj);
855 std::ofstream stream(absolute_path, std::ios::binary);
859 save_ctx.save_source = obj;
860 save_ctx.to_prefab =
true;
863 save_ctx.to_prefab =
false;
864 save_ctx.save_source = {};
877 load_from_archive(ar, obj);
879 catch(
const ser20::Exception& e)
881 APPLOG_ERROR(
"Failed to load entity from view: {}", e.what());
894 load_from_archive(ar, obj);
896 catch(
const ser20::Exception& e)
898 APPLOG_ERROR(
"Failed to load entity from stream: {}", e.what());
905 std::ifstream stream(absolute_path);
917 load_from_archive(ar, obj);
919 catch(
const ser20::Exception& e)
921 APPLOG_ERROR(
"Failed to load entity from stream: {}", e.what());
930 std::ifstream stream(absolute_path, std::ios::binary);
935 entt::registry& registry,
936 entt::handle& obj) ->
bool
959 load_from_archive_start(ar, registry, obj);
972 catch(
const ser20::Exception& e)
1002 obj = load_from_archive_start(ar, registry);
1011 catch(
const ser20::Exception& e)
1030 std::istream stream(&buffer);
1039 obj = load_from_archive_start(ar, registry);
1047 catch(
const ser20::Exception& e)
1065 save_ctx.save_source = src_obj;
1066 save_ctx.to_prefab =
false;
1067 save_ctx.clone_mode = clone_mode;
1072 std::ofstream ss(
"./clone.ecs");
1076 save_ctx.to_prefab =
false;
1077 save_ctx.save_source = {};
1084 load_ctx.clone_mode = clone_mode;
1087 std::ifstream ss(
"./clone.ecs");
1104 save_to_archive(ar, *scn.
registry);
1106 catch(
const ser20::Exception& e)
1108 APPLOG_ERROR(
"Failed to save scene to stream: {}", e.what());
1116 std::ofstream stream(absolute_path);
1128 save_to_archive(ar, *scn.
registry);
1130 catch(
const ser20::Exception& e)
1132 APPLOG_ERROR(
"Failed to save scene to stream: {}", e.what());
1138 std::ofstream stream(absolute_path, std::ios::binary);
1151 load_from_archive(ar, *scn.
registry);
1153 catch(
const ser20::Exception& e)
1155 APPLOG_ERROR(
"Failed to load scene from view: {}", e.what());
1171 load_from_archive(ar, *scn.
registry);
1173 catch(
const ser20::Exception& e)
1175 APPLOG_ERROR(
"Failed to load scene from stream: {}", e.what());
1183 std::ifstream stream(absolute_path);
1197 load_from_archive(ar, *scn.
registry);
1199 catch(
const ser20::Exception& e)
1201 APPLOG_ERROR(
"Failed to load scene from stream: {}", e.what());
1209 std::ifstream stream(absolute_path, std::ios::binary);
1225 load_from_archive(ar, *scn.registry);
1227 catch(
const ser20::Exception& e)
1229 APPLOG_ERROR(
"Failed to load scene from prefab: {}", e.what());
1242 std::istream stream(&buffer);
1263 [&](
auto e,
auto&& comp1,
auto&& comp2)
1265 std::stringstream ss;
1268 auto e_clone = dst_scene.
registry->create();
Base class for different rendering paths in the ACE framework.
void on_play_begin(hpp::span< const entt::handle > entities, delta_t dt)
std::chrono::duration< float > delta_t
#define APPLOG_ERROR(...)
auto get_pretty_name(const meta_type &t) -> std::string
auto get_name(const meta_type &t) -> std::string
void load_entity(Archive &ar, entt::handle &obj, entity_flags flags)
void save_entity_uid(Archive &ar, const entt::const_handle &obj)
auto load_entity_from_id(Archive &ar, entt::handle &obj, entity_flags flags) -> bool
auto load_entity_from_uid(Archive &ar, entt::handle &obj, entity_flags flags) -> bool
auto create_oarchive_associative(std::ostream &stream)
BinaryInputArchive iarchive_binary_t
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)
auto get_path_context() -> path_context *
auto push_save_context() -> bool
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)
void pop_load_context(bool push_result)
void save_to_file_bin(const std::string &absolute_path, const animation_clip &obj)
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, assao_component, tonemapping_component, fxaa_component, ssr_component, light_component, skylight_component, reflection_probe_component, physics_component, audio_source_component, audio_listener_component, text_component, script_component, ui_document_component > all_serializeable_components
auto push_load_context(entt::registry ®istry) -> bool
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)
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)
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
Represents a handle to an asset, providing access and management functions.
auto get_stream_buf() const -> membuf
static auto context() -> rtti::context &
entity_components< Entity > components
Component that provides a unique identifier (UUID) for an entity.
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.