LeviLamina
Loading...
Searching...
No Matches
Overload.h
1#pragma once
2
3#include <cstddef>
4#include <stdexcept>
5#include <string>
6#include <string_view>
7#include <type_traits>
8
9#include "ll/api/command/Command.h"
10#include "ll/api/command/OverloadData.h"
11#include "ll/api/command/ParamTraits.h"
12
13namespace ll::command {
14
15template <reflection::Reflectable Params>
16class Overload : private OverloadData {
17 friend CommandHandle;
18
19 struct TestOffset : private ::Command {
20 uint64 placeholder{};
21 Params params;
22 };
23 static constexpr auto paramOffset = offsetof(Overload<Params>::TestOffset, params);
24 static constexpr auto placeholderOffset = offsetof(Overload<Params>::TestOffset, placeholder);
25
26 template <size_t I, bool Opt>
27 constexpr void addParam(std::string_view name) {
28 using OriginalType = std::remove_cvref_t<typename reflection::member_t<I, Params>>;
29 using RemoveOptionalType = remove_optional_t<OriginalType>;
30 int offset = (int)(paramOffset + reflection::member_offset_v<I, Params>);
31 int flagOffset = -1;
32 if constexpr (traits::is_specialization_of_v<OriginalType, Optional>) {
34 }
36 Traits::transformData(addParamImpl(
37 Traits::typeId(),
38 Traits::parseFn(),
39 name,
40 Traits::dataType(),
41 Traits::enumNameOrPostfix(),
42 Traits::subChain(),
43 offset,
44 flagOffset,
45 Opt,
46 Traits::options()
47 ));
48 }
49 explicit Overload(CommandHandle& handle, std::weak_ptr<mod::Mod> mod) : OverloadData(handle, std::move(mod)) {}
50
51 class ParamName {
52 std::string_view str;
53 int idx;
54
55 constexpr int indexSearcher(std::string_view s) {
56 int i{};
57 for (auto& member : reflection::member_name_array_v<Params>) {
58 if (member == s) return i;
59 i++;
60 }
61#ifndef __INTELLISENSE__
62 throw std::invalid_argument("invalid param " + std::string(str));
63#else
64 return -1;
65#endif
66 }
67
68 public:
69 template <class S>
70 requires(std::is_constructible_v<std::string_view, S const&>)
71 consteval ParamName(S const& s) : str(s),
72 idx(indexSearcher(s)) {}
73 constexpr std::string_view get() const { return str; }
74 constexpr int index() const { return idx; }
75 };
76
77public:
78 [[nodiscard]] constexpr Overload& optional(ParamName const name) {
79 meta::visitIndex<reflection::member_count_v<Params>>(name.index(), [&]<size_t I>() {
80 addParam<I, true>(name.get());
81 });
82 return *this;
83 }
84 [[nodiscard]] constexpr Overload& required(ParamName const name) {
85 meta::visitIndex<reflection::member_count_v<Params>>(name.index(), [&]<size_t I>() {
86 addParam<I, false>(name.get());
87 });
88 return *this;
89 }
90 [[nodiscard]] constexpr Overload& text(std::string_view text) {
91 addTextImpl(text, (int)placeholderOffset);
92 return *this;
93 }
94 template <class Fn>
95 [[nodiscard]] constexpr Overload& modify(Fn&& fn) {
96 std::invoke(std::forward<Fn>(fn), back());
97 return *this;
98 }
99
100 [[nodiscard]] constexpr Overload& postfix(std::string_view postfix) {
101 return modify([&](auto&& val) {
102 val.mEnumNameOrPostfix = storeStr(postfix);
103 val.mParamType = CommandParameterDataType::Postfix;
104 });
105 }
106 [[nodiscard]] constexpr Overload& option(CommandParameterOption option) {
107 return modify([&](auto&& val) { val.addOptions(option); });
108 }
109 [[nodiscard]] constexpr Overload& deoption(CommandParameterOption option) {
110 return modify([&](auto&& val) {
111 val.mOptions = (CommandParameterOption)((uchar)(val.mOptions) & (!(uchar)option));
112 });
113 return *this;
114 }
115
116 template <class Fn>
117 void constexpr execute(Fn&& fn) {
118 using E = std::remove_cvref_t<Fn>;
119 setFactory([fn = std::forward<Fn>(fn)]() -> std::unique_ptr<::Command> {
120 return std::unique_ptr<Command<Params, E>>(new Command<Params, E>{fn});
121 });
122 }
123};
124} // namespace ll::command
Definition Command.h:17
Definition CommandHandle.h:13
Definition Command.h:20
Definition OverloadData.h:20
Definition Overload.h:16
Definition Optional.h:242
Definition ParamTraits.h:33