|
14 | 14 | * along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
|
15 | 15 | */
|
16 | 16 |
|
| 17 | +using System; |
| 18 | + |
| 19 | +using CounterStrikeSharp.API.Core; |
| 20 | +using CounterStrikeSharp.API.Modules.Utils; |
| 21 | + |
17 | 22 | namespace CounterStrikeSharp.API.Modules.Memory
|
18 | 23 | {
|
19 | 24 | public abstract class DisposableMemory : NativeObject, IDisposableMemory
|
20 | 25 | {
|
| 26 | + internal static Type DisposableType = typeof(DisposableMemory); |
| 27 | + |
21 | 28 | internal static int _instances;
|
22 | 29 |
|
23 | 30 | internal static int Instances
|
@@ -82,14 +89,111 @@ public virtual void ReleaseUnmanaged()
|
82 | 89 | MemAlloc.Free(Handle);
|
83 | 90 | }
|
84 | 91 |
|
| 92 | + /// <summary> |
| 93 | + /// Recursively checks if the given type is (or contains) a <see cref="DisposableMemory"/> |
| 94 | + /// </summary> |
| 95 | + /// <param name="type"></param> |
| 96 | + /// <returns></returns> |
| 97 | + internal static bool IsDisposableType(Type type) |
| 98 | + { |
| 99 | + /* This part will be only needed if we have a correct implementation for `NetworkedVector<>` or any class that has any `DisposableMemory` as generic. |
| 100 | + * Until that, this would be overkill |
| 101 | + if (type == DisposableType || DisposableType.IsAssignableFrom(type)) |
| 102 | + return true; |
| 103 | +
|
| 104 | + if (type.IsGenericType) |
| 105 | + { |
| 106 | + foreach (Type arg in type.GetGenericArguments()) |
| 107 | + { |
| 108 | + if (DisposableType.IsAssignableFrom(arg)) |
| 109 | + { |
| 110 | + return true; |
| 111 | + } |
| 112 | +
|
| 113 | + if (IsDisposableType(arg)) |
| 114 | + { |
| 115 | + return true; |
| 116 | + } |
| 117 | + } |
| 118 | + } |
| 119 | +
|
| 120 | + return type.BaseType != null && type.BaseType.Namespace!.StartsWith("CounterStrikeSharp") && IsDisposableType(type.BaseType); |
| 121 | + */ |
| 122 | + |
| 123 | + return type == DisposableType || DisposableType.IsAssignableFrom(type); |
| 124 | + } |
| 125 | + |
| 126 | + internal static void MarkAsPure(DisposableMemory disposable) |
| 127 | + { |
| 128 | + disposable.PurePointer = true; |
| 129 | + |
| 130 | + // we should not count these as they are not handled by us. |
| 131 | + Instances--; |
| 132 | + } |
| 133 | + |
| 134 | + /* |
| 135 | + internal static void MarkCollectionAsPure<T>(IEnumerable<T> collection) where T: DisposableMemory |
| 136 | + { |
| 137 | + foreach (DisposableMemory disposable in collection) |
| 138 | + { |
| 139 | + MarkAsPure(disposable); |
| 140 | + } |
| 141 | + } |
| 142 | + */ |
| 143 | + |
| 144 | + /* Span<T> where T has pointer or reference: Only value types without pointers or references are supported. |
| 145 | + internal static void MarkSpanAsPure<T>(Span<T> collection) |
| 146 | + { |
| 147 | + foreach (T instance in collection) |
| 148 | + { |
| 149 | + if (instance is DisposableMemory disposable) |
| 150 | + { |
| 151 | + MarkAsPure(disposable); |
| 152 | + } |
| 153 | + } |
| 154 | + } |
| 155 | + */ |
| 156 | + |
85 | 157 | internal static void MarkAsPure(object? instance)
|
86 | 158 | {
|
87 |
| - if (instance != null && instance is DisposableMemory disposable) |
| 159 | + if (instance == null) |
| 160 | + return; |
| 161 | + |
| 162 | + switch (instance) |
88 | 163 | {
|
89 |
| - disposable.PurePointer = true; |
| 164 | + case DisposableMemory disposable: |
| 165 | + MarkAsPure(disposable); |
| 166 | + break; |
90 | 167 |
|
91 |
| - // we should not count these as they are not handled by us. |
92 |
| - Instances--; |
| 168 | + /* since 'Networked vectors currently only support CHandle<T>' lets stab ourselves in the back in the future |
| 169 | + case NetworkedVector<Vector> vectors: |
| 170 | + MarkCollectionAsPure<Vector>(vectors); |
| 171 | + break; |
| 172 | +
|
| 173 | + case NetworkedVector<Vector2D> vector2ds: |
| 174 | + MarkCollectionAsPure<Vector2D>(vector2ds); |
| 175 | + break; |
| 176 | +
|
| 177 | + case NetworkedVector<Vector4D> vector4ds: |
| 178 | + MarkCollectionAsPure<Vector4D>(vector4ds); |
| 179 | + break; |
| 180 | +
|
| 181 | + // 'Angle' is only referenced inside the 'Vector' class |
| 182 | + case NetworkedVector<QAngle> angles: |
| 183 | + MarkCollectionAsPure<QAngle>(angles); |
| 184 | + break; |
| 185 | +
|
| 186 | + case NetworkedVector<Quaternion> quaternions: |
| 187 | + MarkCollectionAsPure<Quaternion>(quaternions); |
| 188 | + break; |
| 189 | +
|
| 190 | + case NetworkedVector<matrix3x4_t> matrixes: |
| 191 | + MarkCollectionAsPure<matrix3x4_t>(matrixes); |
| 192 | + break; |
| 193 | +
|
| 194 | + default: throw new NotSupportedException($"'MarkAsPure': type '{instance.GetType().Name}' is not supported."); |
| 195 | + */ |
| 196 | + default: return; |
93 | 197 | }
|
94 | 198 | }
|
95 | 199 | }
|
|
0 commit comments