using System; namespace Nanomesh { public abstract class MetaAttributeList { public abstract IMetaAttribute this[int index] { get; set; } public abstract int Count { get; } public abstract int CountPerAttribute { get; } public abstract MetaAttributeList CreateNew(int length); public abstract MetaAttributeList AddAttributeType() where T : unmanaged, IInterpolable; public abstract bool Equals(int indexA, int indexB, int attribute); public abstract void Interpolate(int attribute, int indexA, int indexB, double ratio); } public class EmptyMetaAttributeList : MetaAttributeList { private readonly int _length; public EmptyMetaAttributeList(int length) { _length = length; } public override IMetaAttribute this[int index] { get => throw new System.Exception(); set => throw new System.Exception(); } public override MetaAttributeList CreateNew(int length) => new EmptyMetaAttributeList(length); public override unsafe bool Equals(int indexA, int indexB, int attribute) { return false; } public override void Interpolate(int attribute, int indexA, int indexB, double ratio) { throw new System.Exception(); } public override MetaAttributeList AddAttributeType() { return new MetaAttributeList(_length); } public override int Count => 0; public override int CountPerAttribute => 0; } public class MetaAttributeList : MetaAttributeList where T0 : unmanaged, IInterpolable { private readonly MetaAttribute[] _attributes; public MetaAttributeList(int length) { _attributes = new MetaAttribute[length]; } public override IMetaAttribute this[int index] { get => _attributes[index]; set => _attributes[index] = (MetaAttribute)value; } public void Set(MetaAttribute value, int index) { _attributes[index] = value; } private void Get(MetaAttribute value, int index) { _attributes[index] = value; } public override MetaAttributeList CreateNew(int length) => new MetaAttributeList(length); public override unsafe bool Equals(int indexA, int indexB, int attribute) { switch (attribute) { case 0: return _attributes[indexA].Get(0).Equals(_attributes[indexB].Get(0)); default: throw new ArgumentOutOfRangeException(); } } public override void Interpolate(int attribute, int indexA, int indexB, double ratio) { _attributes[indexA].attr0 = _attributes[indexA].Get(0).Interpolate(_attributes[indexB].Get(0), ratio); _attributes[indexB].attr0 = _attributes[indexA].attr0; } public override MetaAttributeList AddAttributeType() { MetaAttributeList newAttributes = new MetaAttributeList(_attributes.Length); for (int i = 0; i < Count; i++) newAttributes.Set(new MetaAttribute(_attributes[i].attr0, default(T)), i); return newAttributes; } public override int Count => _attributes.Length; public override int CountPerAttribute => 1; } public class MetaAttributeList : MetaAttributeList where T0 : unmanaged, IInterpolable where T1 : unmanaged, IInterpolable { private readonly MetaAttribute[] _attributes; public MetaAttributeList(int length) { _attributes = new MetaAttribute[length]; } public override IMetaAttribute this[int index] { get => _attributes[index]; set => _attributes[index] = (MetaAttribute)value; } public void Set(MetaAttribute value, int index) { _attributes[index] = value; } private void Get(MetaAttribute value, int index) { _attributes[index] = value; } public override MetaAttributeList CreateNew(int length) => new MetaAttributeList(length); public override unsafe bool Equals(int indexA, int indexB, int attribute) { switch (attribute) { case 0: return _attributes[indexA].Get(0).Equals(_attributes[indexB].Get(0)); case 1: return _attributes[indexA].Get(1).Equals(_attributes[indexB].Get(1)); default: throw new ArgumentOutOfRangeException(); } } public override void Interpolate(int attribute, int indexA, int indexB, double ratio) { switch (attribute) { case 0: _attributes[indexA].attr0 = _attributes[indexA].Get(0).Interpolate(_attributes[indexB].Get(0), ratio); _attributes[indexB].attr0 = _attributes[indexA].attr0; break; case 1: _attributes[indexA].attr1 = _attributes[indexA].Get(1).Interpolate(_attributes[indexB].Get(1), ratio); _attributes[indexB].attr1 = _attributes[indexA].attr1; break; default: throw new ArgumentOutOfRangeException(); } } public override MetaAttributeList AddAttributeType() { MetaAttributeList newAttributes = new MetaAttributeList(_attributes.Length); for (int i = 0; i < Count; i++) newAttributes.Set(new MetaAttribute(_attributes[i].attr0, _attributes[i].attr1, default(T)), i); return newAttributes; } public override int Count => _attributes.Length; public override int CountPerAttribute => 2; } public class MetaAttributeList : MetaAttributeList where T0 : unmanaged, IInterpolable where T1 : unmanaged, IInterpolable where T2 : unmanaged, IInterpolable { private readonly MetaAttribute[] _attributes; public MetaAttributeList(int length) { _attributes = new MetaAttribute[length]; } public override IMetaAttribute this[int index] { get => _attributes[index]; set => _attributes[index] = (MetaAttribute)value; } public void Set(MetaAttribute value, int index) { _attributes[index] = value; } private void Get(MetaAttribute value, int index) { _attributes[index] = value; } public override MetaAttributeList CreateNew(int length) => new MetaAttributeList(length); public override unsafe bool Equals(int indexA, int indexB, int attribute) { switch (attribute) { case 0: return _attributes[indexA].Get(0).Equals(_attributes[indexB].Get(0)); case 1: return _attributes[indexA].Get(1).Equals(_attributes[indexB].Get(1)); case 2: return _attributes[indexA].Get(2).Equals(_attributes[indexB].Get(2)); default: throw new ArgumentOutOfRangeException(); } } public override void Interpolate(int attribute, int indexA, int indexB, double ratio) { switch (attribute) { case 0: _attributes[indexA].attr0 = _attributes[indexA].Get(0).Interpolate(_attributes[indexB].Get(0), ratio); _attributes[indexB].attr0 = _attributes[indexA].attr0; break; case 1: _attributes[indexA].attr1 = _attributes[indexA].Get(1).Interpolate(_attributes[indexB].Get(1), ratio); _attributes[indexB].attr1 = _attributes[indexA].attr1; break; case 2: _attributes[indexA].attr2 = _attributes[indexA].Get(2).Interpolate(_attributes[indexB].Get(2), ratio); _attributes[indexB].attr2 = _attributes[indexA].attr2; break; default: throw new ArgumentOutOfRangeException(); } } public override MetaAttributeList AddAttributeType() { MetaAttributeList newAttributes = new MetaAttributeList(_attributes.Length); for (int i = 0; i < Count; i++) newAttributes.Set(new MetaAttribute(_attributes[i].attr0, _attributes[i].attr1, _attributes[i].attr2, default(T)), i); return newAttributes; } public override int Count => _attributes.Length; public override int CountPerAttribute => 3; } public class MetaAttributeList : MetaAttributeList where T0 : unmanaged, IInterpolable where T1 : unmanaged, IInterpolable where T2 : unmanaged, IInterpolable where T3 : unmanaged, IInterpolable { private readonly MetaAttribute[] _attributes; public MetaAttributeList(int length) { _attributes = new MetaAttribute[length]; } public override IMetaAttribute this[int index] { get => _attributes[index]; set => _attributes[index] = (MetaAttribute)value; } public void Set(MetaAttribute value, int index) { _attributes[index] = value; } private void Get(MetaAttribute value, int index) { _attributes[index] = value; } public override MetaAttributeList CreateNew(int length) => new MetaAttributeList(length); public override unsafe bool Equals(int indexA, int indexB, int attribute) { switch (attribute) { case 0: return _attributes[indexA].Get(0).Equals(_attributes[indexB].Get(0)); case 1: return _attributes[indexA].Get(1).Equals(_attributes[indexB].Get(1)); case 2: return _attributes[indexA].Get(2).Equals(_attributes[indexB].Get(2)); case 3: return _attributes[indexA].Get(3).Equals(_attributes[indexB].Get(3)); default: throw new ArgumentOutOfRangeException(); } } public override void Interpolate(int attribute, int indexA, int indexB, double ratio) { switch (attribute) { case 0: _attributes[indexA].attr0 = _attributes[indexA].Get(0).Interpolate(_attributes[indexB].Get(0), ratio); _attributes[indexB].attr0 = _attributes[indexA].attr0; break; case 1: _attributes[indexA].attr1 = _attributes[indexA].Get(1).Interpolate(_attributes[indexB].Get(1), ratio); _attributes[indexB].attr1 = _attributes[indexA].attr1; break; case 2: _attributes[indexA].attr2 = _attributes[indexA].Get(2).Interpolate(_attributes[indexB].Get(2), ratio); _attributes[indexB].attr2 = _attributes[indexA].attr2; break; case 3: _attributes[indexA].attr3 = _attributes[indexA].Get(3).Interpolate(_attributes[indexB].Get(3), ratio); _attributes[indexB].attr3 = _attributes[indexA].attr3; break; default: throw new ArgumentOutOfRangeException(); } } public override MetaAttributeList AddAttributeType() { MetaAttributeList newAttributes = new MetaAttributeList(_attributes.Length); for (int i = 0; i < Count; i++) newAttributes.Set(new MetaAttribute(_attributes[i].attr0, _attributes[i].attr1, _attributes[i].attr2, _attributes[i].attr3, default(T)), i); return newAttributes; } public override int Count => _attributes.Length; public override int CountPerAttribute => 4; } public class MetaAttributeList : MetaAttributeList where T0 : unmanaged, IInterpolable where T1 : unmanaged, IInterpolable where T2 : unmanaged, IInterpolable where T3 : unmanaged, IInterpolable where T4 : unmanaged, IInterpolable { private readonly MetaAttribute[] _attributes; public MetaAttributeList(int length) { _attributes = new MetaAttribute[length]; } public override IMetaAttribute this[int index] { get => _attributes[index]; set => _attributes[index] = (MetaAttribute)value; } public void Set(MetaAttribute value, int index) { _attributes[index] = value; } private void Get(MetaAttribute value, int index) { _attributes[index] = value; } public override MetaAttributeList CreateNew(int length) => new MetaAttributeList(length); public override unsafe bool Equals(int indexA, int indexB, int attribute) { switch (attribute) { case 0: return _attributes[indexA].Get(0).Equals(_attributes[indexB].Get(0)); case 1: return _attributes[indexA].Get(1).Equals(_attributes[indexB].Get(1)); case 2: return _attributes[indexA].Get(2).Equals(_attributes[indexB].Get(2)); case 3: return _attributes[indexA].Get(3).Equals(_attributes[indexB].Get(3)); case 4: return _attributes[indexA].Get(3).Equals(_attributes[indexB].Get(4)); default: throw new ArgumentOutOfRangeException(); } } public override void Interpolate(int attribute, int indexA, int indexB, double ratio) { switch (attribute) { case 0: _attributes[indexA].attr0 = _attributes[indexA].Get(0).Interpolate(_attributes[indexB].Get(0), ratio); _attributes[indexB].attr0 = _attributes[indexA].attr0; break; case 1: _attributes[indexA].attr1 = _attributes[indexA].Get(1).Interpolate(_attributes[indexB].Get(1), ratio); _attributes[indexB].attr1 = _attributes[indexA].attr1; break; case 2: _attributes[indexA].attr2 = _attributes[indexA].Get(2).Interpolate(_attributes[indexB].Get(2), ratio); _attributes[indexB].attr2 = _attributes[indexA].attr2; break; case 3: _attributes[indexA].attr3 = _attributes[indexA].Get(3).Interpolate(_attributes[indexB].Get(3), ratio); _attributes[indexB].attr3 = _attributes[indexA].attr3; break; case 4: _attributes[indexA].attr4 = _attributes[indexA].Get(4).Interpolate(_attributes[indexB].Get(4), ratio); _attributes[indexB].attr4 = _attributes[indexA].attr4; break; default: throw new ArgumentOutOfRangeException(); } } public override MetaAttributeList AddAttributeType() { throw new NotImplementedException(); } public override int Count => _attributes.Length; public override int CountPerAttribute => 5; } }