- In FieldLoader, cache boxed bools and some boxed ints.
- In FieldLoader, presize collections when parsing a List, HashSet or Dictionary.
- In FieldLoader, don't allocate a list of missing items until required.
- In FieldLoader, when a string value is passed, avoid wrapping this in a MiniYaml object by allowing both strings and yaml to be passed in the GetValue overload that does the real work.
- In Animation, avoid allocating no-op actions.
- In VxlReader, use EnsureCapcity to better size the Dictionary.
- In VxlReader change VxlElement to a struct.
- In Locomotor, presize TerrainSpeeds dictionary.
This helps improve the safety of code the uses reflection when methods may get renamed, and helps navigating code as the nameof will show up when searching for references to members.
- Rename Bits<T> to BitSet<T>.
- Implement set based helpers for BitSet<T>.
- When representing TargetTypes of ITargetable in various traits, use a BitSet<TargetableType> instead of HashSet<string> for better performance & reduced memory usage.
- Fix FieldLoader to trim input values when generating a BitSet<T>.
- Require T in BitSet<T> and BitSetAllocator<T> to be a class since it's just a marker value. This allows the JIT to instantiate generic code for these classes once, as they don't benefit from specialized code for T. (Typically JITs will generate shared code for all reference types, and unique code for every value type encountered).
Compiling these expressions is sadly expensive, and we needed new ones for every trait on every actor each time one was generated. The expressions thankfully can be shared as they are pure functions, which removes this overhead.