From 9d41d329c4ca1421210f23408876ca555546866b Mon Sep 17 00:00:00 2001 From: dexy Date: Tue, 10 Mar 2020 13:46:18 +1100 Subject: [PATCH] ResourceDataReader pool improvement --- .../GameFiles/Resources/Drawable.cs | 2 +- .../GameFiles/Resources/ResourceBaseTypes.cs | 18 +++---- .../GameFiles/Resources/ResourceData.cs | 53 ++++++++++--------- 3 files changed, 37 insertions(+), 36 deletions(-) diff --git a/CodeWalker.Core/GameFiles/Resources/Drawable.cs b/CodeWalker.Core/GameFiles/Resources/Drawable.cs index d13705e..737a153 100644 --- a/CodeWalker.Core/GameFiles/Resources/Drawable.cs +++ b/CodeWalker.Core/GameFiles/Resources/Drawable.cs @@ -454,7 +454,7 @@ namespace CodeWalker.GameFiles } } - [TypeConverter(typeof(ExpandableObjectConverter))] public class ShaderParametersBlock : ResourceSystemBlock + [TypeConverter(typeof(ExpandableObjectConverter))] public class ShaderParametersBlock : ResourceSystemBlock, IResourceNoCacheBlock { public override long BlockLength diff --git a/CodeWalker.Core/GameFiles/Resources/ResourceBaseTypes.cs b/CodeWalker.Core/GameFiles/Resources/ResourceBaseTypes.cs index c0af97e..acd8370 100644 --- a/CodeWalker.Core/GameFiles/Resources/ResourceBaseTypes.cs +++ b/CodeWalker.Core/GameFiles/Resources/ResourceBaseTypes.cs @@ -636,7 +636,7 @@ namespace CodeWalker.GameFiles - [TypeConverter(typeof(ExpandableObjectConverter))] public class ResourceSimpleArray : ListBase where T : IResourceSystemBlock, new() + [TypeConverter(typeof(ExpandableObjectConverter))] public class ResourceSimpleArray : ListBase, IResourceNoCacheBlock where T : IResourceSystemBlock, new() { /// /// Gets the length of the data block. @@ -722,7 +722,7 @@ namespace CodeWalker.GameFiles } } - [TypeConverter(typeof(ExpandableObjectConverter))] public class ResourceSimpleList64 : ResourceSystemBlock where T : IResourceSystemBlock, new() + [TypeConverter(typeof(ExpandableObjectConverter))] public class ResourceSimpleList64 : ResourceSystemBlock, IResourceNoCacheBlock where T : IResourceSystemBlock, new() { public override long BlockLength { @@ -814,7 +814,7 @@ namespace CodeWalker.GameFiles return "(Count: " + EntriesCount.ToString() + ")"; } } - [TypeConverter(typeof(ExpandableObjectConverter))] public class ResourceSimpleList64_s : ResourceSystemBlock where T : struct + [TypeConverter(typeof(ExpandableObjectConverter))] public class ResourceSimpleList64_s : ResourceSystemBlock, IResourceNoCacheBlock where T : struct { public override long BlockLength { @@ -892,7 +892,7 @@ namespace CodeWalker.GameFiles return "(Count: " + EntriesCount.ToString() + ")"; } } - [TypeConverter(typeof(ExpandableObjectConverter))] public class ResourceSimpleList64b_s : ResourceSystemBlock where T : struct + [TypeConverter(typeof(ExpandableObjectConverter))] public class ResourceSimpleList64b_s : ResourceSystemBlock, IResourceNoCacheBlock where T : struct { //this version uses uints for the count/cap! @@ -972,7 +972,7 @@ namespace CodeWalker.GameFiles return "(Count: " + EntriesCount.ToString() + ")"; } } - [TypeConverter(typeof(ExpandableObjectConverter))] public class ResourceSimpleList64_byte : ResourceSystemBlock + [TypeConverter(typeof(ExpandableObjectConverter))] public class ResourceSimpleList64_byte : ResourceSystemBlock, IResourceNoCacheBlock { public override long BlockLength { @@ -1050,7 +1050,7 @@ namespace CodeWalker.GameFiles return "(Count: " + EntriesCount.ToString() + ")"; } } - [TypeConverter(typeof(ExpandableObjectConverter))] public class ResourceSimpleList64_ushort : ResourceSystemBlock + [TypeConverter(typeof(ExpandableObjectConverter))] public class ResourceSimpleList64_ushort : ResourceSystemBlock, IResourceNoCacheBlock { public override long BlockLength { @@ -1128,7 +1128,7 @@ namespace CodeWalker.GameFiles return "(Count: " + EntriesCount.ToString() + ")"; } } - [TypeConverter(typeof(ExpandableObjectConverter))] public class ResourceSimpleList64_uint : ResourceSystemBlock + [TypeConverter(typeof(ExpandableObjectConverter))] public class ResourceSimpleList64_uint : ResourceSystemBlock, IResourceNoCacheBlock { public override long BlockLength { @@ -1206,7 +1206,7 @@ namespace CodeWalker.GameFiles return "(Count: " + EntriesCount.ToString() + ")"; } } - [TypeConverter(typeof(ExpandableObjectConverter))] public class ResourceSimpleList64_ulong : ResourceSystemBlock + [TypeConverter(typeof(ExpandableObjectConverter))] public class ResourceSimpleList64_ulong : ResourceSystemBlock, IResourceNoCacheBlock { public override long BlockLength { @@ -1284,7 +1284,7 @@ namespace CodeWalker.GameFiles return "(Count: " + EntriesCount.ToString() + ")"; } } - [TypeConverter(typeof(ExpandableObjectConverter))] public class ResourceSimpleList64_float : ResourceSystemBlock + [TypeConverter(typeof(ExpandableObjectConverter))] public class ResourceSimpleList64_float : ResourceSystemBlock, IResourceNoCacheBlock { public override long BlockLength { diff --git a/CodeWalker.Core/GameFiles/Resources/ResourceData.cs b/CodeWalker.Core/GameFiles/Resources/ResourceData.cs index f78a947..e4a6a21 100644 --- a/CodeWalker.Core/GameFiles/Resources/ResourceData.cs +++ b/CodeWalker.Core/GameFiles/Resources/ResourceData.cs @@ -50,7 +50,7 @@ namespace CodeWalker.GameFiles // this is a dictionary that contains all the resource blocks // which were read from this resource reader - private Dictionary> blockPool; + public Dictionary blockPool = new Dictionary(); /// /// Gets the length of the underlying stream. @@ -80,7 +80,6 @@ namespace CodeWalker.GameFiles { this.systemStream = systemStream; this.graphicsStream = graphicsStream; - this.blockPool = new Dictionary>(); } public ResourceDataReader(RpfResourceFileEntry resentry, byte[] data, Endianess endianess = Endianess.LittleEndian) @@ -105,16 +104,14 @@ namespace CodeWalker.GameFiles this.systemStream = new MemoryStream(data, 0, systemSize); this.graphicsStream = new MemoryStream(data, systemSize, graphicsSize); - this.blockPool = new Dictionary>(); Position = 0x50000000; } public ResourceDataReader(int systemSize, int graphicsSize, byte[] data, Endianess endianess = Endianess.LittleEndian) - : base((Stream)null, endianess) + : base((Stream)null, endianess) { this.systemStream = new MemoryStream(data, 0, systemSize); this.graphicsStream = new MemoryStream(data, systemSize, graphicsSize); - this.blockPool = new Dictionary>(); Position = 0x50000000; } @@ -171,20 +168,24 @@ namespace CodeWalker.GameFiles /// public T ReadBlock(params object[] parameters) where T : IResourceBlock, new() { - // make sure to return the same object if the same - // block is read again... - if (blockPool.ContainsKey(Position)) + var usepool = !typeof(IResourceNoCacheBlock).IsAssignableFrom(typeof(T)); + if (usepool) { - var blocks = blockPool[Position]; - foreach (var block in blocks) - if (block is T) + // make sure to return the same object if the same + // block is read again... + if (blockPool.ContainsKey(Position)) + { + var block = blockPool[Position]; + if (block is T tblk) { Position += block.BlockLength; - - // since a resource block of the same type - // has been found at the same address, return it - return (T)block; + return tblk; } + else + { + usepool = false; + } + } } var result = new T(); @@ -192,30 +193,25 @@ namespace CodeWalker.GameFiles // replace with correct type... if (result is IResourceXXSystemBlock) + { result = (T)((IResourceXXSystemBlock)result).GetType(this, parameters); + } if (result == null) { return default(T); } - - // add block to the block pool... - if (blockPool.ContainsKey(Position)) + if (usepool) { - blockPool[Position].Add(result); - } - else - { - var blocks = new List(); - blocks.Add(result); - blockPool.Add(Position, blocks); + blockPool[Position] = result; } var classPosition = Position; result.Read(this, parameters); //result.Position = classPosition; //TODO: need this if writing stuff! - return (T)result; + + return result; } /// @@ -595,6 +591,11 @@ namespace CodeWalker.GameFiles { } + /// + /// Represents a data block that won't get cached while loading. Used for 0-length object parts + /// + public interface IResourceNoCacheBlock : IResourceBlock + { }