ResourceDataReader pool improvement

This commit is contained in:
dexy 2020-03-10 13:46:18 +11:00
parent e608912977
commit 9d41d329c4
3 changed files with 37 additions and 36 deletions

View File

@ -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

View File

@ -636,7 +636,7 @@ namespace CodeWalker.GameFiles
[TypeConverter(typeof(ExpandableObjectConverter))] public class ResourceSimpleArray<T> : ListBase<T> where T : IResourceSystemBlock, new()
[TypeConverter(typeof(ExpandableObjectConverter))] public class ResourceSimpleArray<T> : ListBase<T>, IResourceNoCacheBlock where T : IResourceSystemBlock, new()
{
/// <summary>
/// Gets the length of the data block.
@ -722,7 +722,7 @@ namespace CodeWalker.GameFiles
}
}
[TypeConverter(typeof(ExpandableObjectConverter))] public class ResourceSimpleList64<T> : ResourceSystemBlock where T : IResourceSystemBlock, new()
[TypeConverter(typeof(ExpandableObjectConverter))] public class ResourceSimpleList64<T> : 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<T> : ResourceSystemBlock where T : struct
[TypeConverter(typeof(ExpandableObjectConverter))] public class ResourceSimpleList64_s<T> : 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<T> : ResourceSystemBlock where T : struct
[TypeConverter(typeof(ExpandableObjectConverter))] public class ResourceSimpleList64b_s<T> : 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
{

View File

@ -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<long, List<IResourceBlock>> blockPool;
public Dictionary<long, IResourceBlock> blockPool = new Dictionary<long, IResourceBlock>();
/// <summary>
/// Gets the length of the underlying stream.
@ -80,7 +80,6 @@ namespace CodeWalker.GameFiles
{
this.systemStream = systemStream;
this.graphicsStream = graphicsStream;
this.blockPool = new Dictionary<long, List<IResourceBlock>>();
}
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<long, List<IResourceBlock>>();
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<long, List<IResourceBlock>>();
Position = 0x50000000;
}
@ -171,20 +168,24 @@ namespace CodeWalker.GameFiles
/// </summary>
public T ReadBlock<T>(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<IResourceBlock>();
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;
}
/// <summary>
@ -595,6 +591,11 @@ namespace CodeWalker.GameFiles
{ }
/// <summary>
/// Represents a data block that won't get cached while loading. Used for 0-length object parts
/// </summary>
public interface IResourceNoCacheBlock : IResourceBlock
{ }