From 393fe25e79cfeb68fff8ea06bc9d1a5c58557669 Mon Sep 17 00:00:00 2001 From: pohky Date: Wed, 20 Jan 2021 00:57:34 +0100 Subject: [PATCH] Update SafeMemory.cs make this a bit faster --- Dalamud/SafeMemory.cs | 56 ++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/Dalamud/SafeMemory.cs b/Dalamud/SafeMemory.cs index e38c2d333..01b270201 100644 --- a/Dalamud/SafeMemory.cs +++ b/Dalamud/SafeMemory.cs @@ -55,7 +55,7 @@ namespace Dalamud /// The resulting object. /// Whether or not the read succeeded. public static bool Read(IntPtr address, out T result) where T : struct { - if (!ReadBytes(address, SizeOf(), out var buffer)) { + if (!ReadBytes(address, SizeCache.Size, out var buffer)) { result = default; return false; } @@ -78,19 +78,14 @@ namespace Dalamud public static T[] Read(IntPtr address, int count) where T : struct { var size = SizeOf(); + if (!ReadBytes(address, count * size, out var buffer)) + return null; var result = new T[count]; - - var readSucceeded = true; - for (var i = 0; i < count; i++) { - var success = Read(address + i * size, out var res); - - if (!success) - readSucceeded = false; - - result[i] = res; - } - - return !readSucceeded ? null : result; + using var mem = new LocalMemory(buffer.Length); + mem.Write(buffer); + for (var i = 0; i < result.Length; i++) + result[i] = mem.Read(i * size); + return result; } /// @@ -102,7 +97,7 @@ namespace Dalamud /// Whether or not the write succeeded. public static bool Write(IntPtr address, T obj) where T : struct { - using var mem = new LocalMemory(SizeOf()); + using var mem = new LocalMemory(SizeCache.Size); mem.Write(obj); return WriteBytes(address, mem.Read()); } @@ -118,11 +113,11 @@ namespace Dalamud { if (objArray == null || objArray.Length == 0) return true; - var size = SizeOf(); + var size = SizeCache.Size; + using var mem = new LocalMemory(objArray.Length * size); for (var i = 0; i < objArray.Length; i++) - if (!Write(address + i * size, objArray[i])) - return false; - return true; + mem.Write(objArray[i], i * size); + return WriteBytes(address, mem.Read()); } /// @@ -204,12 +199,23 @@ namespace Dalamud /// /// The type to inspect. /// The size of the passed type. - public static int SizeOf() + public static int SizeOf() where T: struct { - var type = typeof(T); - if (type.IsEnum) - type = type.GetEnumUnderlyingType(); - return Type.GetTypeCode(type) == TypeCode.Boolean ? 1 : Marshal.SizeOf(type); + return SizeCache.Size; + } + + private static class SizeCache + { + // ReSharper disable once StaticMemberInGenericType + public static readonly int Size; + + static SizeCache() + { + var type = typeof(T); + if (type.IsEnum) + type = type.GetEnumUnderlyingType(); + Size = Type.GetTypeCode(type) == TypeCode.Boolean ? 1 : Marshal.SizeOf(type); + } } private static class Imports @@ -242,9 +248,9 @@ namespace Dalamud return bytes; } - public T Read() => (T)Marshal.PtrToStructure(this.hGlobal, typeof(T)); + public T Read(int offset = 0) => (T)Marshal.PtrToStructure(this.hGlobal + offset, typeof(T)); public void Write(byte[] data, int index = 0) => Marshal.Copy(data, index, this.hGlobal, this.size); - public void Write(T data) => Marshal.StructureToPtr(data, this.hGlobal, false); + public void Write(T data, int offset = 0) => Marshal.StructureToPtr(data, this.hGlobal + offset, false); ~LocalMemory() => Dispose(); public void Dispose()