#region Copyright & License Information /* * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, * see COPYING. */ #endregion using System; using System.Collections; using System.Collections.Generic; using System.Linq; namespace OpenRA.FileFormats { public class TypeDictionary : IEnumerable { Dictionary dataSingular = new Dictionary(); Dictionary> dataMultiple = new Dictionary>(); public void Add( object val ) { var t = val.GetType(); foreach( var i in t.GetInterfaces() ) InnerAdd( i, val ); foreach( var tt in t.BaseTypes() ) 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 dataSingular.ContainsKey(typeof(T)) || dataMultiple.ContainsKey(typeof(T)); } public T Get() { if (dataMultiple.ContainsKey(typeof(T))) throw new InvalidOperationException("TypeDictionary contains multiple instance of type `{0}`".F(typeof(T))); object ret; if (!dataSingular.TryGetValue(typeof(T), out ret)) throw new InvalidOperationException("TypeDictionary does not contain instance of type `{0}`".F(typeof(T))); return (T)ret; } public T GetOrDefault() { return (T)GetOrDefault(typeof(T)); } public object GetOrDefault(Type t) { if (dataMultiple.ContainsKey(t)) throw new InvalidOperationException("TypeDictionary contains multiple instances of type `{0}`".F(t)); object ret; if (!dataSingular.TryGetValue(t, out ret)) return null; return ret; } public IEnumerable WithInterface() { 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() { return WithInterface().GetEnumerator(); } } public static class TypeExts { public static IEnumerable BaseTypes( this Type t ) { while( t != null ) { yield return t; t = t.BaseType; } } } }