10#include <monopp/mono_field_invoker.h>
11#include <monopp/mono_property_invoker.h>
32 struct script_component_loader_context
36 auto get_script_object(
size_t hash) -> script_component::script_object*
40 if(obj.scoped->object.get_type().get_hash() == hash)
49 thread_local script_component_loader_context* script_component_loader_ctx{};
54 entt::meta_factory<script_component>{}
55 .type(
"script_component"_hs)
68template<
typename Archive,
typename T>
71 template<
typename Invoker>
73 const mono::mono_object& obj,
74 const Invoker& invoker) ->
bool
76 auto& ar =
static_cast<Archive&
>(arbase);
77 auto val = invoker.get_value(obj);
78 return try_save(ar, ser20::make_nvp(invoker.get_name(), val));
82 const mono::mono_object& obj,
83 const mono::mono_field& field) ->
bool
85 auto invoker = mono::make_field_invoker<T>(field);
90 const mono::mono_object& obj,
91 const mono::mono_property& prop) ->
bool
93 auto invoker = mono::make_property_invoker<T>(prop);
98template<
typename Archive>
101 template<
typename Invoker>
103 const mono::mono_object& obj,
104 const Invoker& invoker) ->
bool
106 auto& ar =
static_cast<Archive&
>(arbase);
107 auto val = invoker.get_value(obj);
110 auto& ec = ctx.get_cached<
ecs>();
111 auto&
scene = ec.get_scene();
115 return try_save(ar, ser20::make_nvp(invoker.get_name(), e));
119 const mono::mono_object& obj,
120 const mono::mono_field& field) ->
bool
122 auto invoker = mono::make_field_invoker<entt::entity>(field);
127 const mono::mono_object& obj,
128 const mono::mono_property& prop) ->
bool
130 auto invoker = mono::make_property_invoker<entt::entity>(prop);
135template<
typename Archive,
typename T>
138 template<
typename Invoker>
140 const mono::mono_object& obj,
141 const Invoker& invoker) ->
bool
143 auto& ar =
static_cast<Archive&
>(arbase);
145 auto val = invoker.get_value(obj);
150 const auto& invoker_type = invoker.get_type();
151 auto guid_property = invoker_type.get_property(
"uid");
152 auto mutable_uid_property = mono::make_property_invoker<hpp::uuid>(guid_property);
153 auto uid = mutable_uid_property.get_value(val);
160 return try_save(ar, ser20::make_nvp(invoker.get_name(), asset));
164 const mono::mono_object& obj,
165 const mono::mono_field& field) ->
bool
167 auto invoker = mono::make_field_invoker<mono::mono_object>(field);
172 const mono::mono_object& obj,
173 const mono::mono_property& prop) ->
bool
175 auto invoker = mono::make_property_invoker<mono::mono_object>(prop);
180template<
typename Archive,
typename T>
186 return mono::is_compatible_type<U>(
type);
189 template<
typename Invoker>
191 mono::mono_object& obj,
192 const Invoker& invoker) ->
bool
194 auto& ar =
static_cast<Archive&
>(arbase);
199 if(
try_load(ar, ser20::make_nvp(invoker.get_name(), val)))
201 invoker.set_value(obj, val);
209 mono::mono_object& obj,
210 mono::mono_field& field) ->
bool
212 auto invoker = mono::make_field_invoker<T>(field);
217 mono::mono_object& obj,
218 mono::mono_property& prop) ->
bool
220 auto invoker = mono::make_property_invoker<T>(prop);
225template<
typename Archive>
231 const auto& expected_name =
type.get_name();
232 bool is_supported = std::is_same_v<entt::entity, U> && expected_name ==
"Entity";
236 template<
typename Invoker>
238 mono::mono_object& obj,
239 const Invoker& invoker) ->
bool
241 auto& ar =
static_cast<Archive&
>(arbase);
246 if(
try_load(ar, ser20::make_nvp(invoker.get_name(), val)))
248 invoker.set_value(obj, val.handle.entity());
256 mono::mono_object& obj,
257 mono::mono_field& field) ->
bool
259 auto invoker = mono::make_field_invoker<entt::entity>(field);
264 mono::mono_object& obj,
265 mono::mono_property& prop) ->
bool
267 auto invoker = mono::make_property_invoker<entt::entity>(prop);
272template<
typename Archive,
typename T>
278 const auto& expected_name =
type.get_name();
279 bool is_supported =
false;
283 is_supported |= std::is_same_v<asset_handle<gfx::texture>, U> && expected_name ==
"Texture";
287 is_supported |= std::is_same_v<asset_handle<material>, U> && expected_name ==
"Material";
291 is_supported |= std::is_same_v<asset_handle<mesh>, U> && expected_name ==
"Mesh";
295 is_supported |= std::is_same_v<asset_handle<animation_clip>, U> && expected_name ==
"AnimationClip";
299 is_supported |= std::is_same_v<asset_handle<prefab>, U> && expected_name ==
"Prefab";
303 is_supported |= std::is_same_v<asset_handle<scene_prefab>, U> && expected_name ==
"Scene";
307 is_supported |= std::is_same_v<asset_handle<physics_material>, U> && expected_name ==
"PhysicsMaterial";
311 is_supported |= std::is_same_v<asset_handle<audio_clip>, U> && expected_name ==
"AudioClip";
315 is_supported |= std::is_same_v<asset_handle<font>, U> && expected_name ==
"Font";
320 template<
typename Invoker>
322 mono::mono_object& obj,
323 const Invoker& invoker) ->
bool
325 auto& ar =
static_cast<Archive&
>(arbase);
330 if(
try_load(ar, ser20::make_nvp(invoker.get_name(), val)))
332 const auto& field_type = invoker.get_type();
333 auto guid_property = field_type.get_property(
"uid");
334 auto mutable_uid_property = mono::make_property_invoker<hpp::uuid>(guid_property);
336 auto var = invoker.get_value(obj);
339 var = field_type.new_instance();
340 invoker.set_value(obj, var);
345 mutable_uid_property.set_value(var, val.uid());
354 mono::mono_object& obj,
355 mono::mono_field& field) ->
bool
357 auto invoker = mono::make_field_invoker<mono::mono_object>(field);
362 mono::mono_object& obj,
363 mono::mono_property& prop) ->
bool
365 auto invoker = mono::make_property_invoker<mono::mono_object>(prop);
372 using mono_field_serializer =
373 std::function<bool(ser20::detail::OutputArchiveBase&,
const mono::mono_object&,
const mono::mono_field&)>;
375 auto get_field_serilizer = [](
const std::string& type_name) ->
const mono_field_serializer&
378 static std::map<std::string, mono_field_serializer> reg = {
414 auto it = reg.find(type_name);
419 static const mono_field_serializer empty;
423 using mono_property_serializer =
424 std::function<bool(ser20::detail::OutputArchiveBase&,
const mono::mono_object&,
const mono::mono_property&)>;
426 auto get_property_serilizer = [](
const std::string& type_name) ->
const mono_property_serializer&
429 static std::map<std::string, mono_property_serializer> reg = {
467 auto it = reg.find(type_name);
472 static const mono_property_serializer empty;
476 const auto&
object = obj.scoped->object;
477 const auto&
type =
object.get_type();
479 try_save(ar, ser20::make_nvp(
"type",
type.get_fullname()));
481 auto fields =
type.get_fields();
482 auto properties =
type.get_properties();
483 for(
auto& field : fields)
485 if(field.get_visibility() == mono::visibility::vis_public)
487 const auto& field_type = field.get_type();
489 auto field_serilizer = get_field_serilizer(field_type.get_name());
492 field_serilizer(ar,
object, field);
494 else if(field_type.is_enum())
496 auto enum_type = field_type.get_enum_base_type();
498 auto enum_serilizer = get_field_serilizer(enum_type.get_name());
501 enum_serilizer(ar,
object, field);
507 for(
auto& prop : properties)
509 if(prop.get_visibility() == mono::visibility::vis_public)
511 const auto& prop_type = prop.get_type();
513 auto prop_serilizer = get_property_serilizer(prop_type.get_name());
516 prop_serilizer(ar,
object, prop);
518 else if(prop_type.is_enum())
520 auto enum_type = prop_type.get_enum_base_type();
522 auto enum_serilizer = get_property_serilizer(enum_type.get_name());
525 enum_serilizer(ar,
object, prop);
543 auto it = std::find_if(std::begin(all_scriptable_components),
544 std::end(all_scriptable_components),
545 [&](
const mono::mono_type& script_type)
547 return type == script_type.get_fullname();
550 if(it == std::end(all_scriptable_components))
557 const auto& script_type = *it;
559 auto* existing_obj = script_component_loader_ctx
560 ? script_component_loader_ctx->get_script_object(script_type.get_hash())
568 auto object = script_type.new_instance();
572 using mono_field_serializer =
573 std::function<bool(ser20::detail::InputArchiveBase&, mono::mono_object&, mono::mono_field&)>;
575 auto get_field_serilizer = [](
const std::string& type_name) ->
const mono_field_serializer&
578 static const std::map<std::string, mono_field_serializer> reg = {
617 auto it = reg.find(type_name);
622 static const mono_field_serializer empty;
626 using mono_property_serializer =
627 std::function<bool(ser20::detail::InputArchiveBase&, mono::mono_object&, mono::mono_property&)>;
629 auto get_property_serilizer = [](
const std::string& type_name) ->
const mono_property_serializer&
632 static const std::map<std::string, mono_property_serializer> reg = {
668 auto it = reg.find(type_name);
673 static const mono_property_serializer empty;
677 auto fields = script_type.get_fields();
678 auto properties = script_type.get_properties();
680 for(
auto& field : fields)
682 if(field.get_visibility() == mono::visibility::vis_public)
684 const auto& field_type = field.get_type();
686 auto field_serilizer = get_field_serilizer(field_type.get_name());
689 field_serilizer(ar, obj.scoped->object, field);
691 else if(field_type.is_enum())
693 auto enum_type = field_type.get_enum_base_type();
695 auto enum_serilizer = get_field_serilizer(enum_type.get_name());
698 enum_serilizer(ar, obj.scoped->object, field);
703 for(
auto& prop : properties)
705 if(prop.get_visibility() == mono::visibility::vis_public)
707 const auto& prop_type = prop.get_type();
709 auto prop_serilizer = get_property_serilizer(prop_type.get_name());
712 prop_serilizer(ar, obj.scoped->object, prop);
714 else if(prop_type.is_enum())
716 auto enum_type = prop_type.get_enum_base_type();
718 auto enum_serilizer = get_property_serilizer(enum_type.get_name());
721 enum_serilizer(ar, obj.scoped->object, prop);
732 const auto& comps = obj.get_script_components();
733 try_save(ar, ser20::make_nvp(
"script_components", comps));
743 if(load_ctx.is_updating_prefab())
746 script_component_loader_context ctx;
747 ctx.script_objects = obj.get_script_components();
748 script_component_loader_ctx = &ctx;
752 if(
try_load(ar, ser20::make_nvp(
"script_components", comps)))
754 obj.add_missing_script_components(comps);
757 script_component_loader_ctx =
nullptr;
762 if(
try_load(ar, ser20::make_nvp(
"script_components", comps)))
764 obj.add_script_components(comps);
779 save_ctx.save_source = e;
780 save_ctx.to_prefab =
false;
782 bool was_successful =
false;
786 ar(ser20::make_nvp(
"script_object", obj));
787 was_successful =
true;
789 catch(
const ser20::Exception& e)
791 APPLOG_ERROR(
"Failed to save script component to stream: {}", e.what());
794 save_ctx.to_prefab =
false;
795 save_ctx.save_source = {};
797 return was_successful;
803 bool was_successful =
false;
807 ar(ser20::make_nvp(
"script_object", obj));
808 was_successful =
true;
810 catch(
const ser20::Exception& e)
812 APPLOG_ERROR(
"Failed to load script component from stream: {}", e.what());
815 return was_successful;
Manages assets, including loading, unloading, and storage.
auto get_asset(const std::string &key, load_flags flags=load_flags::standard) -> asset_handle< T >
Gets an asset by its key.
Class that contains core data for audio listeners. There can only be one instance of it per scene.
std::vector< script_object > script_components_t
#define APPLOG_ERROR(...)
attributes::value_type attribute
std::map< std::string, meta_any > attributes
BinaryInputArchive iarchive_binary_t
simd::JSONOutputArchive oarchive_associative_t
BinaryOutputArchive oarchive_binary_t
simd::JSONInputArchive iarchive_associative_t
auto push_save_context() -> bool
void pop_load_context(bool push_result)
auto push_load_context(entt::registry ®istry) -> bool
auto get_save_context() -> save_context &
auto get_load_context() -> load_context &
auto load_from_stream(std::istream &stream, entt::handle e, script_component::script_object &obj) -> bool
void pop_save_context(bool push_result)
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
#define LOAD_INSTANTIATE(cls, Archive)
auto try_load(Archive &ar, ser20::NameValuePair< T > &&t, const hpp::source_location &loc=hpp::source_location::current()) -> bool
Represents a handle to an asset, providing access and management functions.
Manages the entity-component-system (ECS) operations for the ACE framework.
static auto context() -> rtti::context &
static auto is_supported_type(const mono::mono_type &type) -> bool
static auto try_load_mono_field(ser20::detail::InputArchiveBase &arbase, mono::mono_object &obj, mono::mono_field &field) -> bool
static auto try_load_mono_property(ser20::detail::InputArchiveBase &arbase, mono::mono_object &obj, mono::mono_property &prop) -> bool
static auto try_load_mono_invoker(ser20::detail::InputArchiveBase &arbase, mono::mono_object &obj, const Invoker &invoker) -> bool
static auto try_load_mono_invoker(ser20::detail::InputArchiveBase &arbase, mono::mono_object &obj, const Invoker &invoker) -> bool
static auto try_load_mono_property(ser20::detail::InputArchiveBase &arbase, mono::mono_object &obj, mono::mono_property &prop) -> bool
static auto is_supported_type(const mono::mono_type &type) -> bool
static auto try_load_mono_field(ser20::detail::InputArchiveBase &arbase, mono::mono_object &obj, mono::mono_field &field) -> bool
static auto try_load_mono_invoker(ser20::detail::InputArchiveBase &arbase, mono::mono_object &obj, const Invoker &invoker) -> bool
static auto try_load_mono_field(ser20::detail::InputArchiveBase &arbase, mono::mono_object &obj, mono::mono_field &field) -> bool
static auto is_supported_type(const mono::mono_type &type) -> bool
static auto try_load_mono_property(ser20::detail::InputArchiveBase &arbase, mono::mono_object &obj, mono::mono_property &prop) -> bool
static auto try_save_mono_property(ser20::detail::OutputArchiveBase &arbase, const mono::mono_object &obj, const mono::mono_property &prop) -> bool
static auto try_save_mono_invoker(ser20::detail::OutputArchiveBase &arbase, const mono::mono_object &obj, const Invoker &invoker) -> bool
static auto try_save_mono_field(ser20::detail::OutputArchiveBase &arbase, const mono::mono_object &obj, const mono::mono_field &field) -> bool
static auto try_save_mono_field(ser20::detail::OutputArchiveBase &arbase, const mono::mono_object &obj, const mono::mono_field &field) -> bool
static auto try_save_mono_invoker(ser20::detail::OutputArchiveBase &arbase, const mono::mono_object &obj, const Invoker &invoker) -> bool
static auto try_save_mono_property(ser20::detail::OutputArchiveBase &arbase, const mono::mono_object &obj, const mono::mono_property &prop) -> bool
static auto try_save_mono_invoker(ser20::detail::OutputArchiveBase &arbase, const mono::mono_object &obj, const Invoker &invoker) -> bool
static auto try_save_mono_field(ser20::detail::OutputArchiveBase &arbase, const mono::mono_object &obj, const mono::mono_field &field) -> bool
static auto try_save_mono_property(ser20::detail::OutputArchiveBase &arbase, const mono::mono_object &obj, const mono::mono_property &prop) -> bool
Represents a scene in the ACE framework, managing entities and their relationships.
auto create_handle(entt::entity e) -> entt::handle
Creates an entity in the scene.
auto get_all_scriptable_components() const -> const std::vector< mono::mono_type > &