ChatPlexSDK-BS 1.0.1-v6.2.0
C++ ChatPlex BeatSaber SDK
Loading...
Searching...
No Matches
MonoPtr.hpp
1#pragma once
2
3#include "../Unity/MonoPtrHolder.hpp"
4
5#include <UnityEngine/Object.hpp>
6
7namespace CP_SDK::Utils {
8
9 template<class t_Ptr, bool t_Force = false>
10 class MonoPtr
11 {
12 static_assert(t_Force || !std::is_assignable_v<Il2CppObject*, t_Ptr*>, "Don't use non Mono types with MonoPtr.");
13
14 public:
15 MonoPtr() : m_Wrapper(nullptr) { }
16 MonoPtr(t_Ptr* p_Pointer)
17 : m_Wrapper(Unity::MonoPtrHolder::GetOrRegister((Il2CppObject*)p_Pointer))
18 {
19 if (m_Wrapper) m_Wrapper->Grab();
20 }
21 MonoPtr(const MonoPtr& p_Other)
22 : m_Wrapper(p_Other.m_Wrapper)
23 {
24 if (m_Wrapper) m_Wrapper->Grab();
25 }
26 MonoPtr(MonoPtr&& p_Other)
27 : m_Wrapper(p_Other.m_Wrapper)
28 {
29 p_Other.m_Wrapper = nullptr;
30 }
31 ~MonoPtr()
32 {
33 if (m_Wrapper) m_Wrapper->Drop();
34 m_Wrapper = nullptr;
35 }
36
37 public:
38 t_Ptr* Ptr(bool p_Throw = true) const
39 {
40 auto l_IsDead = !m_Wrapper || !m_Wrapper->Ptr;
41 if constexpr (std::is_assignable_v<UnityEngine::Object, t_Ptr>)
42 {
43 auto l_UObject = reinterpret_cast<UnityEngine::Object*>(m_Wrapper->Ptr);
44 if (l_IsDead || !l_UObject->m_CachedPtr.m_value)
45 l_IsDead = true;
46 }
47
48 if (p_Throw && l_IsDead)
49 {
50 ChatPlexSDK::Logger()->Error(u"Dead pointer " + csTypeOf(t_Ptr*)->get_Name());
51 throw NullHandleException();
52 }
53
54 return !l_IsDead ? reinterpret_cast<t_Ptr*>(m_Wrapper->Ptr) : nullptr;
55 }
56
57 bool IsUnityObject()
58 {
59 if constexpr (std::is_assignable_v<UnityEngine::Object, t_Ptr>)
60 return true;
61
62 return false;
63 }
64
65 public:
66 operator bool() const { return Ptr(false); }
67
68 t_Ptr* operator ->() { return Ptr(true); }
69 const t_Ptr* operator ->() const { return const_cast<t_Ptr*>(Ptr(true)); }
70
71 public:
72 MonoPtr& operator=(t_Ptr* p_Pointer)
73 {
74 if (m_Wrapper && m_Wrapper->Ptr == (Il2CppObject*)p_Pointer) return *this;
75 if (m_Wrapper) m_Wrapper->Drop();
76 if (!p_Pointer)
77 {
78 m_Wrapper = nullptr;
79 return *this;
80 }
81
82 m_Wrapper = Unity::MonoPtrHolder::GetOrRegister((Il2CppObject*)p_Pointer);
83 if (m_Wrapper) m_Wrapper->Grab();
84
85 return *this;
86 }
87 MonoPtr& operator=(const MonoPtr<t_Ptr>& p_Other)
88 {
89 if (m_Wrapper) m_Wrapper->Drop();
90 m_Wrapper = p_Other.m_Wrapper;
91 if (m_Wrapper) m_Wrapper->Grab();
92
93 return *this;
94 }
95 MonoPtr& operator=(MonoPtr&& p_Other)
96 {
97 if (m_Wrapper) m_Wrapper->Drop();
98 m_Wrapper = p_Other.m_Wrapper;
99 p_Other.m_Wrapper = nullptr;
100
101 return *this;
102 }
103
104 template<class t_OtherPtr> requires(t_Force || std::is_assignable_v<t_Ptr*&, t_OtherPtr*> || std::is_same_v<t_Ptr*&, t_OtherPtr*>)
105 bool operator==(const MonoPtr<t_OtherPtr>& p_Other) const { return m_Wrapper == p_Other.m_Wrapper; }
106 template<class t_OtherPtr>
107 bool operator==(t_OtherPtr* p_Pointer) const { return m_Wrapper && m_Wrapper->Ptr == p_Pointer; }
108
109 public:
111
112 };
113
116
117 template<class t_Ptr>
118 using CMonoPtrRef = const MonoPtr<t_Ptr>&;
119
120 template<class t_Ptr>
121 using MonoPtrRef = MonoPtr<t_Ptr>&;
122
125
126 template<class t_Type> requires(std::is_assignable_v<UnityEngine::Object, t_Type>)
127 static bool IsUnityPtrValid(t_Type* p_Ptr)
128 {
129 if (!p_Ptr)
130 return false;
131
132 auto l_UObject = reinterpret_cast<UnityEngine::Object*>(p_Ptr);
133 if (!l_UObject->m_CachedPtr.m_value)
134 return false;
135
136 return true;
137 }
138
139}
static Logging::ILogger * Logger()
Logger instance.
void Grab()
Grab a reference to this wrapper.
void Drop()
Drop a reference to this wrapper.
static Wrapper * GetOrRegister(Il2CppObject *p_Pointer)
Get or register a new wrapper.
Various platform utils like Delegate/Action/Function/Event system.
Definition Delegate.hpp:8