ChatPlexSDK-BS 1.0.1-v6.2.0
C++ ChatPlex BeatSaber SDK
Loading...
Searching...
No Matches
il2cpp_customtype.hpp
1#pragma once
2
3#include <type_traits>
4
5#include <custom-types/shared/macros.hpp>
6
7namespace CP_SDK::Utils::Internals {
8
9 template <typename ... t_Args>
10 constexpr std::size_t ArgCount(t_Args&&...)
11 {
12 return sizeof...(t_Args);
13 }
14
15 template<class... t_Args>
16 std::vector<Il2CppClass*> ExtractInterfacesClasses()
17 {
18 return { classof(t_Args*)... };
19 }
20
21 template <typename t_Type>
22 concept Concept_IsCustomType = requires(t_Type)
23 {
24 { t_Type::___TypeRegistration::get() } -> std::same_as<::custom_types::TypeRegistration*>;
25 };
26
27 template<typename t_Type>
28 constexpr ::custom_types::TypeRegistration* GetCustomBaseIf()
29 {
30 if constexpr (Concept_IsCustomType<t_Type>)
31 return t_Type::___TypeRegistration::get();
32
33 return nullptr;
34 }
35
36}
37
40
41#define __CP_SDK_IL2CPP_INHERIT(__mNamespace, __mName, __mBaseClass, ...) \
42 protected: __mName() = default; \
43 public: __mName(const __mName&) = delete; \
44 public: __mName(__mName&&) = delete; \
45 __CP_SDK_IL2CPP_CUSTOM_TYPE_DECLARE(__mNamespace, __mName, __mBaseClass, std::vector<Il2CppClass*>({ __VA_ARGS__ }))
46
47#define __CP_SDK_IL2CPP_INHERIT_HELPERS(__mName) \
48 template<> struct ::il2cpp_utils::il2cpp_type_check::il2cpp_no_arg_class<::__mName*> { \
49 static inline Il2CppClass* get() { \
50 return ::__mName::___TypeRegistration::klass_ptr; \
51 } \
52 }; \
53 template<> struct ::il2cpp_utils::il2cpp_type_check::need_box<::__mName> { \
54 constexpr static bool value = false; \
55 };
56
57#define __CP_SDK_IL2CPP_INHERIT_INIT(__mName) \
58 ::custom_types::TypeRegistration* __mName::___TypeRegistration::instance; \
59 static __mName::___TypeRegistration __registration_instance_##__mName; \
60 char* __mName::___TypeRegistration::st_fields; \
61 Il2CppClass* __mName::___TypeRegistration::klass_ptr; \
62 bool __mName::___TypeRegistration::init = false;
63
66
67#define __CP_SDK_IL2CPP_CTOR_FIELD() \
68 protected: bool __Prevent_CPP_CTOR = false
69
70#define __CP_SDK_IL2CPP_CALL_CPP_CTOR(__mType, ...) \
71 INVOKE_CTOR(__VA_ARGS__);
72
73#define __CP_SDK_IL2CPP_DECLARE_CTOR(__mType) \
74 __CP_SDK_IL2CPP_CTOR_FIELD(); \
75 __CP_SDK_IL2CPP_DECLARE_CTOR_BASE(__mType)
76
77#define __CP_SDK_IL2CPP_DECLARE_CTOR_CHILD(__mType) \
78 __CP_SDK_IL2CPP_DECLARE_CTOR_BASE(__mType)
79
80#define __CP_SDK_IL2CPP_DECLARE_CTOR_BASE(__mType) \
81 public: \
82 void __mType##__Constructor(); \
83 template<::il2cpp_utils::CreationType creationType = ::il2cpp_utils::CreationType::Temporary, class... TArgs> \
84 static ___TargetType* New_ctor(TArgs&&... args) { \
85 static_assert(::custom_types::Decomposer<decltype(&___TargetType::__mType##__Constructor)>::convertible<TArgs...>(), "Arguments provided to New_ctor must be convertible to the constructor!"); \
86 ___TargetType* obj; \
87 if constexpr (creationType == ::il2cpp_utils::CreationType::Temporary) { \
88 obj = static_cast<___TargetType*>(::il2cpp_functions::object_new(___TypeRegistration::klass_ptr)); \
89 } else { \
90 obj = static_cast<___TargetType*>(::il2cpp_utils::createManual(___TypeRegistration::klass_ptr)); \
91 } \
92 obj->__mType##__Constructor(std::forward<TArgs>(args)...); \
93 return obj; \
94 } \
95 ___CREATE_INSTANCE_METHOD(__mType##__Constructor, ".ctor", METHOD_ATTRIBUTE_PUBLIC | METHOD_ATTRIBUTE_HIDE_BY_SIG | METHOD_ATTRIBUTE_SPECIAL_NAME | METHOD_ATTRIBUTE_RT_SPECIAL_NAME, nullptr); \
96 void __mType##__Constructor_Impl()
97
98
99#define __CP_SDK_IL2CPP_DECLARE_CTOR_IMPL(__mType) \
100 void __mType::__mType##__Constructor() \
101 { \
102 /*ChatPlexSDK::Logger()->Error(u"" + StringW(#__mType) + u"::Constructor");*/ \
103 auto __Can_CPP_CTOR = !__Prevent_CPP_CTOR; \
104 __Prevent_CPP_CTOR = true; \
105 if (__Can_CPP_CTOR) __CP_SDK_IL2CPP_CALL_CPP_CTOR(__mType); \
106 if (___TargetType::___TypeRegistration::get()->customBase()) \
107 ::custom_types::InvokeBaseCtor(___TargetType::___TypeRegistration::get()->customBase()->klass(), this); \
108 else \
109 ::custom_types::InvokeBaseCtor(___TargetType::___TypeRegistration::get()->baseType(), this); \
110 __Prevent_CPP_DTOR = false; \
111 __mType##__Constructor_Impl(); \
112 } \
113 void __mType::__mType##__Constructor_Impl()
114
117
118#define __CP_SDK_IL2CPP_DTOR_FIELD() \
119 protected: bool __Prevent_CPP_DTOR = false
120
121#define __CP_SDK_IL2CPP_CALL_CPP_DTOR(__mType) \
122 this->~__mType()
123
124#define __CP_SDK_IL2CPP_DECLARE_DTOR_MONOBEHAVIOUR(__mType) \
125 __CP_SDK_IL2CPP_DTOR_FIELD(); \
126 __CP_SDK_IL2CPP_DECLARE_DTOR_MONOBEHAVIOUR_BASE(__mType)
127
128#define __CP_SDK_IL2CPP_DECLARE_DTOR_MONOBEHAVIOUR_CHILD(__mType) \
129 __CP_SDK_IL2CPP_DECLARE_DTOR_MONOBEHAVIOUR_BASE(__mType)
130
131#define __CP_SDK_IL2CPP_DECLARE_DTOR_MONOBEHAVIOUR_BASE(__mType) \
132 public: \
133 void __mType##__Destructor(); \
134 ___CREATE_INSTANCE_METHOD(__mType##__Destructor, "OnDestroy", METHOD_ATTRIBUTE_PUBLIC | METHOD_ATTRIBUTE_HIDE_BY_SIG, nullptr); \
135 void __mType##__Destructor_Impl()
136
137#define __CP_SDK_IL2CPP_DECLARE_DTOR_MONOBEHAVIOUR_IMPL(__mType) \
138 void __mType::__mType##__Destructor() \
139 { \
140 /*ChatPlexSDK::Logger()->Error(CP_SDK_U16STR(__Type) u"::OnDestroy");*/ \
141 __mType##__Destructor_Impl(); \
142 auto __Can_CPP_DTOR = !__Prevent_CPP_DTOR; \
143 __Prevent_CPP_DTOR = true; \
144 auto l_BaseType = ___TypeRegistration::get()->baseType(); \
145 __CP_SDK_IL2CPP_CALL_BASE_METHOD(false, l_BaseType, CP_SDK_U16STR(__mType) u"__BaseClass", "OnDestroy"); \
146 if (__Can_CPP_DTOR) __CP_SDK_IL2CPP_CALL_CPP_DTOR(__mType); \
147 } \
148 void __mType::__mType##__Destructor_Impl()
149
152
153#define __CP_SDK_IL2CPP_OVERRIDE_METHOD(__mBaseClass, __mRet, __mName, __mMethodInfo, ...) \
154 public: \
155 __mRet __mBaseClass##__##__mName(__VA_ARGS__); \
156 ___CREATE_INSTANCE_METHOD(__mBaseClass##__##__mName, #__mName, (__mMethodInfo->flags & ~METHOD_ATTRIBUTE_ABSTRACT) | METHOD_ATTRIBUTE_PUBLIC | METHOD_ATTRIBUTE_HIDE_BY_SIG, __mMethodInfo)
157
160
162#define __CP_SDK_IL2CPP_CALL_BASE_METHOD(__mLog, __mBaseClass, __mBaseClassName, __mMethodName, ...) \
163 { \
164 static auto l_BaseMethodInfo = il2cpp_functions::class_get_method_from_name(__mBaseClass, __mMethodName, CP_SDK::Utils::Internals::ArgCount(__VA_ARGS__)); \
165 if (l_BaseMethodInfo) il2cpp_utils::RunMethod(this, l_BaseMethodInfo __VA_OPT__(,) __VA_ARGS__); \
166 else if (__mLog) CP_SDK::ChatPlexSDK::Logger()->Error(u"[CP_SDK_IL2CPP_CALL_BASE_METHOD] Method " CP_SDK_U16STR(__mMethodName) u" not found in class " __mBaseClassName); \
167 }
168
171
172#define __CP_SDK_IL2CPP_CUSTOM_TYPE_DECLARE(__mNamespace, __mName, __mBaseClass, __mInterfaces) \
173 using ___TargetType = __mName; \
174 constexpr static auto ___Base__Size = sizeof(__mBaseClass); \
175 friend ::custom_types::Register; \
176 public: \
177 struct ___TypeRegistration : ::custom_types::TypeRegistration { \
178 ___TypeRegistration() { \
179 ::custom_types::Register::AddType(this); \
180 instance = this; \
181 } \
182 static inline std::vector<::custom_types::FieldRegistrator*> fields; \
183 std::vector<::custom_types::FieldRegistrator*> const getFields() const override { \
184 return fields; \
185 } \
186 static void addField(::custom_types::FieldRegistrator* inst) { \
187 fields.push_back(inst); \
188 ::custom_types::_logger().debug("Adding instance field: %s.%s new size: %lu", #__mName, inst->name(), fields.size()); \
189 } \
190 static inline std::vector<::custom_types::StaticFieldRegistrator*> staticFields; \
191 std::vector<::custom_types::StaticFieldRegistrator*> const getStaticFields() const override { \
192 return staticFields; \
193 } \
194 static void addStaticFieldInstance(::custom_types::StaticFieldRegistrator* inst) { \
195 staticFields.push_back(inst); \
196 ::custom_types::_logger().debug("Adding static field: %s.%s new size: %lu", #__mName, inst->name(), staticFields.size()); \
197 } \
198 static inline std::vector<::custom_types::MethodRegistrator*> methods; \
199 std::vector<::custom_types::MethodRegistrator*> const getMethods() const override { \
200 return methods; \
201 } \
202 static void addMethod(::custom_types::MethodRegistrator* inst) { \
203 methods.push_back(inst); \
204 ::custom_types::_logger().debug("Adding method: %s.%s new size: %lu", #__mName, inst->name(), methods.size()); \
205 } \
206 static inline size_t staticFieldOffset; \
207 static size_t addStaticField(size_t sz) { \
208 auto tmp = staticFieldOffset; \
209 staticFieldOffset += sz; \
210 return tmp; \
211 } \
212 static char* st_fields; \
213 char*& static_fields() override { \
214 return st_fields; \
215 } \
216 size_t static_fields_size() const override { \
217 return staticFieldOffset; \
218 } \
219 constexpr const char* name() const override { \
220 return #__mName; \
221 } \
222 constexpr const char* namespaze() const override { \
223 return __mNamespace; \
224 } \
225 constexpr const char* dllName() const override { \
226 return __mNamespace; \
227 } \
228 Il2CppClass* baseType() const override { \
229 return ::il2cpp_utils::il2cpp_type_check::il2cpp_no_arg_class<__mBaseClass*>::get(); \
230 } \
231 std::vector<Il2CppClass*> const interfaces() const override { \
232 return __mInterfaces; \
233 } \
234 constexpr Il2CppTypeEnum typeEnum() const override { \
235 return Il2CppTypeEnum::IL2CPP_TYPE_CLASS; \
236 } \
237 constexpr uint32_t typeFlags() const override { \
238 return 0; \
239 } \
240 static Il2CppClass* klass_ptr; \
241 Il2CppClass*& klass() const override { \
242 return klass_ptr; \
243 } \
244 size_t size() const override { \
245 return sizeof(___TargetType); \
246 } \
247 TypeRegistration* customBase() const override { \
248 return CP_SDK::Utils::Internals::GetCustomBaseIf<__mBaseClass>(); \
249 } \
250 bool initialized() const override { \
251 return init; \
252 } \
253 void setInitialized() const override { \
254 init = true; \
255 } \
256 static bool init; \
257 static TypeRegistration* instance; \
258 static TypeRegistration* get() { \
259 return instance; \
260 } \
261 };