Pull up CategorizedPool. Add Reset method for ObjectPool.

This commit is contained in:
2023-02-11 23:08:43 +08:00
parent b364005741
commit 9fd685b8b3
7 changed files with 90 additions and 69 deletions

View File

@@ -0,0 +1,46 @@
using System.Collections.Generic;
namespace Cryville.Common.Buffers {
public abstract class CategorizedPool<TCategory, TObject> where TObject : class {
protected readonly Dictionary<TCategory, ObjectPool<TObject>> Buckets
= new Dictionary<TCategory, ObjectPool<TObject>>();
public int RentedCount { get; private set; }
public TObject Rent(TCategory name) {
var obj = Buckets[name].Rent();
RentedCount++;
return obj;
}
public void Return(TCategory name, TObject obj) {
Buckets[name].Return(obj);
--RentedCount;
}
}
public class CategorizedPoolAccessor<TCategory, TObject> where TObject : class {
readonly CategorizedPool<TCategory, TObject> _pool;
static readonly SimpleObjectPool<Dictionary<TObject, TCategory>> _dictPool
= new SimpleObjectPool<Dictionary<TObject, TCategory>>(1024);
Dictionary<TObject, TCategory> _rented;
public CategorizedPoolAccessor(CategorizedPool<TCategory, TObject> pool) {
_pool = pool;
}
public TObject Rent(TCategory name) {
var obj = _pool.Rent(name);
if (_rented == null) _rented = _dictPool.Rent();
_rented.Add(obj, name);
return obj;
}
public void Return(TObject obj) {
_pool.Return(_rented[obj], obj);
_rented.Remove(obj);
}
public void ReturnAll() {
if (_rented == null) return;
foreach (var obj in _rented) {
_pool.Return(obj.Value, obj.Key);
}
_rented.Clear();
_dictPool.Return(_rented);
_rented = null;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ec18f22479042d747b88c093aa90c5c0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -24,6 +24,7 @@
_objs[_index++] = null;
}
if (obj == null) obj = Construct();
else Reset(obj);
return obj;
}
/// <summary>
@@ -38,5 +39,10 @@
/// </summary>
/// <returns>The new instance.</returns>
protected abstract T Construct();
/// <summary>
/// Resets an object.
/// </summary>
/// <param name="obj">The object.</param>
protected virtual void Reset(T obj) { }
}
}

View File

@@ -517,8 +517,6 @@ namespace Cryville.Crtr {
try {
workerTimer = new diag::Stopwatch();
workerTimer.Start();
RMVPool.Prepare();
MotionCachePool.Prepare();
LoadChart(info);
workerTimer.Stop();
Logger.Log("main", 1, "Load/WorkerThread", "Worker thread done ({0}ms)", workerTimer.Elapsed.TotalMilliseconds);
@@ -607,6 +605,8 @@ namespace Cryville.Crtr {
pruleset = ruleset.Root;
pruleset.Optimize(etor);
}
ContainerState.RMVPool = new RMVPool();
ContainerState.MCPool = new MotionCachePool();
}
void LoadSkin(FileInfo file) {

View File

@@ -1,6 +1,7 @@
//#define DISABLE_CACHE
using Cryville.Common;
using Cryville.Common.Buffers;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
@@ -90,6 +91,9 @@ namespace Cryville.Crtr.Event {
Parent = parent;
}
_rmvpa = new CategorizedPoolAccessor<Identifier, RealtimeMotionValue>(RMVPool);
_mcpa = new CategorizedPoolAccessor<Identifier, MotionCache>(MCPool);
Values = new Dictionary<Identifier, RealtimeMotionValue>(ChartPlayer.motionRegistry.Count);
CachedValues = new Dictionary<Identifier, MotionCache>(ChartPlayer.motionRegistry.Count);
foreach (var m in ChartPlayer.motionRegistry)
@@ -159,7 +163,7 @@ namespace Cryville.Crtr.Event {
foreach (var cv in CachedValues) {
MotionCache dv;
if (!dest.CachedValues.TryGetValue(cv.Key, out dv)) {
dest.CachedValues.Add(cv.Key, dv = dest.MCPool.Rent(cv.Key));
dest.CachedValues.Add(cv.Key, dv = dest._mcpa.Rent(cv.Key));
}
cv.Value.CopyTo(dv);
}
@@ -187,8 +191,8 @@ namespace Cryville.Crtr.Event {
Disposed = true;
if (CloneType == 1) Handler.Dispose();
if (CloneType == 1 || CloneType == 17) {
RMVPool.ReturnAll();
MCPool.ReturnAll();
_rmvpa.ReturnAll();
_mcpa.ReturnAll();
}
foreach (var s in Children)
s.Value.Dispose();
@@ -212,8 +216,10 @@ namespace Cryville.Crtr.Event {
#endregion
#region Motion
readonly RMVPool RMVPool = new RMVPool();
readonly MotionCachePool MCPool = new MotionCachePool();
internal static RMVPool RMVPool;
internal static MotionCachePool MCPool;
readonly CategorizedPoolAccessor<Identifier, RealtimeMotionValue> _rmvpa;
readonly CategorizedPoolAccessor<Identifier, MotionCache> _mcpa;
Dictionary<StampedEvent, RealtimeMotionValue> PlayingMotions = new Dictionary<StampedEvent, RealtimeMotionValue>(4);
Dictionary<Identifier, RealtimeMotionValue> Values;
Dictionary<Identifier, MotionCache> CachedValues;
@@ -233,7 +239,7 @@ namespace Cryville.Crtr.Event {
void InvalidateMotion(Identifier name) {
MotionCache cache;
if (!CachedValues.TryGetValue(name, out cache))
CachedValues.Add(name, cache = MCPool.Rent(name));
CachedValues.Add(name, cache = _mcpa.Rent(name));
cache.Valid = false;
foreach (var c in ActiveChildren)
Children[c].InvalidateMotion(name);
@@ -242,7 +248,7 @@ namespace Cryville.Crtr.Event {
public Vector GetRawValue(Identifier key) {
MotionCache tr;
if (!CachedValues.TryGetValue(key, out tr))
CachedValues.Add(key, tr = MCPool.Rent(key));
CachedValues.Add(key, tr = _mcpa.Rent(key));
Vector r = tr.Value;
#if !DISABLE_CACHE
if (tr.Valid) return r;
@@ -351,14 +357,14 @@ namespace Cryville.Crtr.Event {
if (ev != null) {
if (ev.Unstamped is Chart.Motion) {
var tev = (Chart.Motion)ev.Unstamped;
var mv = RMVPool.Rent(tev.Name);
var mv = _rmvpa.Rent(tev.Name);
mv.CloneTypeFlag = CloneType;
GetMotionValue(tev.Name).CopyTo(mv);
PlayingMotions.Add(ev, mv);
Update(ev);
if (!ev.Unstamped.IsLong) {
PlayingMotions.Remove(ev);
RMVPool.Return(mv);
_rmvpa.Return(mv);
}
}
else if (ev.Unstamped is EventContainer) {
@@ -376,7 +382,7 @@ namespace Cryville.Crtr.Event {
if (nev is Chart.Motion) {
Update(ev);
var mv = PlayingMotions[ev.Origin];
if (mv.CloneTypeFlag == CloneType) RMVPool.Return(mv);
if (mv.CloneTypeFlag == CloneType) _rmvpa.Return(mv);
PlayingMotions.Remove(ev.Origin);
}
else if (nev is EventContainer) {

View File

@@ -1,6 +1,5 @@
using Cryville.Common;
using Cryville.Common.Buffers;
using System.Collections.Generic;
namespace Cryville.Crtr.Event {
internal class MotionCache {
@@ -11,7 +10,7 @@ namespace Cryville.Crtr.Event {
Value.CopyTo(dest.Value);
}
}
internal class MotionCachePool {
internal class MotionCachePool : CategorizedPool<Identifier, MotionCache> {
private class Bucket : ObjectPool<MotionCache> {
readonly MotionRegistry _reg;
public Bucket(string name, int capacity) : base(capacity) {
@@ -22,35 +21,13 @@ namespace Cryville.Crtr.Event {
result.Value = (Vector)ReflectionHelper.InvokeEmptyConstructor(_reg.Type);
return result;
}
protected override void Reset(MotionCache obj) {
obj.Valid = false;
}
}
static Dictionary<Identifier, Bucket> _buckets;
public static void Prepare() {
_buckets = new Dictionary<Identifier, Bucket>(ChartPlayer.motionRegistry.Count);
public MotionCachePool() {
foreach (var reg in ChartPlayer.motionRegistry)
_buckets.Add(reg.Key, new Bucket(reg.Key, 4096));
}
static readonly SimpleObjectPool<Dictionary<MotionCache, Identifier>> _dictPool
= new SimpleObjectPool<Dictionary<MotionCache, Identifier>>(1024);
Dictionary<MotionCache, Identifier> _rented;
public MotionCache Rent(Identifier name) {
var obj = _buckets[name].Rent();
obj.Valid = false;
if (_rented == null) _rented = _dictPool.Rent();
_rented.Add(obj, name);
return obj;
}
public void Return(MotionCache obj) {
_buckets[_rented[obj]].Return(obj);
_rented.Remove(obj);
}
public void ReturnAll() {
if (_rented == null) return;
foreach (var obj in _rented)
_buckets[obj.Value].Return(obj.Key);
_rented.Clear();
_dictPool.Return(_rented);
_rented = null;
Buckets.Add(reg.Key, new Bucket(reg.Key, 4096));
}
}
}

View File

@@ -1,9 +1,8 @@
using Cryville.Common;
using Cryville.Common.Buffers;
using System.Collections.Generic;
namespace Cryville.Crtr.Event {
internal class RMVPool {
internal class RMVPool : CategorizedPool<Identifier, RealtimeMotionValue> {
private class Bucket : ObjectPool<RealtimeMotionValue> {
readonly MotionRegistry _reg;
public Bucket(string name, int capacity) : base(capacity) {
@@ -13,33 +12,9 @@ namespace Cryville.Crtr.Event {
return new RealtimeMotionValue().Init(_reg.InitValue);
}
}
static Dictionary<Identifier, Bucket> _buckets;
public static void Prepare() {
_buckets = new Dictionary<Identifier, Bucket>(ChartPlayer.motionRegistry.Count);
public RMVPool() {
foreach (var reg in ChartPlayer.motionRegistry)
_buckets.Add(reg.Key, new Bucket(reg.Key, 4096));
}
static readonly SimpleObjectPool<Dictionary<RealtimeMotionValue, Identifier>> _dictPool
= new SimpleObjectPool<Dictionary<RealtimeMotionValue, Identifier>>(1024);
Dictionary<RealtimeMotionValue, Identifier> _rented;
public RealtimeMotionValue Rent(Identifier name) {
var obj = _buckets[name].Rent();
if (_rented == null) _rented = _dictPool.Rent();
_rented.Add(obj, name);
return obj;
}
public void Return(RealtimeMotionValue obj) {
_buckets[_rented[obj]].Return(obj);
_rented.Remove(obj);
}
public void ReturnAll() {
if (_rented == null) return;
foreach (var obj in _rented)
_buckets[obj.Value].Return(obj.Key);
_rented.Clear();
_dictPool.Return(_rented);
_rented = null;
Buckets.Add(reg.Key, new Bucket(reg.Key, 4096));
}
}
}