Skip to content

Commit

Permalink
feat: make command param checker into compile time
Browse files Browse the repository at this point in the history
  • Loading branch information
OEOTYAN committed Oct 5, 2024
1 parent e18ce60 commit d81fc04
Show file tree
Hide file tree
Showing 12 changed files with 82 additions and 51 deletions.
3 changes: 2 additions & 1 deletion src/ll/api/base/CompilerPredefine.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ extern "C" void* __cdecl __RTCastToVoid(void*);
#pragma pack(pop, rttidata)
// NOLINTEND
#endif
struct _IMAGE_DOS_HEADER;

// No one guarantees that the compiler's internal definitions are correct
namespace ll::internal {
Expand All @@ -220,7 +221,7 @@ using CatchableType = ::_CatchableType;
using ThrowInfo = ::_ThrowInfo;
#endif

extern "C" struct _IMAGE_DOS_HEADER __ImageBase; // NOLINT(bugprone-reserved-identifier)
extern "C" ::_IMAGE_DOS_HEADER __ImageBase; // NOLINT(bugprone-reserved-identifier)

[[nodiscard]] LL_FORCEINLINE void* getCurrentModuleHandle() noexcept { return &__ImageBase; }

Expand Down
64 changes: 37 additions & 27 deletions src/ll/api/command/Overload.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,27 +30,18 @@ class Overload : private OverloadData {
uint64 placeholder{};
Params params;
};
static inline auto ParamOffset = offsetof(Overload<Params>::TestOffset, params);
static inline auto PlaceholderOffset = offsetof(Overload<Params>::TestOffset, placeholder);

constexpr Overload& addParam(std::string_view name) {
bool hasName{};
reflection::forEachMember((*(Params*)ParamOffset), [&, this](std::string_view param, auto& val) {
if (name != param) {
return;
}
hasName = true;

using OriginalType = std::remove_cvref_t<decltype((val))>;
static constexpr auto paramOffset = offsetof(Overload<Params>::TestOffset, params);
static constexpr auto placeholderOffset = offsetof(Overload<Params>::TestOffset, placeholder);

constexpr Overload& addParam(std::string_view name, int index) {
meta::visitIndex<reflection::member_count_v<Params>>(index, [&, this]<size_t I>() {
using OriginalType = typename reflection::member_t<I, Params>;
using RemoveOptionalType = remove_optional_t<OriginalType>;

using ParamType = std::conditional_t<
traits::is_specialization_of_v<RemoveOptionalType, SoftEnum>,
std::string,
RemoveOptionalType>;

int offset = (int)(size_t)std::addressof(val);
using ParamType = std::conditional_t<
traits::is_specialization_of_v<RemoveOptionalType, SoftEnum>,
std::string,
RemoveOptionalType>;
int offset = (int)(paramOffset + reflection::member_offset_v<I, Params>);
int flagOffset = -1;
if constexpr (traits::is_specialization_of_v<OriginalType, Optional>) {
flagOffset = offset + OptionalOffsetGetter<ParamType>::value;
Expand All @@ -76,25 +67,44 @@ class Overload : private OverloadData {
true
);
});
if (!hasName) {
throw std::invalid_argument("invalid param " + std::string(name));
}
return *this;
}

explicit Overload(CommandHandle& handle, std::weak_ptr<mod::Mod> mod) : OverloadData(handle, std::move(mod)) {}

class ParamName : public std::string_view {
std::string_view str;
int idx;

constexpr int indexSearcher(std::string_view s) {
int i{};
for (auto& member : reflection::member_name_array_v<Params>) {
if (member == s) return i;
i++;
}
throw std::invalid_argument("invalid param " + std::string(str));
}

public:
template <class S>
requires(std::is_constructible_v<std::string_view, S const&>)
consteval ParamName(S const& s) : str(s),
idx(indexSearcher(s)) {}
constexpr std::string_view get() const { return str; }
constexpr int index() const { return idx; }
};

public:
[[nodiscard]] constexpr Overload& optional(std::string_view name) {
addParam(name).back().mIsOptional = true;
[[nodiscard]] constexpr Overload& optional(ParamName const name) {
addParam(name.get(), name.index()).back().mIsOptional = true;
return *this;
}
[[nodiscard]] constexpr Overload& required(std::string_view name) {
addParam(name).back().mIsOptional = false;
[[nodiscard]] constexpr Overload& required(ParamName const name) {
addParam(name.get(), name.index()).back().mIsOptional = false;
return *this;
}
[[nodiscard]] constexpr Overload& text(std::string_view text) {
addTextImpl(text, (int)PlaceholderOffset);
addTextImpl(text, (int)placeholderOffset);
return *this;
}
template <class Fn>
Expand Down
2 changes: 1 addition & 1 deletion src/ll/api/memory/linux/Signature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ void* SignatureView::resolve(std::span<std::byte> range, bool disableErrorOutput
const auto scanEnd = range.end() - elements.size() + 1;

for (auto i = range.begin(); i != scanEnd; i++) {
i = std::find( i, scanEnd, firstByte);
i = std::find(i, scanEnd, firstByte);
if (i == scanEnd) [[unlikely]] {
break;
}
Expand Down
2 changes: 1 addition & 1 deletion src/ll/api/mod/ModManagerRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Expected<> ModManagerRegistry::loadMod(Manifest manifest) noexcept try {
std::string name = manifest.name;
std::string type = manifest.type;
return getManager(type)->load(std::move(manifest)).transform([&, this] {
auto iter = impl->loadedMods.insert_or_assign(std::move(name), std::move(type)).first;
impl->loadedMods.insert_or_assign(std::move(name), std::move(type)).first;
});
} else {
return makeStringError("Unrecognized mod type: {0}"_tr(manifest.type));
Expand Down
30 changes: 28 additions & 2 deletions src/ll/api/reflection/Reflection.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,38 @@ template <class T>
concept Reflectable = is_reflectable_v<T>;

template <class T>
constexpr auto const name_array_v = boost::pfr::names_as_array<std::remove_cvref_t<T>>();
constexpr auto const member_name_array_v = boost::pfr::names_as_array<std::remove_cvref_t<T>>();

template <class T>
constexpr auto const member_count_v = boost::pfr::tuple_size_v<T>;

template <size_t I, class T>
using member_t = typename boost::pfr::tuple_element_t<I, T>;

template <class T>
struct OffsetGetter {
template <size_t S, size_t A>
struct AlignedStorage {
alignas(A) char storage[S];
};
template <class... Ts>
using AlignedTuple = boost::pfr::detail::sequence_tuple::tuple<AlignedStorage<sizeof(Ts), alignof(Ts)>...>;

template <size_t I, size_t... Ns>
static ptrdiff_t offset(std::index_sequence<Ns...>) noexcept {
AlignedTuple<member_t<Ns, T>...> layout{};
return static_cast<char const*>(&get<I>(layout).storage[0])
- static_cast<char const*>(&get<0>(layout).storage[0]);
}
};

template <size_t I, class T>
inline auto const member_offset_v = OffsetGetter<T>::template offset<I>(std::make_index_sequence<member_count_v<T>>());

template <Reflectable T, class F>
constexpr void forEachMember(T&& value, F&& func) {
boost::pfr::for_each_field(std::forward<T>(value), [func = std::forward<F>(func)](auto&& field, std::size_t idx) {
func(name_array_v<T>[idx], std::forward<decltype((field))>(field));
func(member_name_array_v<T>[idx], std::forward<decltype((field))>(field));
});
}
} // namespace ll::reflection
2 changes: 1 addition & 1 deletion src/ll/api/utils/StringUtils_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ std::string getMcCodeFromTextStyle(fmt::text_style style) {
if (fg.is_rgb) {
auto color = mce::Color(fg.value.rgb_color);
// clang-format off
constexpr const auto carr = std::array{
constexpr const std::array carr{
std::pair{cf::BLACK , mce::Color(0x000000)}, std::pair{cf::DARK_BLUE , mce::Color(0x0000AA)},
std::pair{cf::DARK_GREEN , mce::Color(0x00AA00)}, std::pair{cf::DARK_AQUA , mce::Color(0x00AAAA)},
std::pair{cf::DARK_RED , mce::Color(0xAA0000)}, std::pair{cf::DARK_PURPLE , mce::Color(0xAA00AA)},
Expand Down
9 changes: 3 additions & 6 deletions src/ll/core/command/ModManage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,9 @@ void registerModManageCommand() {
std::string{mod::modsEnumName},
mod::ModRegistrar::getInstance().getSortedModNames()
);
auto& cmd = CommandRegistrar::getInstance().getOrCreateCommand(
Util::toLower(selfModName),
"LeviLamina's main command"_tr(),
config.permission
);
cmd.alias("ll");
auto& cmd = CommandRegistrar::getInstance()
.getOrCreateCommand(Util::toLower(selfModName), "LeviLamina's main command"_tr(), config.permission)
.alias("ll");
cmd.overload<LeviCommand3>().text("load").required("mod").execute(
[](CommandOrigin const&, CommandOutput& output, LeviCommand3 const& param) {
if (ll::mod::ModManagerRegistry::getInstance().hasMod(param.mod)) {
Expand Down
4 changes: 2 additions & 2 deletions src/mc/deps/core/mce/Color.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ class Color : public ll::math::floatN4<Color> {
public:
[[nodiscard]] constexpr Color() noexcept = default;

[[nodiscard]] constexpr Color(uint hex) noexcept : Color((hex >> 16) & 0xFF, (hex >> 8) & 0xFF, hex & 0xFF) {}

template <std::integral T0, std::integral T1, std::integral T2, std::integral T3 = uint>
[[nodiscard]] constexpr Color(T0 const& ir, T1 const& ig, T2 const& ib, T3 const& ia = 255) noexcept
: floatN4(
Expand All @@ -33,6 +31,8 @@ class Color : public ll::math::floatN4<Color> {
requires(V::size() == 3)
: floatN4(v.r, v.g, v.b, a) {}

[[nodiscard]] constexpr Color(uint hex) noexcept : Color((hex >> 16) & 0xFF, (hex >> 8) & 0xFF, hex & 0xFF) {}

[[nodiscard]] constexpr Color(std::string_view hex) noexcept : floatN4(0, 0, 0, 1) { // NOLINT
if (hex[0] == '#') {
hex = hex.substr(1);
Expand Down
2 changes: 1 addition & 1 deletion src/mc/enums/BookEditAction.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ enum class BookEditAction : uchar {
Delete = 0x2,
Swap = 0x3,
Sign = 0x4,
};
};
2 changes: 1 addition & 1 deletion src/mc/nbt/DoubleTag.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class DoubleTag : public ::Tag {
public:
double data;

constexpr DoubleTag& operator=(double value) noexcept{
constexpr DoubleTag& operator=(double value) noexcept {
data = value;
return *this;
}
Expand Down
6 changes: 2 additions & 4 deletions src/mc/world/ContainerIterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ class ContainerIterator {
using reference = value_type&;
using iterator_category = std::random_access_iterator_tag;

[[nodiscard]] constexpr ContainerIterator(T* container, int position)
: mContainer(container),
mSlot(position) {}
[[nodiscard]] constexpr ContainerIterator(T* container, int position) : mContainer(container), mSlot(position) {}

[[nodiscard]] constexpr bool operator==(const ContainerIterator& other) const {
return mSlot == other.mSlot && mContainer == other.mContainer;
Expand All @@ -30,7 +28,7 @@ class ContainerIterator {
return mContainer->getItemNonConst(mSlot);
}
}
[[nodiscard]] constexpr pointer operator->() const {
[[nodiscard]] constexpr pointer operator->() const {
if constexpr (std::is_const_v<T>) {
return &mContainer->getItem(mSlot);
} else {
Expand Down
7 changes: 3 additions & 4 deletions src/mc/world/level/BlockSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,7 @@ class BlockSource : public IBlockSource, public std::enable_shared_from_this<Blo
MCVAPI DimensionType getDimensionId() const;

// vIndex: 20
MCVAPI void
fetchAABBs(std::vector<class AABB>&, class AABB const& intersectTestBox, bool withUnloadedChunks) const;
MCVAPI void fetchAABBs(std::vector<class AABB>&, class AABB const& intersectTestBox, bool withUnloadedChunks) const;

// vIndex: 21
MCVAPI void
Expand Down Expand Up @@ -170,11 +169,11 @@ class BlockSource : public IBlockSource, public std::enable_shared_from_this<Blo

// vIndex: 31
MCVAPI gsl::span<gsl::not_null<class Actor*>>
fetchEntities(class Actor const* except, class AABB const& bb, bool useHitbox, bool);
fetchEntities(class Actor const* except, class AABB const& bb, bool useHitbox, bool);

// vIndex: 32
MCVAPI gsl::span<gsl::not_null<class Actor*>>
fetchEntities(::ActorType, class AABB const&, class Actor const*, std::function<bool(class Actor*)>);
fetchEntities(::ActorType, class AABB const&, class Actor const*, std::function<bool(class Actor*)>);

// vIndex: 33
MCVAPI bool
Expand Down

0 comments on commit d81fc04

Please sign in to comment.