Improve vector cache performance.

This commit is contained in:
2022-11-20 16:02:39 +08:00
parent e38fed89e9
commit ce30b5427b

View File

@@ -65,8 +65,14 @@ namespace Cryville.Crtr.Event {
readonly RMVPool RMVPool = new RMVPool(); readonly RMVPool RMVPool = new RMVPool();
protected Dictionary<StampedEvent, RealtimeMotionValue> PlayingMotions = new Dictionary<StampedEvent, RealtimeMotionValue>(); protected Dictionary<StampedEvent, RealtimeMotionValue> PlayingMotions = new Dictionary<StampedEvent, RealtimeMotionValue>();
protected Dictionary<Identifier, RealtimeMotionValue> Values; protected Dictionary<Identifier, RealtimeMotionValue> Values;
protected Dictionary<Identifier, Vector> CachedValues; protected Dictionary<Identifier, CacheEntry> CachedValues;
protected Dictionary<Identifier, bool> CachedValueStates; protected class CacheEntry {
public bool Valid { get; set; }
public Vector Value { get; set; }
public CacheEntry Clone() {
return new CacheEntry { Valid = Valid, Value = Value == null ? null : Value.Clone() };
}
}
/// <summary> /// <summary>
/// Gets a motion value. /// Gets a motion value.
@@ -88,7 +94,10 @@ namespace Cryville.Crtr.Event {
} }
void InvalidateMotion(Identifier name) { void InvalidateMotion(Identifier name) {
CachedValueStates[name] = false; CacheEntry cache;
if (!CachedValues.TryGetValue(name, out cache))
CachedValues.Add(name, cache = new CacheEntry());
cache.Valid = false;
foreach (var c in Children) foreach (var c in Children)
c.Value.InvalidateMotion(name); c.Value.InvalidateMotion(name);
} }
@@ -102,8 +111,7 @@ namespace Cryville.Crtr.Event {
} }
Values = new Dictionary<Identifier, RealtimeMotionValue>(ChartPlayer.motionRegistry.Count); Values = new Dictionary<Identifier, RealtimeMotionValue>(ChartPlayer.motionRegistry.Count);
CachedValues = new Dictionary<Identifier, Vector>(ChartPlayer.motionRegistry.Count); CachedValues = new Dictionary<Identifier, CacheEntry>(ChartPlayer.motionRegistry.Count);
CachedValueStates = new Dictionary<Identifier, bool>(ChartPlayer.motionRegistry.Count);
foreach (var m in ChartPlayer.motionRegistry) foreach (var m in ChartPlayer.motionRegistry)
Values.Add(m.Key, new RealtimeMotionValue().Init(Parent == null ? m.Value.GlobalInitValue : m.Value.InitValue)); Values.Add(m.Key, new RealtimeMotionValue().Init(Parent == null ? m.Value.GlobalInitValue : m.Value.InitValue));
} }
@@ -124,18 +132,12 @@ namespace Cryville.Crtr.Event {
} }
r.Values = mvs; r.Values = mvs;
var cvs = new Dictionary<Identifier, Vector>(ChartPlayer.motionRegistry.Count); var cvs = new Dictionary<Identifier, CacheEntry>(ChartPlayer.motionRegistry.Count);
foreach (var cv in CachedValues) { foreach (var cv in CachedValues) {
cvs.Add(cv.Key, cv.Value.Clone()); cvs.Add(cv.Key, cv.Value.Clone());
} }
r.CachedValues = cvs; r.CachedValues = cvs;
var cvss = new Dictionary<Identifier, bool>(ChartPlayer.motionRegistry.Count);
foreach (var cv in CachedValueStates) {
cvss.Add(cv.Key, cv.Value);
}
r.CachedValueStates = cvss;
r.Children = new Dictionary<EventContainer, ContainerState>(); r.Children = new Dictionary<EventContainer, ContainerState>();
foreach (var child in Children) { foreach (var child in Children) {
var cc = child.Value.Clone(ct); var cc = child.Value.Clone(ct);
@@ -170,11 +172,13 @@ namespace Cryville.Crtr.Event {
} }
foreach (var cv in CachedValues) { foreach (var cv in CachedValues) {
Vector dv; CacheEntry dv;
if(dest.CachedValues.TryGetValue(cv.Key, out dv)) cv.Value.CopyTo(dv); if (dest.CachedValues.TryGetValue(cv.Key, out dv)) {
dv.Valid = cv.Value.Valid;
if (cv.Value.Value != null) cv.Value.Value.CopyTo(dv.Value);
}
else dest.CachedValues.Add(cv.Key, cv.Value.Clone()); else dest.CachedValues.Add(cv.Key, cv.Value.Clone());
} }
foreach (var cvs in CachedValueStates) dest.CachedValueStates[cvs.Key] = cvs.Value;
if (ct != 1) foreach (var cev in WorkingChildren) if (ct != 1) foreach (var cev in WorkingChildren)
Children[cev].CopyTo(ct, dest.Children[cev]); Children[cev].CopyTo(ct, dest.Children[cev]);
@@ -212,22 +216,21 @@ namespace Cryville.Crtr.Event {
} }
public Vector GetRawValue(Identifier key) { public Vector GetRawValue(Identifier key) {
Vector tr; CacheEntry tr;
if (!CachedValues.TryGetValue(key, out tr)) { if (!CachedValues.TryGetValue(key, out tr))
tr = (Vector)ReflectionHelper.InvokeEmptyConstructor(ChartPlayer.motionRegistry[key].Type); CachedValues.Add(key, tr = new CacheEntry { Valid = false });
CachedValues.Add(key, tr); if (tr.Value == null)
CachedValueStates[key] = false; tr.Value = (Vector)ReflectionHelper.InvokeEmptyConstructor(ChartPlayer.motionRegistry[key].Type);
} Vector r = tr.Value;
Vector r = tr;
#if !DISABLE_CACHE #if !DISABLE_CACHE
if (CachedValueStates[key]) return r; if (tr.Valid) return r;
#endif #endif
float reltime = 0; float reltime = 0;
if (rootPrototype != null) reltime = Time - rootPrototype.Time; if (rootPrototype != null) reltime = Time - rootPrototype.Time;
GetMotionValue(key).GetValue(reltime, ref r); GetMotionValue(key).GetValue(reltime, ref r);
if (Parent != null) r.ApplyFrom(Parent.GetRawValue(key)); if (Parent != null) r.ApplyFrom(Parent.GetRawValue(key));
#if !DISABLE_CACHE #if !DISABLE_CACHE
CachedValueStates[key] = true; tr.Valid = true;
#endif #endif
return r; return r;
} }