diff --git a/tools/entt/davey/davey.hpp b/tools/entt/davey/davey.hpp index 00b55cb92..1d0229ba9 100644 --- a/tools/entt/davey/davey.hpp +++ b/tools/entt/davey/davey.hpp @@ -1,14 +1,19 @@ #ifndef ENTT_DAVEY_DAVEY_HPP #define ENTT_DAVEY_DAVEY_HPP +#include +#include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include #include "meta.hpp" @@ -17,16 +22,112 @@ namespace entt { namespace internal { -#define DAVEY_OR(type) info ? info->name : std::string{type.name()}.c_str() +#define DAVEY_OR(elem) info ? info->name : std::string{elem.info().name()}.c_str() + +template +static void present_element(const entt::meta_any &obj, OnEntity on_entity) { + for([[maybe_unused]] const auto [id, data]: obj.type().data()) { + const auto elem = data.get(obj); + const davey_data *info = data.custom(); + + if(auto type = data.type(); type.info() == entt::type_id()) { + ImGui::Text("%s: %s", DAVEY_OR(type), elem.cast()); + } else if(type.info() == entt::type_id()) { + ImGui::Text("%s: %s", DAVEY_OR(type), elem.cast().c_str()); + } else if(type.info() == entt::type_id()) { + if(const auto entt = elem.cast(); entt == entt::null) { + ImGui::Text("%s: %s", DAVEY_OR(type), "null"); + } else { + on_entity(DAVEY_OR(type), elem.cast()); + } + } else if(type.is_arithmetic()) { + if(type.info() == entt::type_id()) { + std::stringstream buffer{}; + buffer << std::boolalpha << elem.cast(); + ImGui::Text("%s: %s", DAVEY_OR(type), buffer.str().c_str()); + } else if(type.info() == entt::type_id()) { + ImGui::Text("%s: %c", DAVEY_OR(type), elem.cast()); + } else if(type.is_integral()) { + ImGui::Text("%s: %d", DAVEY_OR(type), elem.allow_cast().cast()); + } else { + ImGui::Text("%s: %f", DAVEY_OR(type), elem.allow_cast().cast()); + } + } else if(type.is_pointer_like()) { + if(ImGui::TreeNode(DAVEY_OR(type))) { + present_element(*obj, on_entity); + ImGui::TreePop(); + } + } else if(type.is_class() && entt::resolve(type.info())) { + if(ImGui::TreeNode(DAVEY_OR(type))) { + present_element(elem, on_entity); + ImGui::TreePop(); + } + } else if(type.is_sequence_container()) { + if(ImGui::TreeNode(DAVEY_OR(type))) { + entt::meta_sequence_container view = elem.as_sequence_container(); + + for(std::size_t pos{}, last = view.size(); pos < last; ++pos) { + ImGui::PushID(static_cast(pos)); + + if(ImGui::TreeNode(DAVEY_OR(type), "%d", pos)) { + present_element(view[pos], on_entity); + ImGui::TreePop(); + } + + ImGui::PopID(); + } + + ImGui::TreePop(); + } + } else if(type.is_associative_container()) { + if(ImGui::TreeNode(DAVEY_OR(type))) { + entt::meta_associative_container view = elem.as_associative_container(); + auto it = view.begin(); + + for(std::size_t pos{}, last = view.size(); pos < last; ++pos, ++it) { + ImGui::PushID(static_cast(pos)); + + if(ImGui::TreeNode(DAVEY_OR(type), "%d", pos)) { + const auto [key, value] = *it; + + if(ImGui::TreeNode("key")) { + present_element(key, on_entity); + ImGui::TreePop(); + } + + if(ImGui::TreeNode("value")) { + present_element(value, on_entity); + ImGui::TreePop(); + } + + ImGui::TreePop(); + } + + ImGui::PopID(); + } + + ImGui::TreePop(); + } + } else { + const std::string underlying_type{data.type().info().name()}; + ImGui::Text("%s: %s", DAVEY_OR(type), underlying_type.c_str()); + } + } +} template static void present_entity(const meta_ctx &ctx, const entt::basic_registry ®istry, const Entity entt) { for([[maybe_unused]] auto [id, storage]: registry.storage()) { if(storage.contains(entt)) { if(auto type = entt::resolve(ctx, storage.type()); type) { - if(const davey_data *info = type.custom(); ImGui::TreeNode(&storage.type(), "%s", DAVEY_OR(storage.type()))) { + if(const davey_data *info = type.custom(); ImGui::TreeNode(&storage.type(), "%s", DAVEY_OR(storage))) { if(const auto obj = type.from_void(storage.value(entt)); obj) { - // TODO present element + present_element(obj, [&ctx, ®istry](const char *name, const entt::entity other) { + if(ImGui::TreeNode(name, "%s: %d [%d/%d]", name, entt::to_integral(other), entt::to_entity(other), entt::to_version(other))) { + present_entity(ctx, registry, other); + ImGui::TreePop(); + } + }); } ImGui::TreePop(); @@ -43,14 +144,16 @@ template void storage_tab(const meta_ctx &ctx, const entt::basic_registry ®istry) { for([[maybe_unused]] auto [id, storage]: registry.storage()) { if(auto type = entt::resolve(ctx, storage.type()); type) { - if(const davey_data *info = type.custom(); ImGui::TreeNode(&storage.type(), "%s (%d)", DAVEY_OR(storage.type()), storage.size())) { + if(const davey_data *info = type.custom(); ImGui::TreeNode(&storage.type(), "%s (%d)", DAVEY_OR(storage), storage.size())) { if(const auto type = entt::resolve(ctx, storage.type()); type) { for(auto entt: storage) { ImGui::PushID(static_cast(entt::to_entity(entt))); if(ImGui::TreeNode(&storage.type(), "%d [%d/%d]", entt::to_integral(entt), entt::to_entity(entt), entt::to_version(entt))) { if(const auto obj = type.from_void(storage.value(entt)); obj) { - // TODO present element + present_element(obj, [](const char *name, const entt::entity entt) { + ImGui::Text("%s: %d [%d/%d]", name, entt::to_integral(entt), entt::to_entity(entt), entt::to_version(entt)); + }); } ImGui::TreePop();