Introduce IntKeyedDictionary to improve performance.

This commit is contained in:
2023-03-24 17:06:47 +08:00
parent 89f391f040
commit e2c683567e
18 changed files with 1274 additions and 94 deletions

View File

@@ -0,0 +1,106 @@
using System;
using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
using System.Runtime.Serialization;
using System.Threading;
namespace Cryville.Common.Collections {
internal static class HashHelpers {
#if FEATURE_RANDOMIZED_STRING_HASHING
public const int HashCollisionThreshold = 100;
public static bool s_UseRandomizedStringHashing = String.UseRandomizedHashing();
#endif
// Table of prime numbers to use as hash table sizes.
// A typical resize algorithm would pick the smallest prime number in this array
// that is larger than twice the previous capacity.
// Suppose our Hashtable currently has capacity x and enough elements are added
// such that a resize needs to occur. Resizing first computes 2x then finds the
// first prime in the table greater than 2x, i.e. if primes are ordered
// p_1, p_2, ..., p_i, ..., it finds p_n such that p_n-1 < 2x < p_n.
// Doubling is important for preserving the asymptotic complexity of the
// hashtable operations such as add. Having a prime guarantees that double
// hashing does not lead to infinite loops. IE, your hash function will be
// h1(key) + i*h2(key), 0 <= i < size. h2 and the size must be relatively prime.
public static readonly int[] primes = {
3, 7, 11, 17, 23, 29, 37, 47, 59, 71, 89, 107, 131, 163, 197, 239, 293, 353, 431, 521, 631, 761, 919,
1103, 1327, 1597, 1931, 2333, 2801, 3371, 4049, 4861, 5839, 7013, 8419, 10103, 12143, 14591,
17519, 21023, 25229, 30293, 36353, 43627, 52361, 62851, 75431, 90523, 108631, 130363, 156437,
187751, 225307, 270371, 324449, 389357, 467237, 560689, 672827, 807403, 968897, 1162687, 1395263,
1674319, 2009191, 2411033, 2893249, 3471899, 4166287, 4999559, 5999471, 7199369};
// Used by Hashtable and Dictionary's SeralizationInfo .ctor's to store the SeralizationInfo
// object until OnDeserialization is called.
private static ConditionalWeakTable<object, SerializationInfo> s_SerializationInfoTable;
internal static ConditionalWeakTable<object, SerializationInfo> SerializationInfoTable {
get {
if (s_SerializationInfoTable == null) {
ConditionalWeakTable<object, SerializationInfo> newTable = new ConditionalWeakTable<object, SerializationInfo>();
Interlocked.CompareExchange(ref s_SerializationInfoTable, newTable, null);
}
return s_SerializationInfoTable;
}
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static bool IsPrime(int candidate) {
if ((candidate & 1) != 0) {
int limit = (int)System.Math.Sqrt (candidate);
for (int divisor = 3; divisor <= limit; divisor += 2) {
if ((candidate % divisor) == 0)
return false;
}
return true;
}
return (candidate == 2);
}
internal const Int32 HashPrime = 101;
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static int GetPrime(int min) {
if (min < 0)
throw new ArgumentException("Hashtable's capacity overflowed and went negative. Check load factor, capacity and the current size of the table.");
Contract.EndContractBlock();
for (int i = 0; i < primes.Length; i++) {
int prime = primes[i];
if (prime >= min) return prime;
}
//outside of our predefined table.
//compute the hard way.
for (int i = (min | 1); i < Int32.MaxValue; i += 2) {
if (IsPrime(i) && ((i - 1) % HashPrime != 0))
return i;
}
return min;
}
public static int GetMinPrime() {
return primes[0];
}
// Returns size of hashtable to grow to.
public static int ExpandPrime(int oldSize) {
int newSize = 2 * oldSize;
// Allow the hashtables to grow to maximum possible size (~2G elements) before encoutering capacity overflow.
// Note that this check works even when _items.Length overflowed thanks to the (uint) cast
if ((uint)newSize > MaxPrimeArrayLength && MaxPrimeArrayLength > oldSize) {
Contract.Assert(MaxPrimeArrayLength == GetPrime(MaxPrimeArrayLength), "Invalid MaxPrimeArrayLength");
return MaxPrimeArrayLength;
}
return GetPrime(newSize);
}
// This is the maximum prime smaller than Array.MaxArrayLength
public const int MaxPrimeArrayLength = 0x7FEFFFFD;
}
}

View File

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

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f68b44d5226a73441b94e7dd5873529f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -1,4 +1,4 @@
using System.Collections.Generic; using Cryville.Common.Collections.Specialized;
using UnityEngine; using UnityEngine;
namespace Cryville.Crtr { namespace Cryville.Crtr {
@@ -6,11 +6,11 @@ namespace Cryville.Crtr {
public int Name { get; private set; } public int Name { get; private set; }
public Transform Transform { get; private set; } public Transform Transform { get; private set; }
public SkinContext SkinContext { get; private set; } public SkinContext SkinContext { get; private set; }
public Dictionary<int, PropSrc> PropSrcs { get; private set; } public IntKeyedDictionary<PropSrc> PropSrcs { get; private set; }
public Anchor(int name, Transform transform, int propSrcCount = 0) { public Anchor(int name, Transform transform, int propSrcCount = 0) {
Name = name; Name = name;
Transform = transform; Transform = transform;
if (propSrcCount > 0) PropSrcs = new Dictionary<int, PropSrc>(propSrcCount); if (propSrcCount > 0) PropSrcs = new IntKeyedDictionary<PropSrc>(propSrcCount);
SkinContext = new SkinContext(transform, PropSrcs); SkinContext = new SkinContext(transform, PropSrcs);
} }
} }

View File

@@ -1,4 +1,5 @@
using Cryville.Common; using Cryville.Common;
using Cryville.Common.Collections.Specialized;
using Newtonsoft.Json; using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -142,19 +143,19 @@ namespace Cryville.Crtr {
} }
[JsonIgnore] [JsonIgnore]
public Dictionary<int, PropSrc> PropSrcs { get; private set; } public IntKeyedDictionary<PropSrc> PropSrcs { get; private set; }
protected void SubmitPropSrc(string name, PropSrc property) { protected void SubmitPropSrc(string name, PropSrc property) {
PropSrcs.Add(IdentifierManager.SharedInstance.Request(name), property); PropSrcs.Add(IdentifierManager.SharedInstance.Request(name), property);
} }
[JsonIgnore] [JsonIgnore]
public Dictionary<int, PropOp> PropOps { get; private set; } public IntKeyedDictionary<PropOp> PropOps { get; private set; }
protected void SubmitPropOp(string name, PropOp property) { protected void SubmitPropOp(string name, PropOp property) {
PropOps.Add(IdentifierManager.SharedInstance.Request(name), property); PropOps.Add(IdentifierManager.SharedInstance.Request(name), property);
} }
protected ChartEvent() { protected ChartEvent() {
PropSrcs = new Dictionary<int, PropSrc>(); PropSrcs = new IntKeyedDictionary<PropSrc>();
PropOps = new Dictionary<int, PropOp>(); PropOps = new IntKeyedDictionary<PropOp>();
SubmitPropSrc("event", new PropSrc.Float(() => { SubmitPropSrc("event", new PropSrc.Float(() => {
int hash = GetHashCode(); int hash = GetHashCode();
return Unsafe.As<int, float>(ref hash); return Unsafe.As<int, float>(ref hash);

View File

@@ -1,6 +1,6 @@
using Cryville.Common; using Cryville.Common;
using Cryville.Common.Collections.Specialized;
using Cryville.Common.Pdt; using Cryville.Common.Pdt;
using System.Collections.Generic;
using UnityEngine; using UnityEngine;
namespace Cryville.Crtr.Components { namespace Cryville.Crtr.Components {
@@ -8,7 +8,7 @@ namespace Cryville.Crtr.Components {
/// <summary> /// <summary>
/// The property operators of the component. /// The property operators of the component.
/// </summary> /// </summary>
public Dictionary<int, SkinProperty> Properties { get; private set; } public IntKeyedDictionary<SkinProperty> Properties { get; private set; }
/// <summary> /// <summary>
/// Submits a property. /// Submits a property.
/// </summary> /// </summary>
@@ -22,7 +22,7 @@ namespace Cryville.Crtr.Components {
/// Creates a skin component. /// Creates a skin component.
/// </summary> /// </summary>
protected SkinComponent() { protected SkinComponent() {
Properties = new Dictionary<int, SkinProperty>(); Properties = new IntKeyedDictionary<SkinProperty>();
} }
public virtual void Init() { } public virtual void Init() { }

View File

@@ -1,10 +1,10 @@
using System.Collections.Generic; using Cryville.Common.Collections.Specialized;
using UnityEngine; using UnityEngine;
namespace Cryville.Crtr { namespace Cryville.Crtr {
public class EffectManager { public class EffectManager {
readonly Dictionary<int, EffectGroup> _groups readonly IntKeyedDictionary<EffectGroup> _groups
= new Dictionary<int, EffectGroup>(); = new IntKeyedDictionary<EffectGroup>();
public EffectManager(PdtSkin skin) { public EffectManager(PdtSkin skin) {
foreach (var e in skin.effects) { foreach (var e in skin.effects) {
_groups.Add(e.Key.Key, new EffectGroup(e.Value)); _groups.Add(e.Key.Key, new EffectGroup(e.Value));

View File

@@ -1,5 +1,6 @@
using Cryville.Common; using Cryville.Common;
using Cryville.Common.Buffers; using Cryville.Common.Buffers;
using Cryville.Common.Collections.Specialized;
using Cryville.Crtr.Components; using Cryville.Crtr.Components;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -65,7 +66,7 @@ namespace Cryville.Crtr.Event {
static readonly int _var_current_time = IdentifierManager.SharedInstance.Request("current_time"); static readonly int _var_current_time = IdentifierManager.SharedInstance.Request("current_time");
static readonly int _var_invisible_bounds = IdentifierManager.SharedInstance.Request("invisible_bounds"); static readonly int _var_invisible_bounds = IdentifierManager.SharedInstance.Request("invisible_bounds");
public readonly Dictionary<int, PropSrc> PropSrcs = new Dictionary<int, PropSrc>(); public readonly IntKeyedDictionary<PropSrc> PropSrcs = new IntKeyedDictionary<PropSrc>();
SkinContainer skinContainer; SkinContainer skinContainer;
protected Judge judge; protected Judge judge;
public void AttachSystems(PdtSkin skin, Judge judge) { public void AttachSystems(PdtSkin skin, Judge judge) {
@@ -73,9 +74,9 @@ namespace Cryville.Crtr.Event {
this.judge = judge; this.judge = judge;
} }
public readonly Dictionary<int, List<Anchor>> Anchors = new Dictionary<int, List<Anchor>>(); public readonly IntKeyedDictionary<List<Anchor>> Anchors = new IntKeyedDictionary<List<Anchor>>();
public readonly Dictionary<int, Anchor> DynamicAnchors = new Dictionary<int, Anchor>(); public readonly IntKeyedDictionary<Anchor> DynamicAnchors = new IntKeyedDictionary<Anchor>();
public readonly Dictionary<int, double> DynamicAnchorSetTime = new Dictionary<int, double>(); public readonly IntKeyedDictionary<double> DynamicAnchorSetTime = new IntKeyedDictionary<double>();
Anchor a_cur; Anchor a_cur;
Anchor a_head; Anchor a_head;
Anchor a_tail; Anchor a_tail;

View File

@@ -2,6 +2,7 @@
using Cryville.Common; using Cryville.Common;
using Cryville.Common.Buffers; using Cryville.Common.Buffers;
using Cryville.Common.Collections.Specialized;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
@@ -91,13 +92,13 @@ namespace Cryville.Crtr.Event {
Parent = parent; Parent = parent;
} }
_rmvpa = new CategorizedPoolAccessor<Identifier, RealtimeMotionValue>(RMVPool); _rmvpa = new CategorizedPoolAccessor<int, RealtimeMotionValue>(RMVPool);
_mcpa = new CategorizedPoolAccessor<Identifier, MotionCache>(MCPool); _mcpa = new CategorizedPoolAccessor<int, MotionCache>(MCPool);
Values = new Dictionary<Identifier, RealtimeMotionValue>(ChartPlayer.motionRegistry.Count); Values = new IntKeyedDictionary<RealtimeMotionValue>(ChartPlayer.motionRegistry.Count);
CachedValues = new Dictionary<Identifier, MotionCache>(ChartPlayer.motionRegistry.Count); CachedValues = new IntKeyedDictionary<MotionCache>(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.Key, new RealtimeMotionValue().Init(Parent == null ? m.Value.GlobalInitValue : m.Value.InitValue));
rootPrototype = this; rootPrototype = this;
} }
@@ -114,13 +115,13 @@ namespace Cryville.Crtr.Event {
public ContainerState Clone(byte ct) { public ContainerState Clone(byte ct) {
var r = (ContainerState)MemberwiseClone(); var r = (ContainerState)MemberwiseClone();
var mvs = new Dictionary<Identifier, RealtimeMotionValue>(ChartPlayer.motionRegistry.Count); var mvs = new IntKeyedDictionary<RealtimeMotionValue>(ChartPlayer.motionRegistry.Count);
foreach (var mv in Values) { foreach (var mv in Values) {
mvs.Add(mv.Key, mv.Value.Clone()); mvs.Add(mv.Key, mv.Value.Clone());
} }
r.Values = mvs; r.Values = mvs;
var cvs = new Dictionary<Identifier, MotionCache>(ChartPlayer.motionRegistry.Count); var cvs = new IntKeyedDictionary<MotionCache>(ChartPlayer.motionRegistry.Count);
r.CachedValues = cvs; r.CachedValues = cvs;
r.Children = new Dictionary<EventContainer, ContainerState>(); r.Children = new Dictionary<EventContainer, ContainerState>();
@@ -218,11 +219,11 @@ namespace Cryville.Crtr.Event {
#region Motion #region Motion
internal static RMVPool RMVPool; internal static RMVPool RMVPool;
internal static MotionCachePool MCPool; internal static MotionCachePool MCPool;
readonly CategorizedPoolAccessor<Identifier, RealtimeMotionValue> _rmvpa; readonly CategorizedPoolAccessor<int, RealtimeMotionValue> _rmvpa;
readonly CategorizedPoolAccessor<Identifier, MotionCache> _mcpa; readonly CategorizedPoolAccessor<int, MotionCache> _mcpa;
Dictionary<StampedEvent, RealtimeMotionValue> PlayingMotions = new Dictionary<StampedEvent, RealtimeMotionValue>(4); Dictionary<StampedEvent, RealtimeMotionValue> PlayingMotions = new Dictionary<StampedEvent, RealtimeMotionValue>(4);
Dictionary<Identifier, RealtimeMotionValue> Values; IntKeyedDictionary<RealtimeMotionValue> Values;
Dictionary<Identifier, MotionCache> CachedValues; IntKeyedDictionary<MotionCache> CachedValues;
/// <summary> /// <summary>
/// Gets a motion value. /// Gets a motion value.
@@ -230,13 +231,13 @@ namespace Cryville.Crtr.Event {
/// <param name="name">The motion name.</param> /// <param name="name">The motion name.</param>
/// <param name="clone">Returns a cloned motion value instead.</param> /// <param name="clone">Returns a cloned motion value instead.</param>
/// <returns>A motion value.</returns> /// <returns>A motion value.</returns>
RealtimeMotionValue GetMotionValue(Identifier name, bool clone = false) { RealtimeMotionValue GetMotionValue(int name, bool clone = false) {
RealtimeMotionValue value = Values[name]; RealtimeMotionValue value = Values[name];
if (clone) return value.Clone(); if (clone) return value.Clone();
return value; return value;
} }
void InvalidateMotion(Identifier name) { void InvalidateMotion(int name) {
MotionCache cache; MotionCache cache;
if (!CachedValues.TryGetValue(name, out cache)) if (!CachedValues.TryGetValue(name, out cache))
CachedValues.Add(name, cache = _mcpa.Rent(name)); CachedValues.Add(name, cache = _mcpa.Rent(name));
@@ -245,7 +246,7 @@ namespace Cryville.Crtr.Event {
Children[c].InvalidateMotion(name); Children[c].InvalidateMotion(name);
} }
public Vector GetRawValue(Identifier key) { public Vector GetRawValue(int key) {
MotionCache tr; MotionCache tr;
if (!CachedValues.TryGetValue(key, out tr)) if (!CachedValues.TryGetValue(key, out tr))
CachedValues.Add(key, tr = _mcpa.Rent(key)); CachedValues.Add(key, tr = _mcpa.Rent(key));
@@ -263,11 +264,11 @@ namespace Cryville.Crtr.Event {
return r; return r;
} }
public T GetRawValue<T>(Identifier key) where T : Vector { public T GetRawValue<T>(int key) where T : Vector {
return (T)GetRawValue(key); return (T)GetRawValue(key);
} }
static readonly Identifier n_pt = new Identifier("pt"); static readonly int n_pt = IdentifierManager.SharedInstance.Request("pt");
public Vector2 ScreenPoint { public Vector2 ScreenPoint {
get { get {
var mv = GetRawValue<VecPt>(n_pt); var mv = GetRawValue<VecPt>(n_pt);
@@ -275,7 +276,7 @@ namespace Cryville.Crtr.Event {
} }
} }
static readonly Identifier n_dir = new Identifier("dir"); static readonly int n_dir = IdentifierManager.SharedInstance.Request("dir");
public Vector3 Direction { public Vector3 Direction {
get { get {
Vec3 r = GetRawValue<Vec3>(n_dir); Vec3 r = GetRawValue<Vec3>(n_dir);
@@ -283,7 +284,7 @@ namespace Cryville.Crtr.Event {
} }
} }
static readonly Identifier n_normal = new Identifier("normal"); static readonly int n_normal = IdentifierManager.SharedInstance.Request("normal");
public Vector3 Normal { public Vector3 Normal {
get { get {
Vec3 r = GetRawValue<Vec3>(n_normal); Vec3 r = GetRawValue<Vec3>(n_normal);
@@ -297,8 +298,8 @@ namespace Cryville.Crtr.Event {
} }
} }
static readonly Identifier n_sv = new Identifier("sv"); static readonly int n_sv = IdentifierManager.SharedInstance.Request("sv");
static readonly Identifier n_svm = new Identifier("svm"); static readonly int n_svm = IdentifierManager.SharedInstance.Request("svm");
public float ScrollVelocity { public float ScrollVelocity {
get { get {
return GetRawValue<VecPtComp>(n_sv).ToFloat(ChartPlayer.hitRect) return GetRawValue<VecPtComp>(n_sv).ToFloat(ChartPlayer.hitRect)
@@ -306,7 +307,7 @@ namespace Cryville.Crtr.Event {
} }
} }
static readonly Identifier n_dist = new Identifier("dist"); static readonly int n_dist = IdentifierManager.SharedInstance.Request("dist");
public float Distance { public float Distance {
get { get {
var mv = GetRawValue<VecPtComp>(n_dist); var mv = GetRawValue<VecPtComp>(n_dist);
@@ -314,15 +315,15 @@ namespace Cryville.Crtr.Event {
} }
} }
static readonly Identifier n_corner = new Identifier("corner"); static readonly int n_corner = IdentifierManager.SharedInstance.Request("corner");
public bool Corner { public bool Corner {
get { get {
return GetRawValue<VecI1>(n_corner).Value % 2 >= 1; return GetRawValue<VecI1>(n_corner).Value % 2 >= 1;
} }
} }
static readonly Identifier n_ctrl0 = new Identifier("ctrl0"); static readonly int n_ctrl0 = IdentifierManager.SharedInstance.Request("ctrl0");
static readonly Identifier n_ctrl1 = new Identifier("ctrl1"); static readonly int n_ctrl1 = IdentifierManager.SharedInstance.Request("ctrl1");
public Vector3 GetControlPoint(bool alt1, float deltaz) { public Vector3 GetControlPoint(bool alt1, float deltaz) {
var mv = GetRawValue<VecCtrl>(alt1 ? n_ctrl1 : n_ctrl0); var mv = GetRawValue<VecCtrl>(alt1 ? n_ctrl1 : n_ctrl0);
if (alt1 && mv.IsZero()) { if (alt1 && mv.IsZero()) {
@@ -331,7 +332,7 @@ namespace Cryville.Crtr.Event {
return mv.ToVector3(ChartPlayer.hitRect, deltaz); return mv.ToVector3(ChartPlayer.hitRect, deltaz);
} }
static readonly Identifier n_track = new Identifier("track"); static readonly int n_track = IdentifierManager.SharedInstance.Request("track");
public float Track { public float Track {
get { get {
return GetRawValue<Vec1>(n_track).Value; return GetRawValue<Vec1>(n_track).Value;
@@ -357,9 +358,9 @@ namespace Cryville.Crtr.Event {
if (ev != null) { if (ev != null) {
if (ev.Unstamped is Chart.Motion) { if (ev.Unstamped is Chart.Motion) {
var tev = (Chart.Motion)ev.Unstamped; var tev = (Chart.Motion)ev.Unstamped;
var mv = _rmvpa.Rent(tev.Name); var mv = _rmvpa.Rent(tev.Name.Key);
mv.CloneTypeFlag = CloneType; mv.CloneTypeFlag = CloneType;
GetMotionValue(tev.Name).CopyTo(mv); GetMotionValue(tev.Name.Key).CopyTo(mv);
PlayingMotions.Add(ev, mv); PlayingMotions.Add(ev, mv);
Update(ev); Update(ev);
if (!ev.Unstamped.IsLong) { if (!ev.Unstamped.IsLong) {
@@ -407,8 +408,8 @@ namespace Cryville.Crtr.Event {
foreach (var m in PlayingMotions) { foreach (var m in PlayingMotions) {
var tev = (Chart.Motion)m.Key.Unstamped; var tev = (Chart.Motion)m.Key.Unstamped;
if (tev.RelativeNode != null && CloneType == 2) continue; if (tev.RelativeNode != null && CloneType == 2) continue;
var value = GetMotionValue(tev.Name/*, true*/); var value = GetMotionValue(tev.Name.Key/*, true*/);
InvalidateMotion(tev.Name); InvalidateMotion(tev.Name.Key);
if (m.Key.Duration == 0) { if (m.Key.Duration == 0) {
if (tev.RelativeNode != null) { if (tev.RelativeNode != null) {
value.SetRelativeNode(tev.RelativeNode); value.SetRelativeNode(tev.RelativeNode);
@@ -428,7 +429,7 @@ namespace Cryville.Crtr.Event {
tev.AbsoluteValue.LerpWith(m.Value.AbsoluteValue, lerpedTime, ref value.AbsoluteValue); tev.AbsoluteValue.LerpWith(m.Value.AbsoluteValue, lerpedTime, ref value.AbsoluteValue);
} }
} }
Values[tev.Name] = value; Values[tev.Name.Key] = value;
} }
} }

View File

@@ -1,5 +1,6 @@
using Cryville.Common; using Cryville.Common;
using Cryville.Common.Buffers; using Cryville.Common.Buffers;
using Cryville.Common.Collections.Specialized;
using System.Collections.Generic; using System.Collections.Generic;
namespace Cryville.Crtr.Event { namespace Cryville.Crtr.Event {
@@ -11,7 +12,7 @@ namespace Cryville.Crtr.Event {
Value.CopyTo(dest.Value); Value.CopyTo(dest.Value);
} }
} }
internal class MotionCachePool : CategorizedPool<Identifier, MotionCache> { internal class MotionCachePool : CategorizedPool<int, MotionCache> {
private class Bucket : ObjectPool<MotionCache> { private class Bucket : ObjectPool<MotionCache> {
readonly MotionRegistry _reg; readonly MotionRegistry _reg;
public Bucket(Identifier name, int capacity) : base(capacity) { public Bucket(Identifier name, int capacity) : base(capacity) {
@@ -26,12 +27,12 @@ namespace Cryville.Crtr.Event {
obj.Valid = false; obj.Valid = false;
} }
} }
readonly Dictionary<Identifier, ObjectPool<MotionCache>> m_buckets; readonly IntKeyedDictionary<ObjectPool<MotionCache>> m_buckets;
protected override IReadOnlyDictionary<Identifier, ObjectPool<MotionCache>> Buckets { get { return m_buckets; } } protected override IReadOnlyDictionary<int, ObjectPool<MotionCache>> Buckets { get { return m_buckets; } }
public MotionCachePool() { public MotionCachePool() {
m_buckets = new Dictionary<Identifier, ObjectPool<MotionCache>>(ChartPlayer.motionRegistry.Count); m_buckets = new IntKeyedDictionary<ObjectPool<MotionCache>>(ChartPlayer.motionRegistry.Count);
foreach (var reg in ChartPlayer.motionRegistry) foreach (var reg in ChartPlayer.motionRegistry)
m_buckets.Add(reg.Key, new Bucket(reg.Key, 4096)); m_buckets.Add(reg.Key.Key, new Bucket(reg.Key, 4096));
} }
} }
} }

View File

@@ -1,9 +1,10 @@
using Cryville.Common; using Cryville.Common;
using Cryville.Common.Buffers; using Cryville.Common.Buffers;
using Cryville.Common.Collections.Specialized;
using System.Collections.Generic; using System.Collections.Generic;
namespace Cryville.Crtr.Event { namespace Cryville.Crtr.Event {
internal class RMVPool : CategorizedPool<Identifier, RealtimeMotionValue> { internal class RMVPool : CategorizedPool<int, RealtimeMotionValue> {
private class Bucket : ObjectPool<RealtimeMotionValue> { private class Bucket : ObjectPool<RealtimeMotionValue> {
readonly MotionRegistry _reg; readonly MotionRegistry _reg;
public Bucket(Identifier name, int capacity) : base(capacity) { public Bucket(Identifier name, int capacity) : base(capacity) {
@@ -13,12 +14,12 @@ namespace Cryville.Crtr.Event {
return new RealtimeMotionValue().Init(_reg.InitValue); return new RealtimeMotionValue().Init(_reg.InitValue);
} }
} }
readonly Dictionary<Identifier, ObjectPool<RealtimeMotionValue>> m_buckets; readonly IntKeyedDictionary<ObjectPool<RealtimeMotionValue>> m_buckets;
protected override IReadOnlyDictionary<Identifier, ObjectPool<RealtimeMotionValue>> Buckets { get { return m_buckets; } } protected override IReadOnlyDictionary<int, ObjectPool<RealtimeMotionValue>> Buckets { get { return m_buckets; } }
public RMVPool() { public RMVPool() {
m_buckets = new Dictionary<Identifier, ObjectPool<RealtimeMotionValue>>(ChartPlayer.motionRegistry.Count); m_buckets = new IntKeyedDictionary<ObjectPool<RealtimeMotionValue>>(ChartPlayer.motionRegistry.Count);
foreach (var reg in ChartPlayer.motionRegistry) foreach (var reg in ChartPlayer.motionRegistry)
m_buckets.Add(reg.Key, new Bucket(reg.Key, 4096)); m_buckets.Add(reg.Key.Key, new Bucket(reg.Key, 4096));
} }
} }
} }

View File

@@ -1,5 +1,6 @@
using Cryville.Common; using Cryville.Common;
using Cryville.Common.Buffers; using Cryville.Common.Buffers;
using Cryville.Common.Collections.Specialized;
using Cryville.Common.Pdt; using Cryville.Common.Pdt;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -82,7 +83,7 @@ namespace Cryville.Crtr {
} }
#endregion #endregion
#region Judge #region Judge
internal readonly Dictionary<int, int> judgeMap = new Dictionary<int, int>(); internal readonly IntKeyedDictionary<int> judgeMap = new IntKeyedDictionary<int>();
void InitJudges() { void InitJudges() {
foreach (var i in _rs.judges) { foreach (var i in _rs.judges) {
var id = i.Key; var id = i.Key;
@@ -215,15 +216,15 @@ namespace Cryville.Crtr {
} }
#endregion #endregion
#region Score #region Score
readonly Dictionary<int, int> scoreStringKeys = new Dictionary<int, int>(); readonly IntKeyedDictionary<int> scoreStringKeys = new IntKeyedDictionary<int>();
readonly Dictionary<int, int> scoreStringKeysRev = new Dictionary<int, int>(); readonly IntKeyedDictionary<int> scoreStringKeysRev = new IntKeyedDictionary<int>();
readonly Dictionary<int, PropSrc> scoreSrcs = new Dictionary<int, PropSrc>(); readonly IntKeyedDictionary<PropSrc> scoreSrcs = new IntKeyedDictionary<PropSrc>();
readonly Dictionary<int, PropOp> scoreOps = new Dictionary<int, PropOp>(); readonly IntKeyedDictionary<PropOp> scoreOps = new IntKeyedDictionary<PropOp>();
readonly Dictionary<int, ScoreDefinition> scoreDefs = new Dictionary<int, ScoreDefinition>(); readonly IntKeyedDictionary<ScoreDefinition> scoreDefs = new IntKeyedDictionary<ScoreDefinition>();
readonly Dictionary<int, float> scores = new Dictionary<int, float>(); readonly IntKeyedDictionary<float> scores = new IntKeyedDictionary<float>();
readonly Dictionary<int, string> scoreStringCache = new Dictionary<int, string>(); readonly IntKeyedDictionary<string> scoreStringCache = new IntKeyedDictionary<string>();
readonly ArrayPool<byte> scoreStringPool = new ArrayPool<byte>(); readonly ArrayPool<byte> scoreStringPool = new ArrayPool<byte>();
readonly Dictionary<int, string> scoreFormatCache = new Dictionary<int, string>(); readonly IntKeyedDictionary<string> scoreFormatCache = new IntKeyedDictionary<string>();
readonly TargetString scoreFullStr = new TargetString(); readonly TargetString scoreFullStr = new TargetString();
readonly StringBuffer scoreFullBuf = new StringBuffer(); readonly StringBuffer scoreFullBuf = new StringBuffer();
void InitScores() { void InitScores() {

View File

@@ -1,4 +1,5 @@
using Cryville.Common; using Cryville.Common;
using Cryville.Common.Collections.Specialized;
using Cryville.Common.Math; using Cryville.Common.Math;
using Cryville.Common.Pdt; using Cryville.Common.Pdt;
using Cryville.Crtr.Event; using Cryville.Crtr.Event;
@@ -10,7 +11,7 @@ using UnityEngine;
namespace Cryville.Crtr { namespace Cryville.Crtr {
public class PdtEvaluator : PdtEvaluatorBase { public class PdtEvaluator : PdtEvaluatorBase {
static readonly Dictionary<PdtOperatorSignature, PdtOperator> _shortops = new Dictionary<PdtOperatorSignature, PdtOperator>(); static readonly Dictionary<PdtOperatorSignature, PdtOperator> _shortops = new Dictionary<PdtOperatorSignature, PdtOperator>();
readonly Dictionary<int, PdtOperator> _ctxops = new Dictionary<int, PdtOperator>(); readonly IntKeyedDictionary<PdtOperator> _ctxops = new IntKeyedDictionary<PdtOperator>();
static readonly byte[] _nullbuf = new byte[0]; static readonly byte[] _nullbuf = new byte[0];
readonly byte[] _numbuf = new byte[4]; readonly byte[] _numbuf = new byte[4];
@@ -31,13 +32,12 @@ namespace Cryville.Crtr {
else if (name == _var_false) { LoadNum(0); type = PdtInternalType.Number; value = _numbuf; } else if (name == _var_false) { LoadNum(0); type = PdtInternalType.Number; value = _numbuf; }
else if (name == _var_null) { LoadIdent(0); type = PdtInternalType.Undefined; value = _numbuf; } else if (name == _var_null) { LoadIdent(0); type = PdtInternalType.Undefined; value = _numbuf; }
else { else {
var id = new Identifier(name);
PropSrc prop; SkinVariable variable; PropSrc prop; SkinVariable variable;
if (ContextEvent != null && ContextEvent.PropSrcs.TryGetValue(name, out prop)) { if (ContextEvent != null && ContextEvent.PropSrcs.TryGetValue(name, out prop)) {
prop.Get(out type, out value); prop.Get(out type, out value);
} }
else if (ContextState != null && ChartPlayer.motionRegistry.ContainsKey(id)) { else if (ContextState != null && ChartPlayer.motionRegistry.ContainsKey(new Identifier(name))) {
_vec = ContextState.GetRawValue(id); _vec = ContextState.GetRawValue(name);
_vecsrc.Invalidate(); _vecsrc.Invalidate();
_vecsrc.Get(out type, out value); _vecsrc.Get(out type, out value);
} }
@@ -121,12 +121,12 @@ namespace Cryville.Crtr {
public void ContextCascadeDiscardBlock() { public void ContextCascadeDiscardBlock() {
ContextCascadeBlocks.Pop(); ContextCascadeBlocks.Pop();
} }
readonly Dictionary<int, PropSrc>[] ContextCascade = new Dictionary<int, PropSrc>[256]; readonly IntKeyedDictionary<PropSrc>[] ContextCascade = new IntKeyedDictionary<PropSrc>[256];
int _cascadeHeight; int _cascadeHeight;
public void ContextCascadeInsert() { public void ContextCascadeInsert() {
ContextCascade[_cascadeHeight++].Clear(); ContextCascade[_cascadeHeight++].Clear();
} }
public void ContextCascadeInsert(Dictionary<int, PropSrc> srcs) { public void ContextCascadeInsert(IReadOnlyDictionary<int, PropSrc> srcs) {
ContextCascadeInsert(); ContextCascadeInsert();
foreach (var src in srcs) ContextCascadeUpdate(src.Key, src.Value); foreach (var src in srcs) ContextCascadeUpdate(src.Key, src.Value);
} }
@@ -136,7 +136,7 @@ namespace Cryville.Crtr {
public PropSrc ContextCascadeLookup(int name) { public PropSrc ContextCascadeLookup(int name) {
PropSrc result; PropSrc result;
for (int i = _cascadeHeight - 1; i >= ContextCascadeBlocks.Peek(); i--) { for (int i = _cascadeHeight - 1; i >= ContextCascadeBlocks.Peek(); i--) {
Dictionary<int, PropSrc> cas = ContextCascade[i]; var cas = ContextCascade[i];
if (cas.TryGetValue(name, out result)) { if (cas.TryGetValue(name, out result)) {
return result; return result;
} }
@@ -149,7 +149,7 @@ namespace Cryville.Crtr {
public PdtEvaluator() { public PdtEvaluator() {
ContextCascadeBlocks.Push(0); ContextCascadeBlocks.Push(0);
for (int i = 0; i < ContextCascade.Length; i++) ContextCascade[i] = new Dictionary<int, PropSrc>(); for (int i = 0; i < ContextCascade.Length; i++) ContextCascade[i] = new IntKeyedDictionary<PropSrc>();
_vecsrc = new VectorSrc(() => _vec); _vecsrc = new VectorSrc(() => _vec);
_ctxops.Add(IdentifierManager.SharedInstance.Request("screen_edge"), new func_screen_edge(() => ContextTransform)); _ctxops.Add(IdentifierManager.SharedInstance.Request("screen_edge"), new func_screen_edge(() => ContextTransform));

View File

@@ -1,7 +1,7 @@
using Cryville.Common; using Cryville.Common;
using Cryville.Common.Collections.Specialized;
using Cryville.Common.Pdt; using Cryville.Common.Pdt;
using System; using System;
using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using RBeatTime = Cryville.Crtr.BeatTime; using RBeatTime = Cryville.Crtr.BeatTime;
using RClip = Cryville.Crtr.Clip; using RClip = Cryville.Crtr.Clip;
@@ -100,7 +100,7 @@ namespace Cryville.Crtr {
} }
} }
public class Enum<T> : PropOp { public class Enum<T> : PropOp {
static readonly Dictionary<int, int> _cache = new Dictionary<int, int>(); static readonly IntKeyedDictionary<int> _cache = new IntKeyedDictionary<int>();
readonly Action<T> _cb; readonly Action<T> _cb;
readonly Func<int, T> _caster; readonly Func<int, T> _caster;
static Enum() { static Enum() {
@@ -109,7 +109,6 @@ namespace Cryville.Crtr {
var names = typeof(T).GetFields(BindingFlags.Public | BindingFlags.Static); var names = typeof(T).GetFields(BindingFlags.Public | BindingFlags.Static);
for (int i = 0; i < names.Length; i++) for (int i = 0; i < names.Length; i++)
_cache[IdentifierManager.SharedInstance.Request(names[i].Name)] = Convert.ToInt32(names[i].GetValue(null)); _cache[IdentifierManager.SharedInstance.Request(names[i].Name)] = Convert.ToInt32(names[i].GetValue(null));
} }
public Enum(Action<T> cb, Func<int, T> caster) { public Enum(Action<T> cb, Func<int, T> caster) {
_cb = cb; _cb = cb;

View File

@@ -1,3 +1,4 @@
using Cryville.Common.Collections.Specialized;
using Cryville.Common.Pdt; using Cryville.Common.Pdt;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
@@ -9,7 +10,7 @@ namespace Cryville.Crtr {
readonly SkinElement _rootElement; readonly SkinElement _rootElement;
readonly DynamicStack[] _stacks = new DynamicStack[2]; readonly DynamicStack[] _stacks = new DynamicStack[2];
readonly HashSet<SkinPropertyKey> _once = new HashSet<SkinPropertyKey>(); readonly HashSet<SkinPropertyKey> _once = new HashSet<SkinPropertyKey>();
public readonly Dictionary<int, SkinVariable> Variables = new Dictionary<int, SkinVariable>(); public readonly IntKeyedDictionary<SkinVariable> Variables = new IntKeyedDictionary<SkinVariable>();
class DynamicStack { class DynamicStack {
public readonly List<DynamicProperty> Properties = new List<DynamicProperty>(); public readonly List<DynamicProperty> Properties = new List<DynamicProperty>();
@@ -167,8 +168,8 @@ namespace Cryville.Crtr {
} }
public class SkinContext { public class SkinContext {
public Transform Transform { get; private set; } public Transform Transform { get; private set; }
public Dictionary<int, PropSrc> PropSrcs { get; private set; } public IReadOnlyDictionary<int, PropSrc> PropSrcs { get; private set; }
public SkinContext(Transform transform, Dictionary<int, PropSrc> propSrcs = null) { public SkinContext(Transform transform, IReadOnlyDictionary<int, PropSrc> propSrcs = null) {
Transform = transform; Transform = transform;
PropSrcs = propSrcs; PropSrcs = propSrcs;
} }

View File

@@ -1,4 +1,5 @@
using Cryville.Common; using Cryville.Common;
using Cryville.Common.Collections.Specialized;
using Cryville.Common.Pdt; using Cryville.Common.Pdt;
using Cryville.Crtr.Components; using Cryville.Crtr.Components;
using System; using System;
@@ -50,8 +51,8 @@ namespace Cryville.Crtr {
} }
public abstract override string ToString(); public abstract override string ToString();
public abstract bool IsValueRequired { get; } public abstract bool IsValueRequired { get; }
public abstract void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars); public abstract void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, IntKeyedDictionary<SkinVariable> vars);
public abstract void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars, int dl); public abstract void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, IntKeyedDictionary<SkinVariable> vars, int dl);
public class CreateComponent : SkinPropertyKey { public class CreateComponent : SkinPropertyKey {
public Type Component { get; private set; } public Type Component { get; private set; }
public CreateComponent(IEnumerable<string> a, Type component) : base(a) { public CreateComponent(IEnumerable<string> a, Type component) : base(a) {
@@ -61,10 +62,10 @@ namespace Cryville.Crtr {
return string.Format("*{0}", Component.Name); return string.Format("*{0}", Component.Name);
} }
public override bool IsValueRequired { get { return false; } } public override bool IsValueRequired { get { return false; } }
public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars) { public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, IntKeyedDictionary<SkinVariable> vars) {
ctx.WriteTransform.gameObject.AddComponent(Component); ctx.WriteTransform.gameObject.AddComponent(Component);
} }
public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars, int dl) { public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, IntKeyedDictionary<SkinVariable> vars, int dl) {
throw new InvalidOperationException("Component creation in dynamic context is not allowed"); throw new InvalidOperationException("Component creation in dynamic context is not allowed");
} }
} }
@@ -79,10 +80,10 @@ namespace Cryville.Crtr {
return string.Format("{0}.{1}", Component.Name, IdentifierManager.SharedInstance.Retrieve(Name)); return string.Format("{0}.{1}", Component.Name, IdentifierManager.SharedInstance.Retrieve(Name));
} }
public override bool IsValueRequired { get { return true; } } public override bool IsValueRequired { get { return true; } }
public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars) { public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, IntKeyedDictionary<SkinVariable> vars) {
Execute(ctx, GetPropOp(ctx.WriteTransform).Operator, exp); Execute(ctx, GetPropOp(ctx.WriteTransform).Operator, exp);
} }
public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars, int dl) { public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, IntKeyedDictionary<SkinVariable> vars, int dl) {
var prop = GetPropOp(ctx.WriteTransform); var prop = GetPropOp(ctx.WriteTransform);
if (dl > prop.UpdateDynamicLevel) return; if (dl > prop.UpdateDynamicLevel) return;
Execute(ctx, prop.Operator, exp); Execute(ctx, prop.Operator, exp);
@@ -118,10 +119,10 @@ namespace Cryville.Crtr {
return string.Format("@has {0}", IdentifierManager.SharedInstance.Retrieve(Name)); return string.Format("@has {0}", IdentifierManager.SharedInstance.Retrieve(Name));
} }
public override bool IsValueRequired { get { return false; } } public override bool IsValueRequired { get { return false; } }
public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars) { public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, IntKeyedDictionary<SkinVariable> vars) {
group.RegisterAnchor(Name); group.RegisterAnchor(Name);
} }
public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars, int dl) { public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, IntKeyedDictionary<SkinVariable> vars, int dl) {
throw new InvalidOperationException("Anchor creation in dynamic context is not allowed"); throw new InvalidOperationException("Anchor creation in dynamic context is not allowed");
} }
} }
@@ -135,12 +136,12 @@ namespace Cryville.Crtr {
return string.Format("@at {0}", IdentifierManager.SharedInstance.Retrieve(Name)); return string.Format("@at {0}", IdentifierManager.SharedInstance.Retrieve(Name));
} }
public override bool IsValueRequired { get { return true; } } public override bool IsValueRequired { get { return true; } }
public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars) { public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, IntKeyedDictionary<SkinVariable> vars) {
throw new InvalidOperationException("Setting anchor in static context is not allowed"); throw new InvalidOperationException("Setting anchor in static context is not allowed");
} }
float _time; float _time;
readonly PropOp _timeOp; readonly PropOp _timeOp;
public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars, int dl) { public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, IntKeyedDictionary<SkinVariable> vars, int dl) {
if (dl > 0) return; if (dl > 0) return;
var psrcs = ctx.ReadContext.PropSrcs; var psrcs = ctx.ReadContext.PropSrcs;
if (psrcs != null) ChartPlayer.etor.ContextCascadeInsert(psrcs); if (psrcs != null) ChartPlayer.etor.ContextCascadeInsert(psrcs);
@@ -161,12 +162,12 @@ namespace Cryville.Crtr {
return string.Format(IsSelf ? "@emit_self {0}" : "@emit {0}", IdentifierManager.SharedInstance.Retrieve(Name)); return string.Format(IsSelf ? "@emit_self {0}" : "@emit {0}", IdentifierManager.SharedInstance.Retrieve(Name));
} }
public override bool IsValueRequired { get { return true; } } public override bool IsValueRequired { get { return true; } }
public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars) { public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, IntKeyedDictionary<SkinVariable> vars) {
throw new InvalidOperationException("Emitting effect in static context is not allowed"); throw new InvalidOperationException("Emitting effect in static context is not allowed");
} }
float _index; float _index;
readonly PropOp _op; readonly PropOp _op;
public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars, int dl) { public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, IntKeyedDictionary<SkinVariable> vars, int dl) {
ChartPlayer.etor.Evaluate(_op, exp); ChartPlayer.etor.Evaluate(_op, exp);
if (IsSelf) ChartPlayer.effectManager.EmitSelf(Name, _index, ctx.WriteTransform); if (IsSelf) ChartPlayer.effectManager.EmitSelf(Name, _index, ctx.WriteTransform);
else ChartPlayer.effectManager.Emit(Name, _index); else ChartPlayer.effectManager.Emit(Name, _index);
@@ -181,13 +182,13 @@ namespace Cryville.Crtr {
return string.Format("@var {0}", IdentifierManager.SharedInstance.Retrieve(Name)); return string.Format("@var {0}", IdentifierManager.SharedInstance.Retrieve(Name));
} }
public override bool IsValueRequired { get { return true; } } public override bool IsValueRequired { get { return true; } }
public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars) { public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, IntKeyedDictionary<SkinVariable> vars) {
SkinVariable v; SkinVariable v;
if (!vars.TryGetValue(Name, out v)) if (!vars.TryGetValue(Name, out v))
vars.Add(Name, v = new SkinVariable()); vars.Add(Name, v = new SkinVariable());
ChartPlayer.etor.Evaluate(v.Op, exp); ChartPlayer.etor.Evaluate(v.Op, exp);
} }
public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars, int dl) { public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, IntKeyedDictionary<SkinVariable> vars, int dl) {
SkinVariable v; SkinVariable v;
if (!vars.TryGetValue(Name, out v)) if (!vars.TryGetValue(Name, out v))
throw new InvalidOperationException(string.Format("Variable \"{0}\" not defined", IdentifierManager.SharedInstance.Retrieve(Name))); throw new InvalidOperationException(string.Format("Variable \"{0}\" not defined", IdentifierManager.SharedInstance.Retrieve(Name)));