From 94f17f8ad8ca7d303676f7973fffe70cb4c38e8d Mon Sep 17 00:00:00 2001 From: OEOTYAN Date: Wed, 31 Jan 2024 05:43:04 +0800 Subject: [PATCH] feat: add reflection offset getter --- .clangd | 1 + src/ll/api/base/Meta.h | 4 +- src/ll/api/base/MsvcPredefine.h | 2 +- src/ll/api/command/CommandRegistrar.cpp | 8 ++++ src/ll/api/command/CommandRegistrar.h | 12 ++++- src/ll/api/reflection/Reflection.h | 51 +++++++++++++++++++++- src/ll/test/ConfigTest.cpp | 12 ++++- src/ll/test/EventTest.cpp | 4 +- src/ll/test/PtrTest.cpp | 2 - src/mc/server/commands/CommandRegistry.cpp | 6 +-- src/mc/server/commands/CommandRegistry.h | 4 +- 11 files changed, 89 insertions(+), 17 deletions(-) create mode 100644 src/ll/api/command/CommandRegistrar.cpp diff --git a/.clangd b/.clangd index 8a640599a5..8f64971a9f 100644 --- a/.clangd +++ b/.clangd @@ -10,6 +10,7 @@ CompileFlags: Add: - "-ferror-limit=0" - '-D__FUNCTION__="dummy"' + - '-D__clangd__' - "-Yusrc/ll/api/Global.h" - "-FIsrc/ll/api/Global.h" # clangd bug can't find pch file Remove: diff --git a/src/ll/api/base/Meta.h b/src/ll/api/base/Meta.h index 12069b0fc0..0739973de3 100644 --- a/src/ll/api/base/Meta.h +++ b/src/ll/api/base/Meta.h @@ -136,8 +136,8 @@ template return Id; } } - -#if 0 +// TODO: fix this +#if !(defined(__INTELLISENSE__) || defined(__clangd__) || defined(__clang__)) template struct DynamicTypeList { template diff --git a/src/ll/api/base/MsvcPredefine.h b/src/ll/api/base/MsvcPredefine.h index 4143d5f284..5318c03362 100644 --- a/src/ll/api/base/MsvcPredefine.h +++ b/src/ll/api/base/MsvcPredefine.h @@ -4,7 +4,7 @@ // MSVC has customized some functions and classes inside the compiler, but they are not included in IntelliSense. This // header file is only used for IntelliSense. -#if defined(__INTELLISENSE__) || defined(__clang__) +#if defined(__INTELLISENSE__) || defined(__clang__) || defined(__clangd__) // NOLINTBEGIN #pragma pack(push, ehdata, 4) diff --git a/src/ll/api/command/CommandRegistrar.cpp b/src/ll/api/command/CommandRegistrar.cpp new file mode 100644 index 0000000000..9b4b4477fd --- /dev/null +++ b/src/ll/api/command/CommandRegistrar.cpp @@ -0,0 +1,8 @@ +#include "ll/api/command/CommandRegistrar.h" + +namespace ll::command { + +CommandRegistrar::CommandRegistrar(CommandRegistry& registry) : registry(®istry) {} +CommandRegistrar::~CommandRegistrar() = default; + +} // namespace ll::command diff --git a/src/ll/api/command/CommandRegistrar.h b/src/ll/api/command/CommandRegistrar.h index 13badb5def..7e3cb9a47c 100644 --- a/src/ll/api/command/CommandRegistrar.h +++ b/src/ll/api/command/CommandRegistrar.h @@ -2,4 +2,14 @@ #include "mc/server/commands/CommandRegistry.h" -namespace ll::command {} +namespace ll::command { +class CommandRegistrar { + CommandRegistry* registry; + +public: + LLNDAPI CommandRegistrar(CommandRegistry&); + LLAPI ~CommandRegistrar(); + + CommandRegistry* operator->() const { return registry; } +}; +} // namespace ll::command diff --git a/src/ll/api/reflection/Reflection.h b/src/ll/api/reflection/Reflection.h index 8e91cee682..4be6d8f07e 100644 --- a/src/ll/api/reflection/Reflection.h +++ b/src/ll/api/reflection/Reflection.h @@ -15,6 +15,7 @@ #endif #include "boost/pfr.hpp" +#include "boost/pfr/detail/offset_based_getter.hpp" #include "magic_enum.hpp" @@ -26,11 +27,57 @@ inline constexpr bool is_reflectable_v = template concept Reflectable = is_reflectable_v; +template +inline constexpr auto const name_array_v = boost::pfr::names_as_array>(); + +template +constexpr auto makeSequenceTupleFromTieTuple(const T& t, std::index_sequence) noexcept { + return boost::pfr::detail::sequence_tuple::make_sequence_tuple(boost::pfr::detail::sequence_tuple::get(t)...); +} + +template < + typename U, + typename S = decltype(makeSequenceTupleFromTieTuple( + boost::pfr::detail::tie_as_tuple(boost::pfr::detail::fake_object), + boost::pfr::detail::make_index_sequence>() + ))> +struct OffsetGetter { + using this_t = OffsetGetter; + + static_assert( + sizeof(U) == sizeof(S), + "Member sequence does not indicate correct size for struct type! Maybe the user-provided type is not a " + "SimpleAggregate?" + ); + static_assert(alignof(U) == alignof(S), " Member sequence does not indicate correct alignment for struct type!"); + + // Get offset of idx'th member + // Idea: Layout object has the same offsets as instance of S, so if S and U are layout compatible, then these offset + // calculations are correct. + template + static consteval std::ptrdiff_t offset() noexcept { +#if defined(__INTELLISENSE__) || defined(__clangd__) || defined(__clang__) + return 0; // TODO: fix this +#else + constexpr boost::pfr::detail::tuple_of_aligned_storage_t layout{}; + return (&boost::pfr::detail::sequence_tuple::get(layout).storage_) + - (&boost::pfr::detail::sequence_tuple::get<0>(layout).storage_); +#endif + } +}; + +template +consteval auto makeOffsetArrayImpl(std::index_sequence) { + return boost::pfr::detail::make_stdarray((OffsetGetter::template offset())...); +} +template +inline constexpr auto const offset_array_v = + makeOffsetArrayImpl(std::make_index_sequence>()); + template constexpr void forEachMember(T&& value, F&& func) { - static constexpr auto const namearray = boost::pfr::names_as_array>(); boost::pfr::for_each_field(std::forward(value), [func = std::forward(func)](auto&& field, std::size_t idx) { - func(namearray[idx], std::forward(field)); + func(name_array_v[idx], std::forward(field)); }); } } // namespace ll::reflection diff --git a/src/ll/test/ConfigTest.cpp b/src/ll/test/ConfigTest.cpp index 753f59cba9..73597722f3 100644 --- a/src/ll/test/ConfigTest.cpp +++ b/src/ll/test/ConfigTest.cpp @@ -31,6 +31,11 @@ #include "mc/world/actor/DataItem.h" +// [0, 8, 16, 96, 97, 98, 104, 136, 144, 160, 176, 184, 196, 208, 232, 248, 304, 328, 360, 392, 408] + +// ["structure", "version", "ver", "someFlag", "eeeeFlag", "ssbbFlag", "str", "plain", "amap", "bmap", "vec2", "vec3", +// "pos", "box", "tuple", "pair", "array", "vector", "nullvector", "mulset", "hi"] + template class TestClass { public: @@ -86,7 +91,7 @@ class TestClass { // LL_AUTO_TYPE_INSTANCE_HOOK(Virtual, HookPriority::Normal, FillCommand, &FillCommand::execute, void, CommandOrigin // const&, CommandOutput&) { // } -#if 0 +#if !(defined(__INTELLISENSE__) || defined(__clangd__) || defined(__clang__)) struct myTypeList1 : ll::meta::DynamicTypeList {}; struct myTypeList2 : ll::meta::DynamicTypeList {}; struct myTypeList3 : ll::meta::TypeList {}; @@ -154,7 +159,10 @@ LL_AUTO_TYPE_INSTANCE_HOOK(ConfigTest, HookPriority::Normal, ServerInstance, &Se ll::logger.debug("789\xDB\xFE"); ll::logger.debug("789\xDB\xFE"); -#if 0 + + ll::logger.debug("{}", ll::reflection::offset_array_v>); + +#if !(defined(__INTELLISENSE__) || defined(__clangd__) || defined(__clang__)) myTypeList1::push_back(); myTypeList1::push_back(); ll::logger.debug("{}", ll::reflection::type_raw_name_v); diff --git a/src/ll/test/EventTest.cpp b/src/ll/test/EventTest.cpp index b6a0bd0aff..dc0af6d48a 100644 --- a/src/ll/test/EventTest.cpp +++ b/src/ll/test/EventTest.cpp @@ -38,7 +38,7 @@ #include "ll/api/utils/HashUtils.h" -#if 0 +#if !(defined(__INTELLISENSE__) || defined(__clangd__) || defined(__clang__)) struct myTypeList2 : ll::meta::DynamicTypeList {}; #endif @@ -213,7 +213,7 @@ LL_AUTO_TYPE_INSTANCE_HOOK( .debug("Player {} MultiListener of {}", ev.self().getRealName(), ll::reflection::type_raw_name_v); }); bus.addListener(mul); -#if 0 +#if !(defined(__INTELLISENSE__) || defined(__clangd__) || defined(__clang__)) myTypeList2::push_back(); ll::logger.debug("{}", typeid(myTypeList2::value()).name()); #endif diff --git a/src/ll/test/PtrTest.cpp b/src/ll/test/PtrTest.cpp index 58fef406b8..6ce6fc0b13 100644 --- a/src/ll/test/PtrTest.cpp +++ b/src/ll/test/PtrTest.cpp @@ -94,8 +94,6 @@ LL_AUTO_TYPE_INSTANCE_HOOK( &BlockDefinitionGroup::registerBlocks, void ) { - std::cout << "type_hash " << entt::type_hash>::value() << std::endl; - ll::error_utils::printException(ll::logger, ll::error_utils::getWinLastError()); try { diff --git a/src/mc/server/commands/CommandRegistry.cpp b/src/mc/server/commands/CommandRegistry.cpp index 678896a3b2..206cb60b63 100644 --- a/src/mc/server/commands/CommandRegistry.cpp +++ b/src/mc/server/commands/CommandRegistry.cpp @@ -20,7 +20,7 @@ CommandRegistry::Signature::Signature( : name(name), desc(desc), perm(perm), - main_symbol(symbol), + mainSymbol(symbol), flag(flag) {} void CommandRegistry::registerOverload( @@ -102,11 +102,11 @@ bool CommandRegistry::unregisterCommand(std::string const& name) { auto sig = mSignatures.find(command); std::erase_if(mCommandSymbols, [&](Symbol const& r) { - return r == sig->second.main_symbol || r == sig->second.alt_symbol; + return r == sig->second.mainSymbol || r == sig->second.altSymbol; }); std::erase_if(mFactorizations, [&](Factorization const& r) { - return r.commandSymbol == sig->second.main_symbol || r.commandSymbol == sig->second.alt_symbol; + return r.commandSymbol == sig->second.mainSymbol || r.commandSymbol == sig->second.altSymbol; }); mSignatures.erase(sig); diff --git a/src/mc/server/commands/CommandRegistry.h b/src/mc/server/commands/CommandRegistry.h index 8b0fa64154..24d24cc734 100644 --- a/src/mc/server/commands/CommandRegistry.h +++ b/src/mc/server/commands/CommandRegistry.h @@ -236,8 +236,8 @@ class CommandRegistry { std::vector overloads; // this+0x40 std::vector unk88; // this+0x58 CommandPermissionLevel perm; // this+0x70 - Symbol main_symbol; // this+0x74 - Symbol alt_symbol; // this+0x78 + Symbol mainSymbol; // this+0x74 + Symbol altSymbol; // this+0x78 CommandFlag flag; // this+0x7C int firstRule{}; // this+0x80 int firstFactorization{}; // this+0x84