using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using ANX.Framework.NonXNA.PlatformSystem; using ANX.Framework.NonXNA.Reflection; // This file is part of the ANX.Framework created by the // "ANX.Framework developer group" and released under the Ms-PL license. // For details see: http://anxframework.codeplex.com/license namespace ANX.Framework.NonXNA { public class AddInSystemFactory { #region Constants internal static readonly Type[] ValidAddInCreators = { typeof(IInputSystemCreator), typeof(IRenderSystemCreator), typeof(ISoundSystemCreator), typeof(IMediaSystemCreator), typeof(IPlatformSystemCreator), }; #endregion #region Private private Dictionary creators; private static AddInSystemFactory instance; private bool initialized; private Dictionary defaultCreators; private Dictionary addinSystems; #endregion #region Public public static AddInSystemFactory Instance { get { if (instance == null) { instance = new AddInSystemFactory(); Logger.Info("Created AddInSystemFactory instance"); } return instance; } } internal static IPlatformSystemCreator DefaultPlatformCreator { get { return Instance.GetDefaultCreator(); } } #endregion #region Constructor private AddInSystemFactory() { defaultCreators = new Dictionary(); creators = new Dictionary(); addinSystems = new Dictionary(); addinSystems.Add(AddInType.InputSystem, new AddInTypeCollection()); addinSystems.Add(AddInType.MediaSystem, new AddInTypeCollection()); addinSystems.Add(AddInType.RenderSystem, new AddInTypeCollection()); addinSystems.Add(AddInType.SoundSystem, new AddInTypeCollection()); addinSystems.Add(AddInType.PlatformSystem, new AddInTypeCollection()); Logger.Info("Operating System: {0} ({1})", OSInformation.GetVersionString(), OSInformation.GetVersion().ToString()); } #endregion #region Initialize public void Initialize() { if (initialized == false) { initialized = true; Logger.Info("[ANX] Initializing ANX.Framework AddInSystemFactory..."); CreateAllAddIns(); SortAddIns(); } } #endregion #region CreateAllAddIns private void CreateAllAddIns() { Assembly[] allAssemblies = AssemblyLoader.GetAllAssemblies(); foreach (Assembly assembly in allAssemblies) { AddIn addin = new AddIn(assembly); if (addin.IsValid && addin.IsSupported) { addinSystems[addin.Type].AvailableSystems.Add(addin); Logger.Info("[ANX] successfully loaded addin..."); } else { Logger.Info("[ANX] skipped loading file because it is not supported or not a valid AddIn"); } } } #endregion #region AddCreator public void AddCreator(ICreator creator) { string creatorName = creator.Name.ToLowerInvariant(); if (creators.ContainsKey(creatorName)) { throw new Exception("Duplicate creator found. A creator with the name '" + creator.Name + "' was already registered."); } creators.Add(creatorName, creator); Logger.Info("added creator '{0}'. Total count of registered creators is now {1}.", creatorName, creators.Count); } #endregion #region HasFramework public bool HasFramework(String name) { return creators.ContainsKey(name.ToLowerInvariant()); } #endregion #region GetCreator public T GetCreator(String name) where T : class, ICreator { Initialize(); ICreator creator = null; creators.TryGetValue(name.ToLowerInvariant(), out creator); return creator as T; } #endregion #region GetCreators public IEnumerable GetCreators() where T : class, ICreator { Initialize(); foreach (ICreator creator in creators.Values) { Type[] interfaces = TypeHelper.GetInterfacesFrom(creator.GetType()); foreach (Type t in interfaces) { if (t.Name.Equals( typeof(T).Name )) { yield return creator as T; } } } } #endregion #region GetDefaultCreator public T GetDefaultCreator() where T : class, ICreator { Initialize(); AddInType addInType = GetAddInType(typeof(T)); AddInTypeCollection info = addinSystems[addInType]; if (String.IsNullOrEmpty(info.PreferredName)) { if (info.AvailableSystems.Count > 0) { return info.AvailableSystems[0].Instance as T; } throw new AddInLoadingException(String.Format( "Couldn't get default {0} because there are no " + "registered {0}s available! Make sure you referenced a {0} library " + "in your project or one is laying in your output folder!", addInType)); } else { foreach (AddIn addin in info.AvailableSystems) { if (addin.Name.Equals(info.PreferredName, StringComparison.CurrentCultureIgnoreCase)) { return addin.Instance as T; } } throw new AddInLoadingException(String.Format( "Couldn't get default {0} '{1}' because it was not found in the " + "list of registered creators!", addInType, info.PreferredName)); } throw new AddInLoadingException(String.Format( "Couldn't find a DefaultCreator of type '{0}'!", typeof(T).FullName)); } #endregion #region SortAddIns public void SortAddIns() { foreach (AddInTypeCollection info in addinSystems.Values) { info.AvailableSystems.Sort(); } creators = creators.OrderBy(x => x.Value.Priority).ToDictionary( x => x.Key, x => x.Value); } #endregion #region GetPreferredSystem public string GetPreferredSystem(AddInType addInType) { return addinSystems[addInType].PreferredName; } #endregion #region SetPreferredSystem public void SetPreferredSystem(AddInType addInType, string preferredName) { if (addinSystems[addInType].PreferredLocked) { throw new AddInLoadingException(String.Format( "Can't set preferred {0} because a {0} is alread in use.", addInType)); } addinSystems[addInType].PreferredName = preferredName; } #endregion #region PreventSystemChange public void PreventSystemChange(AddInType addInType) { addinSystems[addInType].PreferredLocked = true; } #endregion #region GetAddInType internal static AddInType GetAddInType(Type t) { foreach (Type creatorType in ValidAddInCreators) { if (TypeHelper.IsTypeAssignableFrom(creatorType, t)) { return (AddInType)Enum.Parse(typeof(AddInType), creatorType.Name.Substring(1, creatorType.Name.Length - 8)); } } return AddInType.Unknown; } #endregion } }