 |
Botcraft 1.21.4
|
Loading...
Searching...
No Matches
Go to the documentation of this file.
4#define DEFINE_CONDITION(Name, ...) private: bool Name() const { return __VA_ARGS__; } static_assert(true, "Forcing ;")
6#ifdef PROTOCOLCRAFT_DETAILED_PARSING
7#define _OFFSETS_DECLARATION(Name) \
8 using Name##_offset_type = \
9 Internal::OffsetType<typename Name##_type::storage_type>::type; \
10 Name##_offset_type Name##_start{}; \
11 Name##_offset_type Name##_end{}
12#define _OFFSETS_FIELDS_DATA_DECLARATION(Name) \
13 using field_offset_type = Name##_offset_type; \
14 template <typename Parent> static constexpr field_offset_type \
15 Parent::* field_start_offset_ptr = &Parent::Name##_start; \
16 template <typename Parent> static constexpr field_offset_type \
17 Parent::* field_end_offset_ptr = &Parent::Name##_end
19#define _OFFSETS_DECLARATION(Name)
20#define _OFFSETS_FIELDS_DATA_DECLARATION(Name)
35#define SERIALIZED_FIELD_WITHOUT_GETTER_SETTER(Name, ...) \
37 using Name##_type = typename Internal::SerializedType<__VA_ARGS__>; \
38 Name##_type::storage_type Name{}; \
39 _OFFSETS_DECLARATION(Name); \
40 template <size_t, typename> struct FieldsData; \
41 static constexpr size_t Name##_index = \
42 Internal::field_index<0, struct FieldDummy##Name, FieldsData>; \
43 template <typename T> \
44 struct FieldsData<Name##_index, T> { \
45 static constexpr std::array name_array = \
46 Internal::ToSnakeCase<Internal::GetSnakeCaseSize(#Name)>(#Name); \
47 static constexpr std::string_view field_name = \
48 Internal::ToStringView<std::size(name_array)>(name_array); \
49 using field_type = __VA_ARGS__; \
50 using field_storage_type = Name##_type::storage_type; \
51 using field_serialization_type = Name##_type::serialization_type; \
52 template <typename Parent> static constexpr field_storage_type \
53 Parent::*field_ptr = &Parent::Name; \
54 _OFFSETS_FIELDS_DATA_DECLARATION(Name); \
56 static_assert(true, "Forcing ;")
64 std::conditional_t<std::is_arithmetic_v<Name##_type::storage_type> || std::is_enum_v<Name##_type::storage_type>, \
65 Name##_type::storage_type, const Name##_type::storage_type&> Get##Name() const { return Name; } \
66 static_assert(true, "Forcing ;")
71 std::conditional_t<std::is_arithmetic_v<Name##_type::storage_type> || std::is_enum_v<Name##_type::storage_type>, \
72 Name##_type::storage_type, const Name##_type::storage_type&> Name##_) { Name = Name##_; return *this; } \
73 static_assert(true, "Forcing ;")
75#define GETTER_SETTER(Name) GETTER(Name); SETTER(Name)
77#define SERIALIZED_FIELD(Name, ...) \
78 SERIALIZED_FIELD_WITHOUT_GETTER_SETTER(Name, __VA_ARGS__); \
82#define DECLARE_READ protected: virtual void ReadImpl(ReadIterator& iter, size_t& length) override
84#define DECLARE_WRITE protected: virtual void WriteImpl(WriteContainer& container) const override
86#define DECLARE_SERIALIZE protected: virtual Json::Value SerializeImpl() const override
89#ifdef PROTOCOLCRAFT_DETAILED_PARSING
90#define _DEFINE_OFFSETS_UTILITIES \
91 template <size_t i> auto& GetFieldStartOffset() { \
92 return this->*FieldsData<i, void>::template field_start_offset_ptr<std::remove_reference_t<decltype(*this)>>; } \
93 template <size_t i> auto& GetFieldEndOffset() { \
94 return this->*FieldsData<i, void>::template field_end_offset_ptr<std::remove_reference_t<decltype(*this)>>; } \
95 template <size_t i> const auto& GetFieldStartOffset() const { \
96 return this->*FieldsData<i, void>::template field_start_offset_ptr<std::remove_reference_t<decltype(*this)>>; } \
97 template <size_t i> const auto& GetFieldEndOffset() const { \
98 return this->*FieldsData<i, void>::template field_end_offset_ptr<std::remove_reference_t<decltype(*this)>>; }
100#define _DEFINE_OFFSETS_UTILITIES
106#define DEFINE_UTILITIES \
108 template <size_t, typename> struct FieldsData; \
109 static constexpr size_t num_fields = Internal::field_index<0, void, FieldsData>; \
110 template <size_t i> static constexpr std::string_view field_name = FieldsData<i, void>::field_name; \
111 template <size_t i> using field_type = typename FieldsData<i, void>::field_type; \
112 template <size_t i> using field_storage_type = typename FieldsData<i, void>::field_storage_type; \
113 template <size_t i> using field_serialization_type = \
114 typename FieldsData<i, void>::field_serialization_type; \
115 template <size_t i> auto& GetField() { \
116 return this->*FieldsData<i, void>::template field_ptr<std::remove_reference_t<decltype(*this)>>; } \
117 template <size_t i> const auto& GetField() const { \
118 return this->*FieldsData<i, void>::template field_ptr<std::remove_reference_t<decltype(*this)>>; } \
119 _DEFINE_OFFSETS_UTILITIES; \
120 static_assert(true, "Forcing ;")
123#define DECLARE_READ_WRITE_SERIALIZE DEFINE_UTILITIES; DECLARE_READ; DECLARE_WRITE; DECLARE_SERIALIZE
125#ifdef PROTOCOLCRAFT_DETAILED_PARSING
126#define _OFFSETS_POINTERS , &this->GetFieldStartOffset<i>(), &this->GetFieldEndOffset<i>()
128#define _OFFSETS_POINTERS
131#define DEFINE_READ(ClassName) \
132 void ClassName::ReadImpl(ReadIterator& iter, size_t& length) { \
133 Internal::loop<num_fields>([&](auto i) { \
135 auto& field = this->GetField<i>(); \
136 if constexpr (Internal::IsCustomType<field_type<i>>) { \
137 field = field_type<i>::Read( \
138 this, iter, length _OFFSETS_POINTERS); \
140 else if constexpr (Internal::IsConditioned<field_type<i>>) { \
141 if (field_type<i>::Evaluate(this)) { \
142 if constexpr (field_type<i>::stored_as_optional) { \
144 typename field_storage_type<i>::value_type, \
145 field_serialization_type<i>>( \
146 iter, length _OFFSETS_POINTERS); \
150 field_storage_type<i>, \
151 field_serialization_type<i>>( \
152 iter, length _OFFSETS_POINTERS); \
155 else if constexpr (field_type<i>::stored_as_optional) { \
156 field = std::nullopt; \
161 field_storage_type<i>, \
162 field_serialization_type<i>>( \
163 iter, length _OFFSETS_POINTERS); \
166 catch (const std::exception& ex) { \
167 throw std::runtime_error(std::string("While reading ") + \
168 std::string(field_name<i>) + " (" + std::to_string(i) + \
169 "th field) in " + #ClassName + "\n" + ex.what()); \
172 } static_assert(true, "Forcing ;")
175#define DEFINE_WRITE(ClassName) \
176 void ClassName::WriteImpl(WriteContainer& container) const { \
177 Internal::loop<num_fields>([&](auto i) { \
178 const auto& field = this->GetField<i>(); \
179 if constexpr (Internal::IsCustomType<field_type<i>>) { \
180 field_type<i>::Write(this, field, container); \
182 else if constexpr (Internal::IsConditioned<field_type<i>>) { \
183 if (field_type<i>::Evaluate(this)) { \
184 if constexpr (field_type<i>::stored_as_optional) { \
186 typename field_storage_type<i>::value_type, \
187 field_serialization_type<i>>(field.value(), container); \
191 field_storage_type<i>, \
192 field_serialization_type<i>>(field, container); \
198 field_storage_type<i>, \
199 field_serialization_type<i>>(field, container); \
202 } static_assert(true, "Forcing ;")
205#define DEFINE_SERIALIZE(ClassName) \
206 Json::Value ClassName::SerializeImpl() const { \
207 Json::Value output; \
208 Internal::loop<num_fields>([&](auto i) { \
209 const auto& field = this->GetField<i>(); \
210 std::optional<Json::Value> serialized = std::nullopt; \
211 if constexpr (Internal::IsCustomType<field_type<i>>) { \
212 serialized = field_type<i>::Serialize( \
213 this, field _OFFSETS_POINTERS); \
215 else if constexpr (Internal::IsConditioned<field_type<i>>) { \
216 if (field_type<i>::Evaluate(this)) { \
217 serialized = SerializeType<field_storage_type<i>>( \
218 field _OFFSETS_POINTERS); \
222 serialized = SerializeType<field_storage_type<i>>( \
223 field _OFFSETS_POINTERS); \
225 if (serialized.has_value()) { \
226 output[std::string(field_name<i>)] = serialized.value(); \
230 } static_assert(true, "Forcing ;")
233#define DEFINE_NETWORK_TYPE(ClassName) \
234 DEFINE_READ(ClassName); \
235 DEFINE_WRITE(ClassName); \
236 DEFINE_SERIALIZE(ClassName)
239#define DEFINE_MESSAGE_CLASS(ClassName) \
240 DEFINE_READ(ClassName); \
241 DEFINE_WRITE(ClassName); \
242 DEFINE_SERIALIZE(ClassName); \
243 template class BaseMessage<ClassName>