5#include <monopp/mono_field_invoker.h>
6#include <monopp/mono_property_invoker.h>
26auto find_attribute(
const std::string&
name,
const std::vector<mono::mono_object>& attribs) -> mono::mono_object
28 auto it = std::find_if(std::begin(attribs),
30 [&](
const mono::mono_object& obj)
32 return obj.get_type().get_name() ==
name;
35 if(it != std::end(attribs))
71 auto fullname =
type.get_fullname();
72 return fullname.find(
"System.Collections.Generic.List<") == 0;
85 return type.get_element_type();
91 auto item_prop =
type.get_property(
"Item");
92 if (item_prop.get_internal_ptr())
94 return item_prop.get_type();
107template<
typename Invoker>
111 auto field_name = mutable_field.get_name();
113 nested_proxy.
impl->get_name = [obj_proxy, field_name]()
115 auto parent_name = obj_proxy.impl->get_name();
116 if(parent_name.empty())
120 return fmt::format(
"{}/{}", parent_name, field_name);
123 nested_proxy.
impl->getter = [obj_proxy, field_name](entt::meta_any& result)
mutable
125 entt::meta_any obj_var;
126 if(obj_proxy.impl->getter(obj_var) && obj_var)
128 auto& mono_obj = obj_var.cast<mono::mono_object&>();
131 auto obj_type = mono_obj.get_type();
132 auto field = obj_type.get_field(field_name);
133 auto invoker = mono::make_field_invoker<mono::mono_object>(field);
135 auto nested_obj = invoker.get_value(mono_obj);
136 if(nested_obj.valid())
139 result = entt::meta_any{std::in_place_type<mono::mono_object>, nested_obj};
146 nested_proxy.
impl->setter = [obj_proxy, field_name](
meta_any_proxy& proxy,
const entt::meta_any& value, uint64_t execution_count)
mutable
148 entt::meta_any obj_var;
149 if(obj_proxy.impl->getter(obj_var) && obj_var)
151 auto& mono_obj = obj_var.cast<mono::mono_object&>();
152 if(value.allow_cast<mono::mono_object>())
155 auto obj_type = mono_obj.get_type();
156 auto field = obj_type.get_field(field_name);
157 auto invoker = mono::make_field_invoker<mono::mono_object>(field);
159 auto nested_obj = value.cast<mono::mono_object>();
160 invoker.set_value(mono_obj, nested_obj);
161 return obj_proxy.impl->setter(proxy, obj_var, execution_count);
176template<
typename Invoker>
180 auto prop_name = mutable_property.get_name();
182 nested_proxy.
impl->get_name = [obj_proxy, prop_name]()
184 auto parent_name = obj_proxy.impl->get_name();
185 if(parent_name.empty())
189 return fmt::format(
"{}/{}", parent_name, prop_name);
192 nested_proxy.
impl->getter = [obj_proxy, prop_name](entt::meta_any& result)
mutable
194 entt::meta_any obj_var;
195 if(obj_proxy.impl->getter(obj_var) && obj_var)
197 auto& mono_obj = obj_var.cast<mono::mono_object&>();
200 auto obj_type = mono_obj.get_type();
201 auto property = obj_type.get_property(prop_name);
202 auto invoker = mono::make_property_invoker<mono::mono_object>(property);
204 auto nested_obj = invoker.get_value(mono_obj);
205 if(nested_obj.valid())
208 result = entt::meta_any{std::in_place_type<mono::mono_object>, nested_obj};
215 nested_proxy.
impl->setter = [obj_proxy, prop_name](
meta_any_proxy& proxy,
const entt::meta_any& value, uint64_t execution_count)
mutable
217 entt::meta_any obj_var;
218 if(obj_proxy.impl->getter(obj_var) && obj_var)
220 auto& mono_obj = obj_var.cast<mono::mono_object&>();
221 if(value.allow_cast<mono::mono_object>())
224 auto obj_type = mono_obj.get_type();
225 auto property = obj_type.get_property(prop_name);
226 auto invoker = mono::make_property_invoker<mono::mono_object>(property);
228 auto nested_obj = value.cast<mono::mono_object>();
229 invoker.set_value(mono_obj, nested_obj);
230 return obj_proxy.impl->setter(proxy, obj_var, execution_count);
241 mono::mono_object& obj,
242 const meta_any_proxy& obj_proxy,
243 const std::string&
name,
244 const var_info& info) -> inspect_result;
264 auto invoker = mono::make_field_invoker<T>(
field);
265 return invoker.get_value(obj);
268 void set_value(mono::mono_object& obj,
const T& value)
const
270 auto invoker = mono::make_field_invoker<T>(
field);
271 invoker.set_value(obj, value);
276 return field.get_attributes();
281 return field.get_type();
306 auto invoker = mono::make_property_invoker<T>(
property);
307 return invoker.get_value(obj);
310 void set_value(mono::mono_object& obj,
const T& value)
const
312 auto invoker = mono::make_property_invoker<T>(
property);
313 invoker.set_value(obj, value);
318 return property.get_attributes();
323 return property.get_type();
335template<
typename T,
typename ProxyType>
340 field_proxy.
impl->get_name = [obj_proxy, script_proxy]()
342 auto parent_name = obj_proxy.impl->get_name();
343 if(parent_name.empty())
345 return script_proxy.get_name();
347 return fmt::format(
"{}/{}", parent_name, script_proxy.get_name());
350 field_proxy.
impl->getter = [obj_proxy, script_proxy](entt::meta_any& result)
mutable
352 entt::meta_any obj_var;
353 if(obj_proxy.impl->getter(obj_var) && obj_var)
355 auto& mono_obj = obj_var.cast<mono::mono_object&>();
356 auto field_value = script_proxy.get_value(mono_obj);
358 result = entt::meta_any{std::in_place_type<T>, field_value};
364 field_proxy.
impl->setter = [obj_proxy, script_proxy](
meta_any_proxy& proxy,
const entt::meta_any& value, uint64_t execution_count)
mutable
366 entt::meta_any obj_var;
367 if(obj_proxy.impl->getter(obj_var) && obj_var)
369 auto& mono_obj = obj_var.cast<mono::mono_object&>();
370 if(value.allow_cast<T>())
372 script_proxy.set_value(mono_obj, value.cast<T>());
373 return obj_proxy.impl->setter(proxy, obj_var, execution_count);
388 template<
typename Invoker>
392 auto field_name = mutable_field.get_name();
394 handle_proxy.
impl->get_name = [obj_proxy, field_name]()
396 auto parent_name = obj_proxy.impl->get_name();
397 if(parent_name.empty())
401 return fmt::format(
"{}/{}", parent_name, field_name);
404 handle_proxy.
impl->getter = [obj_proxy, field_name, &ctx](entt::meta_any& result)
mutable
406 entt::meta_any obj_var;
407 if(obj_proxy.impl->getter(obj_var) && obj_var)
409 auto& mono_obj = obj_var.cast<mono::mono_object&>();
412 auto obj_type = mono_obj.get_type();
413 auto field = obj_type.get_field(field_name);
414 auto invoker = mono::make_field_invoker<entt::entity>(field);
416 auto entity = invoker.get_value(mono_obj);
417 auto& ec = ctx.get_cached<
ecs>();
418 auto&
scene = ec.get_scene();
421 result = entt::meta_any{std::in_place_type<entt::handle>,
handle};
427 handle_proxy.
impl->setter = [obj_proxy, field_name](
meta_any_proxy& proxy,
const entt::meta_any& value, uint64_t execution_count)
mutable
429 entt::meta_any obj_var;
430 if(obj_proxy.impl->getter(obj_var) && obj_var)
432 auto& mono_obj = obj_var.cast<mono::mono_object&>();
433 if(value.allow_cast<entt::handle>())
436 auto obj_type = mono_obj.get_type();
437 auto field = obj_type.get_field(field_name);
438 auto invoker = mono::make_field_invoker<entt::entity>(field);
440 auto handle = value.cast<entt::handle>();
441 invoker.set_value(mono_obj,
handle.entity());
442 return obj_proxy.impl->setter(proxy, obj_var, execution_count);
457template<
typename T,
typename Invoker>
461 auto field_name = mutable_field.get_name();
463 asset_proxy.
impl->get_name = [obj_proxy, field_name]()
465 auto parent_name = obj_proxy.impl->get_name();
466 if(parent_name.empty())
470 return fmt::format(
"{}/{}", parent_name, field_name);
473 asset_proxy.
impl->getter = [obj_proxy, field_name, &ctx](entt::meta_any& result)
mutable
475 entt::meta_any obj_var;
476 if(obj_proxy.impl->getter(obj_var) && obj_var)
478 auto& mono_obj = obj_var.cast<mono::mono_object&>();
481 auto obj_type = mono_obj.get_type();
482 auto field = obj_type.get_field(field_name);
483 auto invoker = mono::make_field_invoker<mono::mono_object>(field);
485 auto val = invoker.get_value(mono_obj);
491 const auto& field_type = invoker.get_type();
492 auto prop = field_type.get_property(
"uid");
493 auto mutable_prop = mono::make_property_invoker<hpp::uuid>(prop);
494 auto uid = mutable_prop.get_value(val);
497 asset = am.get_asset<T>(uid);
501 result = entt::meta_any{std::in_place_type<asset_handle<T>>, asset};
507 asset_proxy.
impl->setter = [obj_proxy, field_name](
meta_any_proxy& proxy,
const entt::meta_any& value, uint64_t execution_count)
mutable
509 entt::meta_any obj_var;
510 if(obj_proxy.impl->getter(obj_var) && obj_var)
512 auto& mono_obj = obj_var.cast<mono::mono_object&>();
516 auto obj_type = mono_obj.get_type();
517 auto field = obj_type.get_field(field_name);
518 auto invoker = mono::make_field_invoker<mono::mono_object>(field);
521 const auto& field_type = invoker.get_type();
523 auto val = invoker.get_value(mono_obj);
526 val = field_type.new_instance();
527 invoker.set_value(mono_obj, val);
532 auto prop = field_type.get_property(
"uid");
533 auto mutable_prop = mono::make_property_invoker<hpp::uuid>(prop);
534 mutable_prop.set_value(val, asset.uid());
537 return obj_proxy.impl->setter(proxy, obj_var, execution_count);
557 element_proxy.
impl->get_name = [array_proxy, element_name]()
559 auto parent_name = array_proxy.impl->get_name();
560 if(parent_name.empty())
564 return fmt::format(
"{}/{}", parent_name, element_name);
567 element_proxy.
impl->getter = [array_proxy, index](entt::meta_any& result)
mutable
569 entt::meta_any array_var;
570 if(array_proxy.impl->getter(array_var) && array_var)
572 auto& array_obj = array_var.cast<mono::mono_object&>();
573 mono::mono_array<T> array(array_obj);
575 if(index < array.size())
577 auto element_value = array.get(index);
579 result = entt::meta_any{std::in_place_type<T>, element_value};
586 element_proxy.
impl->setter = [array_proxy, index](
meta_any_proxy& proxy,
const entt::meta_any& value, uint64_t execution_count)
mutable
588 entt::meta_any array_var;
589 if(array_proxy.impl->getter(array_var) && array_var)
591 auto& array_obj = array_var.cast<mono::mono_object&>();
592 if(value.allow_cast<T>())
594 mono::mono_array<T> array(array_obj);
596 if(index < array.size())
598 array.set(index, value.cast<T>());
601 auto mutable_array_proxy = array_proxy;
602 return mutable_array_proxy.impl->setter(mutable_array_proxy, array_var, execution_count);
609 return element_proxy;
617 mono::mono_object& obj,
619 mono::mono_field& field,
622 auto invoker = mono::make_field_invoker<T>(field);
634 mono::mono_object& obj,
636 mono::mono_field& field,
647 if(!field_proxy.impl->getter(var))
660 auto tooltip_attrib =
find_attribute(
"TooltipAttribute", attribs);
663 if(tooltip_attrib.valid())
665 auto invoker = mono::make_field_invoker<std::string>(tooltip_attrib.get_type(),
"tooltip");
666 tooltip = invoker.get_value(tooltip_attrib);
671 if(min_attrib.valid())
673 auto invoker = mono::make_field_invoker<float>(min_attrib.get_type(),
"min");
674 float min_value = invoker.get_value(min_attrib);
675 meta_attribs[
"min"] = min_value;
678 if(range_attrib.valid())
680 auto invoker = mono::make_field_invoker<float>(range_attrib.get_type(),
"min");
681 float min_value = invoker.get_value(range_attrib);
682 meta_attribs[
"min"] = min_value;
684 auto max_invoker = mono::make_field_invoker<float>(range_attrib.get_type(),
"max");
685 float max_value = max_invoker.get_value(range_attrib);
686 meta_attribs[
"max"] = max_value;
689 if(max_attrib.valid())
691 auto invoker = mono::make_field_invoker<float>(max_attrib.get_type(),
"max");
692 float max_value = invoker.get_value(max_attrib);
693 meta_attribs[
"max"] = max_value;
696 if(step_attrib.valid())
698 auto invoker = mono::make_field_invoker<float>(step_attrib.get_type(),
"step");
699 float step_value = invoker.get_value(step_attrib);
700 meta_attribs[
"step"] = step_value;
707 result |=
inspect_var(ctx, var, field_proxy, info, custom);
714 mono::mono_object& obj,
716 mono::mono_property& property,
719 auto invoker = mono::make_property_invoker<T>(property);
731 mono::mono_object& obj,
733 mono::mono_property& property,
744 if(!prop_proxy.impl->getter(var))
757 auto tooltip_attrib =
find_attribute(
"TooltipAttribute", attribs);
760 if(tooltip_attrib.valid())
762 auto invoker = mono::make_field_invoker<std::string>(tooltip_attrib.get_type(),
"tooltip");
763 tooltip = invoker.get_value(tooltip_attrib);
768 if(min_attrib.valid())
770 auto invoker = mono::make_field_invoker<float>(min_attrib.get_type(),
"min");
771 float min_value = invoker.get_value(min_attrib);
772 meta_attribs[
"min"] = min_value;
775 if(range_attrib.valid())
777 auto invoker = mono::make_field_invoker<float>(range_attrib.get_type(),
"min");
778 float min_value = invoker.get_value(range_attrib);
779 meta_attribs[
"min"] = min_value;
781 auto max_invoker = mono::make_field_invoker<float>(range_attrib.get_type(),
"max");
782 float max_value = max_invoker.get_value(range_attrib);
783 meta_attribs[
"max"] = max_value;
786 if(max_attrib.valid())
788 auto invoker = mono::make_field_invoker<float>(max_attrib.get_type(),
"max");
789 float max_value = invoker.get_value(max_attrib);
790 meta_attribs[
"max"] = max_value;
793 if(step_attrib.valid())
795 auto invoker = mono::make_field_invoker<float>(step_attrib.get_type(),
"step");
796 float step_value = invoker.get_value(step_attrib);
797 meta_attribs[
"step"] = step_value;
804 result |=
inspect_var(ctx, var, prop_proxy, info, custom);
814 static auto value_to_name(T value,
const std::vector<std::pair<T, std::string>>& mapping) ->
const std::string&
816 for(
const auto& kvp : mapping)
818 if(kvp.first == value)
824 static const std::string empty;
828 static auto name_to_value(
const std::string&
name,
const std::vector<std::pair<T, std::string>>& mapping) -> T
830 for(
const auto& kvp : mapping)
832 if(kvp.second ==
name)
838 return std::numeric_limits<T>::max();
841 template<
typename Invoker>
843 mono::mono_object& obj,
845 const Invoker& mutable_field,
846 const std::vector<std::pair<T, std::string>>& mapping,
849 auto val = mutable_field.get_value(obj);
853 auto attribs = mutable_field.get_attributes();
854 auto tooltip_attrib =
find_attribute(
"TooltipAttribute", attribs);
857 if(tooltip_attrib.valid())
859 auto invoker = mono::make_field_invoker<std::string>(tooltip_attrib.get_type(),
"tooltip");
860 tooltip = invoker.get_value(tooltip_attrib);
865 std::vector<const char*> cstrings{};
866 cstrings.reserve(mapping.size());
870 for(
const auto& pair : mapping)
872 cstrings.push_back(pair.second.c_str());
874 if(current_name == pair.second)
885 ImGui::LabelText(
"##enum",
"%s", cstrings[current_idx]);
889 int listbox_item_size =
static_cast<int>(cstrings.size());
891 ImGuiComboFlags flags = 0;
893 if(ImGui::BeginCombo(
"##enum", cstrings[current_idx], flags))
895 for(
int n = 0; n < listbox_item_size; n++)
897 const bool is_selected = (current_idx == n);
899 if(ImGui::Selectable(cstrings[n], is_selected))
907 ImGui::DrawItemActivityOutline();
911 ImGui::SetItemDefaultFocus();
917 ImGui::DrawItemActivityOutline();
922 mutable_field.set_value(obj, val);
929 mono::mono_object& obj,
931 mono::mono_field& field,
938 const auto& field_type = field.get_type();
940 auto mapping = field_type.get_enum_values<T>();
948 mono::mono_object& obj,
950 mono::mono_field& field,
951 const std::vector<std::pair<T, std::string>>& mapping,
966 auto tooltip_attrib =
find_attribute(
"TooltipAttribute", attribs);
969 if(tooltip_attrib.valid())
971 auto invoker = mono::make_field_invoker<std::string>(tooltip_attrib.get_type(),
"tooltip");
972 tooltip = invoker.get_value(tooltip_attrib);
977 std::vector<const char*> cstrings{};
978 cstrings.reserve(mapping.size());
982 for(
const auto& pair : mapping)
984 cstrings.push_back(pair.second.c_str());
986 if(current_name == pair.second)
997 ImGui::LabelText(
"##enum",
"%s", cstrings[current_idx]);
1001 int listbox_item_size =
static_cast<int>(cstrings.size());
1003 ImGuiComboFlags flags = 0;
1005 if(ImGui::BeginCombo(
"##enum", cstrings[current_idx], flags))
1007 for(
int n = 0; n < listbox_item_size; n++)
1009 const bool is_selected = (current_idx == n);
1011 if(ImGui::Selectable(cstrings[n], is_selected))
1019 entt::meta_any new_value = entt::forward_as_meta(val);
1020 entt::meta_any old_value;
1021 field_proxy.impl->getter(old_value);
1027 ImGui::DrawItemActivityOutline();
1031 ImGui::SetItemDefaultFocus();
1037 ImGui::DrawItemActivityOutline();
1044 mono::mono_object& obj,
1046 mono::mono_property& property,
1053 const auto& field_type =
property.get_type();
1055 auto mapping = field_type.get_enum_values<T>();
1063 mono::mono_object& obj,
1065 mono::mono_property& property,
1066 const std::vector<std::pair<T, std::string>>& mapping,
1081 auto tooltip_attrib =
find_attribute(
"TooltipAttribute", attribs);
1084 if(tooltip_attrib.valid())
1086 auto invoker = mono::make_field_invoker<std::string>(tooltip_attrib.get_type(),
"tooltip");
1087 tooltip = invoker.get_value(tooltip_attrib);
1092 std::vector<const char*> cstrings{};
1093 cstrings.reserve(mapping.size());
1095 int current_idx = 0;
1097 for(
const auto& pair : mapping)
1099 cstrings.push_back(pair.second.c_str());
1101 if(current_name == pair.second)
1112 ImGui::LabelText(
"##enum",
"%s", cstrings[current_idx]);
1116 int listbox_item_size =
static_cast<int>(cstrings.size());
1118 ImGuiComboFlags flags = 0;
1120 if(ImGui::BeginCombo(
"##enum", cstrings[current_idx], flags))
1122 for(
int n = 0; n < listbox_item_size; n++)
1124 const bool is_selected = (current_idx == n);
1126 if(ImGui::Selectable(cstrings[n], is_selected))
1134 entt::meta_any new_value = entt::forward_as_meta(val);
1135 entt::meta_any old_value;
1136 prop_proxy.impl->getter(old_value);
1142 ImGui::DrawItemActivityOutline();
1146 ImGui::SetItemDefaultFocus();
1152 ImGui::DrawItemActivityOutline();
1162 template<
typename Invoker>
1164 mono::mono_object& obj,
1166 const Invoker& mutable_field,
1171 auto attribs = mutable_field.get_attributes();
1172 auto tooltip_attrib =
find_attribute(
"TooltipAttribute", attribs);
1175 if(tooltip_attrib.valid())
1177 auto invoker = mono::make_field_invoker<std::string>(tooltip_attrib.get_type(),
"tooltip");
1178 tooltip = invoker.get_value(tooltip_attrib);
1186 if(!handle_proxy.impl->getter(var))
1193 result |=
inspect_var(ctx, var, handle_proxy, info);
1200 mono::mono_object& obj,
1202 mono::mono_field& field,
1205 auto invoker = mono::make_field_invoker<entt::entity>(field);
1211 return inspect_invoker(ctx, obj, obj_proxy, invoker, field_info);
1215 mono::mono_object& obj,
1217 mono::mono_property& field,
1220 auto invoker = mono::make_property_invoker<entt::entity>(field);
1226 return inspect_invoker(ctx, obj, obj_proxy, invoker, field_info);
1233 template<
typename Invoker>
1235 mono::mono_object& obj,
1237 const Invoker& mutable_field,
1242 auto attribs = mutable_field.get_attributes();
1243 auto tooltip_attrib =
find_attribute(
"TooltipAttribute", attribs);
1246 if(tooltip_attrib.valid())
1248 auto invoker = mono::make_field_invoker<std::string>(tooltip_attrib.get_type(),
"tooltip");
1249 tooltip = invoker.get_value(tooltip_attrib);
1257 if(!asset_proxy.impl->getter(var))
1264 result |=
inspect_var(ctx, var, asset_proxy, info);
1271 mono::mono_object& obj,
1273 mono::mono_field& field,
1276 auto invoker = mono::make_field_invoker<mono::mono_object>(field);
1282 return inspect_invoker(ctx, obj, obj_proxy, invoker, field_info);
1286 mono::mono_object& obj,
1288 mono::mono_property& field,
1291 auto invoker = mono::make_property_invoker<mono::mono_object>(field);
1297 return inspect_invoker(ctx, obj, obj_proxy, invoker, field_info);
1306 template<
typename Invoker>
1308 mono::mono_object& obj,
1310 const Invoker& mutable_field,
1311 const mono::mono_type& collection_type,
1316 auto val = mutable_field.get_value(obj);
1322 bool is_array = collection_type.is_array();
1325 if (!is_array && !is_list)
1331 size_t collection_size = 0;
1334 mono::mono_array<mono::mono_object> array(val);
1335 collection_size = array.size();
1340 auto count_prop = collection_type.get_property(
"Count");
1341 if (count_prop.get_internal_ptr())
1343 auto count_invoker = mono::make_property_invoker<int32_t>(count_prop);
1344 collection_size =
static_cast<size_t>(count_invoker.get_value(val));
1349 ImGui::PushID(mutable_field.get_name().c_str());
1351 bool tree_open = ImGui::TreeNodeEx(mutable_field.get_name().c_str(),
1352 ImGuiTreeNodeFlags_DefaultOpen,
1354 mutable_field.get_name().c_str(),
1358 if (is_list && !info.read_only)
1361 if (ImGui::SmallButton(
"+"))
1364 auto add_method = collection_type.get_method(
"Add", 1);
1365 if (add_method.valid())
1368 if (element_type.valid())
1371 mono::mono_object new_element = element_type.new_instance();;
1374 auto add_invoker = mono::make_method_invoker<void(const mono::mono_object&)>(add_method);
1375 add_invoker(val, new_element);
1382 if (collection_size > 0)
1385 if (ImGui::SmallButton(
"-"))
1388 auto remove_at_method = collection_type.get_method(
"RemoveAt", 1);
1389 if (remove_at_method.valid())
1391 auto remove_invoker = mono::make_method_invoker<void(int32_t)>(remove_at_method);
1392 remove_invoker(val,
static_cast<int32_t
>(collection_size - 1));
1402 ImGui::PushStyleVar(ImGuiStyleVar_IndentSpacing, 8.0f);
1405 for (
size_t i = 0; i < collection_size; ++i)
1408 mono::mono_object element;
1411 mono::mono_array<mono::mono_object> array(val);
1412 element = array.get(i);
1417 auto item_prop = collection_type.get_property(
"Item");
1418 if (item_prop.get_internal_ptr())
1420 auto item_invoker = mono::make_property_invoker<mono::mono_object>(item_prop);
1421 element = item_invoker.get_value(val);
1425 if (element.valid())
1429 collection_proxy.
impl->get_name = [obj_proxy, mutable_field]()
1431 auto parent_name = obj_proxy.impl->get_name();
1432 auto field_name = mutable_field.get_name();
1433 if(parent_name.empty())
1437 return fmt::format(
"{}/{}", parent_name, field_name);
1439 collection_proxy.
impl->getter = [obj_proxy, mutable_field](entt::meta_any& result)
mutable
1441 entt::meta_any obj_var;
1442 if(obj_proxy.impl->getter(obj_var) && obj_var)
1444 auto& mono_obj = obj_var.cast<mono::mono_object&>();
1445 auto collection_obj = mutable_field.get_value(mono_obj);
1446 result = entt::meta_any{std::in_place_type<mono::mono_object>, collection_obj};
1451 collection_proxy.
impl->setter = [obj_proxy, mutable_field](
meta_any_proxy& proxy,
const entt::meta_any& value, uint64_t execution_count)
mutable
1453 entt::meta_any obj_var;
1454 if(obj_proxy.impl->getter(obj_var) && obj_var)
1456 auto& mono_obj = obj_var.cast<mono::mono_object&>();
1457 if(value.allow_cast<mono::mono_object>())
1459 mutable_field.set_value(mono_obj, value.cast<mono::mono_object>());
1460 return obj_proxy.impl->setter(proxy, obj_var, execution_count);
1467 std::string element_name = fmt::format(
"Element {}", i);
1471 entt::meta_any element_var = entt::forward_as_meta(element);
1473 ImGui::PushID(
static_cast<int>(i));
1477 if (is_list && !info.read_only)
1480 if (ImGui::SmallButton(
"X"))
1482 auto remove_at_method = collection_type.get_method(
"RemoveAt", 1);
1483 if (remove_at_method.valid())
1485 auto remove_invoker = mono::make_method_invoker<void(int32_t)>(remove_at_method);
1486 remove_invoker(val,
static_cast<int32_t
>(i));
1498 ImGui::PopStyleVar();
1508 mono::mono_object& obj,
1510 mono::mono_field& field,
1513 auto invoker = mono::make_field_invoker<mono::mono_object>(field);
1514 auto field_type = field.get_type();
1524 mono::mono_object& obj,
1526 mono::mono_property& property,
1529 auto invoker = mono::make_property_invoker<mono::mono_object>(property);
1530 auto prop_type =
property.get_type();
1543 template<
typename Invoker>
1545 mono::mono_object& obj,
1547 const Invoker& mutable_field,
1552 auto val = mutable_field.get_value(obj);
1553 mono::mono_array<T> array(val);
1555 for(
size_t i = 0; i < array.size(); ++i)
1559 array_proxy.
impl->get_name = [obj_proxy, mutable_field]()
1561 auto parent_name = obj_proxy.impl->get_name();
1562 auto field_name = mutable_field.get_name();
1563 if(parent_name.empty())
1567 return fmt::format(
"{}/{}", parent_name, field_name);
1569 array_proxy.
impl->getter = [obj_proxy, mutable_field](entt::meta_any& result)
mutable
1571 entt::meta_any obj_var;
1572 if(obj_proxy.impl->getter(obj_var) && obj_var)
1574 auto& mono_obj = obj_var.cast<mono::mono_object&>();
1575 auto array_obj = mutable_field.get_value(mono_obj);
1576 result = entt::meta_any{std::in_place_type<mono::mono_object>, array_obj};
1581 array_proxy.
impl->setter = [obj_proxy, mutable_field](
meta_any_proxy& proxy,
const entt::meta_any& value, uint64_t execution_count)
mutable
1583 entt::meta_any obj_var;
1584 if(obj_proxy.impl->getter(obj_var) && obj_var)
1586 auto& mono_obj = obj_var.cast<mono::mono_object&>();
1587 if(value.allow_cast<mono::mono_object>())
1589 mutable_field.set_value(mono_obj, value.cast<mono::mono_object>());
1590 return obj_proxy.impl->setter(proxy, obj_var, execution_count);
1597 std::string element_name = fmt::format(
"Element {}", i);
1601 entt::meta_any element;
1602 if(element_proxy.impl->getter(element))
1611 mono::mono_object& obj,
1613 mono::mono_field& field,
1616 auto invoker = mono::make_field_invoker<mono::mono_object>(field);
1622 return inspect_invoker(ctx, obj, obj_proxy, invoker, field_info);
1626 mono::mono_object& obj,
1628 mono::mono_property& field,
1631 auto invoker = mono::make_property_invoker<mono::mono_object>(field);
1637 return inspect_invoker(ctx, obj, obj_proxy, invoker, field_info);
1642 entt::meta_any& var,
1647 auto& data = var.cast<mono::mono_object&>();
1651 const auto&
type = data.get_type();
1659 auto get_field_inspector = [](
const std::string& type_name) ->
const mono_field_inspector&
1662 static std::map<std::string, mono_field_inspector> reg = {
1697 auto it = reg.find(type_name);
1702 static const mono_field_inspector empty;
1706 auto get_enum_field_inspector = [](
const std::string& type_name) ->
const mono_field_inspector&
1709 static std::map<std::string, mono_field_inspector> reg = {
1721 auto it = reg.find(type_name);
1726 static const mono_field_inspector empty;
1730 auto fields =
type.get_fields();
1731 for(
auto& field : fields)
1733 bool inspect_predicate = field.get_visibility() == mono::visibility::vis_public;
1739 inspect_predicate = !field.is_backing_field();
1742 if(field.is_static())
1744 inspect_predicate =
false;
1748 if(inspect_predicate)
1750 const auto& field_type = field.get_type();
1752 auto field_inspector = get_field_inspector(field_type.get_name());
1755 override_ctx.
push_segment(field.get_name(), field.get_name());
1759 result |= field_inspector(ctx, data, var_proxy, field, info);
1761 else if(field_type.is_enum())
1763 auto enum_type = field_type.get_enum_base_type();
1764 auto enum_inspector = get_enum_field_inspector(enum_type.get_name());
1767 result |= enum_inspector(ctx, data, var_proxy, field, info);
1810 std::string unknown_text;
1812 auto invoker = mono::make_field_invoker<mono::mono_object>(field);
1813 auto nested_obj = invoker.get_value(data);
1814 if(nested_obj.valid())
1816 unknown_text = fmt::format(
"Unknown ({})", nested_obj.get_type().get_name());
1820 unknown_text =
"null (" + field_type.get_name() +
")";
1823 entt::meta_any unknown_var = entt::forward_as_meta(unknown_text);
1824 auto unknown_var_proxy =
make_proxy(unknown_var);
1828 result |=
inspect_var(ctx, unknown_var, unknown_var_proxy, field_info);
1832 override_ctx.pop_segment();
1840 mono::mono_property&,
1843 auto get_property_inspector = [](
const std::string& type_name) ->
const mono_property_inspector&
1846 static std::map<std::string, mono_property_inspector> reg = {
1880 auto it = reg.find(type_name);
1885 static const mono_property_inspector empty;
1889 auto get_enum_property_inspector = [](
const std::string& type_name) ->
const mono_property_inspector&
1892 static std::map<std::string, mono_property_inspector> reg = {
1904 auto it = reg.find(type_name);
1909 static const mono_property_inspector empty;
1913 auto properties =
type.get_properties();
1914 for(
auto& prop : properties)
1916 bool inspect_predicate = prop.get_visibility() == mono::visibility::vis_public;
1921 inspect_predicate =
true;
1924 if(prop.is_static())
1926 inspect_predicate =
false;
1929 if(inspect_predicate)
1931 const auto& prop_type = prop.get_type();
1933 auto property_inspector = get_property_inspector(prop_type.get_name());
1936 override_ctx.
push_segment(prop.get_name(), prop.get_name());
1938 if(property_inspector)
1940 result |= property_inspector(ctx, data, var_proxy, prop, info);
1942 else if(prop_type.is_enum())
1944 auto enum_type = prop_type.get_enum_base_type();
1945 auto enum_inspector = get_enum_property_inspector(enum_type.get_name());
1948 result |= enum_inspector(ctx, data, var_proxy, prop, info);
1991 std::string unknown_text;
1993 auto invoker = mono::make_property_invoker<mono::mono_object>(prop);
1994 auto nested_obj = invoker.get_value(data);
1995 if(nested_obj.valid())
1997 unknown_text = fmt::format(
"Unknown ({})", nested_obj.get_type().get_name());
2001 unknown_text =
"null (" + prop.get_type().get_name() +
")";
2004 entt::meta_any unknown_var = entt::forward_as_meta(unknown_text);
2005 auto unknown_var_proxy =
make_proxy(unknown_var);
2009 result |=
inspect_var(ctx, unknown_var, unknown_var_proxy, field_info);
2013 override_ctx.pop_segment();
2022 entt::meta_any& var,
2028 obj_proxy.
impl->get_name = [parent_proxy = var_proxy]()
2030 return parent_proxy.impl->get_name();
2032 obj_proxy.
impl->getter = [parent_proxy = var_proxy](entt::meta_any& result)
2035 if(parent_proxy.impl->getter(var) && var)
2037 auto& data = var.cast<mono::mono_scoped_object&>();
2038 auto& mono_obj =
static_cast<mono::mono_object&
>(data.object);
2039 result = entt::forward_as_meta(mono_obj);
2044 obj_proxy.
impl->setter = [parent_proxy = var_proxy](
meta_any_proxy& proxy,
const entt::meta_any& value, uint64_t execution_count)
mutable
2047 if(proxy.impl->getter(var) && var)
2050 return parent_proxy.impl->setter(parent_proxy, var, execution_count);
2056 auto& data = var.cast<mono::mono_scoped_object&>();
2057 auto& mono_obj =
static_cast<mono::mono_object&
>(data.object);
2058 auto obj_var = entt::forward_as_meta(mono_obj);
2070 mono::mono_object& obj,
2072 const std::string&
name,
2078 bool tree_open = ImGui::TreeNodeEx(
name.c_str(), ImGuiTreeNodeFlags_DefaultOpen);
2082 ImGui::PushStyleVar(ImGuiStyleVar_IndentSpacing, 8.0f);
2085 auto obj_var = entt::forward_as_meta(obj);
2087 result |=
inspector.inspect(ctx, obj_var, obj_proxy, info, {});
2089 ImGui::PopStyleVar();
Manages assets, including loading, unloading, and storage.
Manages ImGui layout for property inspection in the editor.
void PushReadonly(bool _enabled)
std::map< std::string, meta_any > attributes
auto make_custom(Args &&...args) -> entt::meta_custom
Provides utilities for inspecting and converting sequence-related types to strings.
Hash specialization for batch_key to enable use in std::unordered_map.
auto is_serializable_type(const mono::mono_type &type) -> bool
Checks if a mono type has the System.Serializable attribute.
auto inspect_property(rtti::context &ctx, entt::meta_any &object, const meta_any_proxy &var_proxy, const entt::meta_data &prop) -> inspect_result
auto find_attribute(const std::string &name, const std::vector< mono::mono_object > &attribs) -> mono::mono_object
auto make_array_element_proxy(const meta_any_proxy &array_proxy, size_t index, const std::string &element_name) -> meta_any_proxy
Creates a specialized proxy for individual array elements in script objects.
auto make_nested_property_proxy(const meta_any_proxy &obj_proxy, const Invoker &mutable_property) -> meta_any_proxy
Creates a proxy for a nested serializable object property.
void add_property_action(rtti::context &ctx, prefab_override_context &override_ctx, inspect_result &result, const meta_any_proxy &var_proxy, const entt::meta_any &old_var, const entt::meta_any &new_var, const entt::meta_custom &custom)
auto get_collection_element_type(const mono::mono_type &type) -> mono::mono_type
Gets the element type of a collection (array or List<T>)
auto is_list_type(const mono::mono_type &type) -> bool
Checks if a mono type is a List<T>
auto make_entity_handle_proxy(const meta_any_proxy &obj_proxy, const Invoker &mutable_field, rtti::context &ctx) -> meta_any_proxy
Creates a specialized proxy for entity handle fields in script objects.
auto make_asset_handle_proxy(const meta_any_proxy &obj_proxy, const Invoker &mutable_field, rtti::context &ctx) -> meta_any_proxy
Creates a specialized proxy for asset handle fields in script objects.
auto make_script_proxy(const meta_any_proxy &obj_proxy, const ProxyType &script_proxy) -> meta_any_proxy
Creates a meta_any_proxy that can access script fields through the proxy wrapper.
auto make_nested_object_proxy(const meta_any_proxy &obj_proxy, const Invoker &mutable_field) -> meta_any_proxy
Creates a proxy for a nested serializable object field.
auto is_debug_view() -> bool
Checks if currently in debug view mode.
auto inspect_serializable_object(rtti::context &ctx, mono::mono_object &obj, const meta_any_proxy &obj_proxy, const std::string &name, const var_info &info) -> inspect_result
Recursively inspects a serializable object using the main inspector.
auto make_proxy(entt::meta_any &var, const std::string &name) -> meta_any_proxy
Creates a simple proxy for direct variable access.
auto inspect_var(rtti::context &ctx, entt::meta_any &var, const meta_any_proxy &var_proxy, const var_info &info, const entt::meta_custom &custom) -> inspect_result
Main entry point for inspecting any variable with automatic type resolution.
Represents a handle to an asset, providing access and management functions.
Manages the entity-component-system (ECS) operations for the ACE framework.
Result of an inspection operation indicating what changes occurred.
bool changed
Whether the value was modified during inspection.
bool edit_finished
Whether user finished editing (e.g., released mouse or pressed enter)
auto inspect(rtti::context &ctx, entt::meta_any &var, const meta_any_proxy &var_proxy, const var_info &info, const entt::meta_custom &custom) -> inspect_result override
auto inspect(rtti::context &ctx, entt::meta_any &var, const meta_any_proxy &var_proxy, const var_info &info, const entt::meta_custom &custom) -> inspect_result override
Proxy wrapper for mono field access that integrates with meta_any_proxy system.
auto get_name() const -> std::string
auto get_value(mono::mono_object &obj) const -> T
mono_field_proxy(mono::mono_field f)
auto get_attributes() const
void set_value(mono::mono_object &obj, const T &value) const
static auto inspect_field(rtti::context &ctx, mono::mono_object &obj, const meta_any_proxy &obj_proxy, mono::mono_field &field, const var_info &info) -> inspect_result
static auto inspect_invoker(rtti::context &ctx, mono::mono_object &obj, const meta_any_proxy &obj_proxy, const Invoker &mutable_field, const var_info &info) -> inspect_result
static auto inspect_property(rtti::context &ctx, mono::mono_object &obj, const meta_any_proxy &obj_proxy, mono::mono_property &field, const var_info &info) -> inspect_result
static auto inspect_invoker(rtti::context &ctx, mono::mono_object &obj, const meta_any_proxy &obj_proxy, const Invoker &mutable_field, const var_info &info) -> inspect_result
static auto inspect_field(rtti::context &ctx, mono::mono_object &obj, const meta_any_proxy &obj_proxy, mono::mono_field &field, const var_info &info) -> inspect_result
static auto inspect_property(rtti::context &ctx, mono::mono_object &obj, const meta_any_proxy &obj_proxy, mono::mono_property &field, const var_info &info) -> inspect_result
static auto inspect_property(rtti::context &ctx, mono::mono_object &obj, const meta_any_proxy &obj_proxy, mono::mono_property &field, const var_info &info) -> inspect_result
static auto inspect_invoker(rtti::context &ctx, mono::mono_object &obj, const meta_any_proxy &obj_proxy, const Invoker &mutable_field, const var_info &info) -> inspect_result
static auto inspect_field(rtti::context &ctx, mono::mono_object &obj, const meta_any_proxy &obj_proxy, mono::mono_field &field, const var_info &info) -> inspect_result
Inspector for collections (arrays and List<T>) with add/remove support.
static auto inspect_field(rtti::context &ctx, mono::mono_object &obj, const meta_any_proxy &obj_proxy, mono::mono_field &field, const var_info &info) -> inspect_result
static auto inspect_property(rtti::context &ctx, mono::mono_object &obj, const meta_any_proxy &obj_proxy, mono::mono_property &property, const var_info &info) -> inspect_result
static auto inspect_collection(rtti::context &ctx, mono::mono_object &obj, const meta_any_proxy &obj_proxy, const Invoker &mutable_field, const mono::mono_type &collection_type, const var_info &info) -> inspect_result
static auto inspect_field(rtti::context &ctx, mono::mono_object &obj, const meta_any_proxy &obj_proxy, mono::mono_field &field, const var_info &info) -> inspect_result
static auto name_to_value(const std::string &name, const std::vector< std::pair< T, std::string > > &mapping) -> T
static auto inspect_enum_property_with_proxy(rtti::context &ctx, mono::mono_object &obj, const meta_any_proxy &obj_proxy, mono::mono_property &property, const std::vector< std::pair< T, std::string > > &mapping, const var_info &info) -> inspect_result
static auto inspect_invoker(rtti::context &ctx, mono::mono_object &obj, const meta_any_proxy &obj_proxy, const Invoker &mutable_field, const std::vector< std::pair< T, std::string > > &mapping, const var_info &info) -> inspect_result
static auto inspect_property(rtti::context &ctx, mono::mono_object &obj, const meta_any_proxy &obj_proxy, mono::mono_property &property, const var_info &info) -> inspect_result
static auto inspect_enum_field_with_proxy(rtti::context &ctx, mono::mono_object &obj, const meta_any_proxy &obj_proxy, mono::mono_field &field, const std::vector< std::pair< T, std::string > > &mapping, const var_info &info) -> inspect_result
static auto value_to_name(T value, const std::vector< std::pair< T, std::string > > &mapping) -> const std::string &
static auto inspect_property(rtti::context &ctx, mono::mono_object &obj, const meta_any_proxy &obj_proxy, mono::mono_property &property, const var_info &info) -> inspect_result
static auto inspect_field(rtti::context &ctx, mono::mono_object &obj, const meta_any_proxy &obj_proxy, mono::mono_field &field, const var_info &info) -> inspect_result
static auto inspect_invoker_with_proxy(rtti::context &ctx, mono::mono_object &obj, const meta_any_proxy &obj_proxy, mono::mono_field &field, const var_info &info) -> inspect_result
static auto inspect_property_with_proxy(rtti::context &ctx, mono::mono_object &obj, const meta_any_proxy &obj_proxy, mono::mono_property &property, const var_info &info) -> inspect_result
Proxy wrapper for mono property access that integrates with meta_any_proxy system.
auto get_attributes() const
mono_property_proxy(mono::mono_property p)
std::string property_name
void set_value(mono::mono_object &obj, const T &value) const
auto get_name() const -> std::string
auto get_value(mono::mono_object &obj) const -> T
mono::mono_property property
Global context for tracking prefab override changes during inspection.
void push_segment(const std::string &segment, const std::string &pretty_segment)
Pushes a new path segment onto both contexts and applies override styling.
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.
Metadata about a variable being inspected.
bool is_property
Whether this is a property that can be overridden in prefabs.
bool read_only
Whether the variable should be displayed as read-only.