From 33013b9484a88b114c0911466d2e7c38d35b2878 Mon Sep 17 00:00:00 2001 From: DrSmugleaf Date: Tue, 16 May 2023 13:36:00 -0700 Subject: [PATCH] Replace Marshal.SizeOf with Unsafe.SizeOf for component registration (#112) * Replace Marshal.SizeOf with Unsafe.SizeOf for component registration * Merge codepaths * Fix doc comments --- src/Arch/Core/Utils/CompileTimeStatics.cs | 117 +++++++++++++++------- 1 file changed, 82 insertions(+), 35 deletions(-) diff --git a/src/Arch/Core/Utils/CompileTimeStatics.cs b/src/Arch/Core/Utils/CompileTimeStatics.cs index b33d1e27..455dd940 100644 --- a/src/Arch/Core/Utils/CompileTimeStatics.cs +++ b/src/Arch/Core/Utils/CompileTimeStatics.cs @@ -109,9 +109,10 @@ public static ComponentType[] TypesArray /// You should only be using this when you exactly know what you are doing. /// /// Its . + /// The size in bytes of . /// Its . [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ComponentType Add(ComponentType type) + private static ComponentType Add(Type type, int typeSize) { if (TryGet(type, out var meta)) { @@ -119,13 +120,25 @@ public static ComponentType Add(ComponentType type) } // Register and assign component id - meta = type; + meta = new ComponentType(Size + 1, type, typeSize, type.GetFields().Length == 0); _types.Add(type, meta); Size++; return meta; } + /// + /// Adds a new manually and registers it. + /// You should only be using this when you exactly know what you are doing. + /// + /// Its . + /// Its . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ComponentType Add(ComponentType type) + { + return Add(type.Type, type.ByteSize); + } + /// /// Adds a new component and registers it. /// @@ -134,7 +147,7 @@ public static ComponentType Add(ComponentType type) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ComponentType Add() { - return Add(typeof(T)); + return Add(typeof(T), SizeOf()); } /// @@ -145,18 +158,7 @@ public static ComponentType Add() [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ComponentType Add(Type type) { - if (TryGet(type, out var meta)) - { - return meta; - } - - // Register and assign component id - var size = type.IsValueType ? Marshal.SizeOf(type) : IntPtr.Size; - meta = new ComponentType(Size + 1, type, size, type.GetFields().Length == 0); - _types.Add(type, meta); - - Size++; - return meta; + return Add(type, SizeOf(type)); } // NOTE: Should this be `Contains` to follow other existing .NET APIs (ICollection.Contains(T))? @@ -164,7 +166,7 @@ public static ComponentType Add(Type type) /// Checks if a component is registered. /// /// Its generic type. - /// True if it is, otherwhise false. + /// True if it is, otherwise false. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Has() { @@ -176,7 +178,7 @@ public static bool Has() /// Checks if a component is registered. /// /// Its . - /// True if it is, otherwhise false. + /// True if it is, otherwise false. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Has(Type type) { @@ -187,7 +189,7 @@ public static bool Has(Type type) /// Removes a registered component by its from the . /// /// The component to remove. - /// True if it was sucessfull, false if not. + /// True if it was successful, false if not. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Remove() { @@ -198,7 +200,7 @@ public static bool Remove() /// Removes a registered component by its from the . /// /// The component to remove. - /// True if it was sucessfull, false if not. + /// True if it was successful, false if not. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Remove(Type type) { @@ -206,18 +208,15 @@ public static bool Remove(Type type) } /// - /// Replaces a registered component by its with another one. - /// The new will receive the id from the old one. - /// Use with caution, might cause undefined behaviour if you do not know what exactly you are doing. + /// Removes a registered component by its from the . /// - /// The old component to be replaced. - /// The new component that replaced the old one. + /// The component to remove. + /// The removed , if it existed. + /// True if it was successful, false if not. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Replace() + public static bool Remove(Type type, out ComponentType compType) { - var oldType = typeof(T0); - var newType = typeof(T1); - Replace(oldType, newType); + return _types.Remove(type, out compType); } /// @@ -227,22 +226,47 @@ public static bool Remove(Type type) /// /// The old component to be replaced. /// The new component that replaced the old one. + /// The size in bytes of . [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Replace(Type oldType, Type newType) + public static void Replace(Type oldType, Type newType, int newTypeSize) { var id = 0; - if (TryGet(oldType, out var oldComponentType)) + if (Remove(oldType, out var oldComponentType)) { id = oldComponentType.Id; - _types.Remove(oldType); } else { id = ++Size; } - var size = newType.IsValueType ? Marshal.SizeOf(newType) : IntPtr.Size; - _types.Add(newType, new ComponentType(id, newType, size, newType.GetFields().Length == 0)); + _types.Add(newType, new ComponentType(id, newType, newTypeSize, newType.GetFields().Length == 0)); + } + + /// + /// Replaces a registered component by its with another one. + /// The new will receive the id from the old one. + /// Use with caution, might cause undefined behaviour if you do not know what exactly you are doing. + /// + /// The old component to be replaced. + /// The new component that replaced the old one. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Replace() + { + Replace(typeof(T0), typeof(T1), SizeOf()); + } + + /// + /// Replaces a registered component by its with another one. + /// The new will receive the id from the old one. + /// Use with caution, might cause undefined behaviour if you do not know what exactly you are doing. + /// + /// The old component to be replaced. + /// The new component that replaced the old one. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Replace(Type oldType, Type newType) + { + Replace(oldType, newType, SizeOf(newType)); } /// @@ -250,7 +274,7 @@ public static void Replace(Type oldType, Type newType) /// /// Its generic type. /// Its , if it is registered. - /// True if it registered, otherwhise false. + /// True if it registered, otherwise false. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryGet(out ComponentType componentType) { @@ -262,12 +286,35 @@ public static bool TryGet(out ComponentType componentType) /// /// Its . /// Its , if it is registered. - /// True if it registered, otherwhise false. + /// True if it registered, otherwise false. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryGet(Type type, out ComponentType componentType) { return _types.TryGetValue(type, out componentType); } + + private static int SizeOf() + { + if (typeof(T).IsValueType) + { + return Unsafe.SizeOf(); + } + + return IntPtr.Size; + } + + private static int SizeOf(Type type) + { + if (type.IsValueType) + { + return (int) typeof(Unsafe) + .GetMethod(nameof(Unsafe.SizeOf))! + .MakeGenericMethod(type) + .Invoke(null, null)!; + } + + return IntPtr.Size; + } } ///