using Cryville.Common; using Cryville.Common.Buffers; using System.Collections.Generic; namespace Cryville.Crtr.Event { internal class MotionCache { public bool Valid { get; set; } public Vector Value { get; set; } public void CopyTo(MotionCache dest) { dest.Valid = Valid; Value.CopyTo(dest.Value); } } internal class MotionCachePool { private class Bucket : ObjectPool { readonly MotionRegistry _reg; public Bucket(string name, int capacity) : base(capacity) { _reg = ChartPlayer.motionRegistry[name]; } protected override MotionCache Construct() { var result = new MotionCache(); result.Value = (Vector)ReflectionHelper.InvokeEmptyConstructor(_reg.Type); return result; } } static Dictionary _buckets; public static void Prepare() { _buckets = new Dictionary(ChartPlayer.motionRegistry.Count); foreach (var reg in ChartPlayer.motionRegistry) _buckets.Add(reg.Key, new Bucket(reg.Key, 4096)); } static readonly SimpleObjectPool> _dictPool = new SimpleObjectPool>(1024); Dictionary _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; } } }