diff --git a/OpenRa.FileFormats/TypeDictionary.cs b/OpenRa.FileFormats/TypeDictionary.cs index e9c5db5cf5..94c71835cd 100644 --- a/OpenRa.FileFormats/TypeDictionary.cs +++ b/OpenRa.FileFormats/TypeDictionary.cs @@ -8,49 +8,73 @@ namespace OpenRa.FileFormats { public class TypeDictionary { - Cache> innerInherit = new Cache>( _ => new List() ); + Dictionary dataSingular = new Dictionary(); + Dictionary> dataMultiple = new Dictionary>(); public void Add( object val ) { var t = val.GetType(); foreach( var i in t.GetInterfaces() ) - innerInherit[ i ].Add( val ); + InnerAdd( i, val ); foreach( var tt in t.BaseTypes() ) - innerInherit[ tt ].Add( val ); + InnerAdd( tt, val ); + } + + void InnerAdd( Type t, object val ) + { + List objs; + object obj; + + if( dataMultiple.TryGetValue( t, out objs ) ) + objs.Add( val ); + else if( dataSingular.TryGetValue( t, out obj ) ) + { + dataSingular.Remove( t ); + dataMultiple.Add( t, new List { obj, val } ); + } + else + dataSingular.Add( t, val ); } public bool Contains() { - return innerInherit[ typeof( T ) ].Count != 0; + return dataSingular.ContainsKey( typeof( T ) ) || dataMultiple.ContainsKey( typeof( T ) ); } public T Get() { - var l = innerInherit[typeof(T)]; - if (l.Count == 1) - return (T)l[0]; - else if (l.Count == 0) + if( dataMultiple.ContainsKey( typeof( T ) ) ) + throw new InvalidOperationException( string.Format( "TypeDictionary contains multiple instance of type `{0}`", typeof( T ) ) ); + + object ret; + if( !dataSingular.TryGetValue( typeof( T ), out ret ) ) throw new InvalidOperationException(string.Format("TypeDictionary does not contain instance of type `{0}`", typeof(T))); - else - throw new InvalidOperationException(string.Format("TypeDictionary contains multiple instance of type `{0}`", typeof(T))); + return (T)ret; } - + public T GetOrDefault() { - var l = innerInherit[ typeof( T ) ]; - if( l.Count == 1 ) - return (T)l[ 0 ]; - else if( l.Count == 0 ) - return default( T ); - else + if( dataMultiple.ContainsKey( typeof( T ) ) ) throw new InvalidOperationException( string.Format( "TypeDictionary contains multiple instance of type `{0}`", typeof( T ) ) ); + + object ret; + if( !dataSingular.TryGetValue( typeof( T ), out ret ) ) + return default( T ); + return (T)ret; } public IEnumerable WithInterface() { - foreach( var i in innerInherit[ typeof( T ) ] ) - yield return (T)i; + List objs; + object obj; + + if( dataMultiple.TryGetValue( typeof( T ), out objs ) ) + return objs.Cast(); + else if( dataSingular.TryGetValue( typeof( T ), out obj ) ) + return new T[] { (T)obj }; + else + return new T[ 0 ]; } public IEnumerator GetEnumerator()