anx.framework/ANX.Framework/NonXNA/AddInSystemFactory.cs
SND\AstrorEnales_cp ef734ddcd3 Implemented the MediaPlayer and MediaQueue classes as preparation for native Song playback.
Also added the FrameworkDispatcher calls in the Game class.
Checking for possible fire and forget sound instances to be disposed in the FrameworkDispatcher update chain.
2015-03-15 01:11:17 +01:00

255 lines
6.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using ANX.Framework.NonXNA.PlatformSystem;
using ANX.Framework.NonXNA.Reflection;
using ANX.Framework.NonXNA.SoundSystem;
// 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),
};
#endregion
#region Private
private Dictionary<string, ICreator> creators;
private static AddInSystemFactory instance;
private bool initialized;
private Dictionary<AddInType, AddInTypeCollection> addInSystems;
#endregion
#region Public
public static AddInSystemFactory Instance
{
get
{
if (instance == null)
{
instance = new AddInSystemFactory();
Logger.Info("Created AddInSystemFactory instance");
}
return instance;
}
}
#endregion
#region Constructor
private AddInSystemFactory()
{
creators = new Dictionary<string, ICreator>();
addInSystems = new Dictionary<AddInType, AddInTypeCollection>();
foreach (AddInType type in Enum.GetValues(typeof(AddInType)))
addInSystems.Add(type, new AddInTypeCollection());
}
#endregion
#region Initialize
public void Initialize()
{
if (initialized)
return;
initialized = true;
Logger.Info("[ANX] Initializing ANX.Framework AddInSystemFactory...");
CreateAllAddIns();
SortAddIns();
}
#endregion
#region CreateAllAddIns
private void CreateAllAddIns()
{
foreach (Type creatorType in AssemblyLoader.CreatorTypes)
{
Type matchingSupportedPlatformsType = FindSupportedPlatformsTypeByNamespace(creatorType);
if (matchingSupportedPlatformsType == null)
matchingSupportedPlatformsType = FindSupportedPlatformsTypeByAssembly(creatorType);
AddIn addin = new AddIn(creatorType, matchingSupportedPlatformsType);
if (addin.IsSupported)
{
addInSystems[addin.Type].Add(addin);
Logger.Info("[ANX] successfully loaded AddIn (" + addin.Type + ") " + creatorType.FullName + ".");
}
else
Logger.Info("[ANX] skipped loading file because it is not supported or not a valid AddIn.");
}
}
#endregion
#region FindSupportedPlatformsTypeByNamespace
private Type FindSupportedPlatformsTypeByNamespace(Type creatorType)
{
foreach (Type spType in AssemblyLoader.SupportedPlatformsTypes)
if (spType.Namespace == creatorType.Namespace)
return spType;
return null;
}
#endregion
#region FindSupportedPlatformsTypeByAssembly
private Type FindSupportedPlatformsTypeByAssembly(Type creatorType)
{
foreach (Type spType in AssemblyLoader.SupportedPlatformsTypes)
if (TypeHelper.GetAssemblyFrom(spType) == TypeHelper.GetAssemblyFrom(creatorType))
return spType;
return null;
}
#endregion
#region AddCreator
internal 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<T>(string name) where T : class, ICreator
{
Initialize();
if (creators.ContainsKey(name.ToLowerInvariant()))
return creators[name.ToLowerInvariant()] as T;
return null;
}
#endregion
#region GetCreators
public IEnumerable<T> GetCreators<T>() 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 GetAvailableCreators
public IEnumerable<T> GetAvailableCreators<T>() where T : class, ICreator
{
AddInType type = GetAddInType(typeof(T));
if (type != AddInType.Unknown)
{
AddInTypeCollection addIns = addInSystems[type];
foreach (AddIn addIn in addIns)
{
T instance = addIn.Instance as T;
if (instance != null && instance.IsSupported)
{
yield return instance;
}
}
}
else
{
throw new Exception("couldn't resolve AddInType of '" + typeof(T).FullName + "'");
}
}
#endregion
#region GetDefaultCreator
public T GetDefaultCreator<T>() where T : class, ICreator
{
Initialize();
AddInType addInType = GetAddInType(typeof(T));
return addInSystems[addInType].GetDefaultCreator<T>(addInType);
}
#endregion
#region SortAddIns
public void SortAddIns()
{
foreach (AddInTypeCollection info in addInSystems.Values)
info.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].Lock();
}
#endregion
#region GetAddInType
internal static AddInType GetAddInType(Type t)
{
foreach (Type creatorType in ValidAddInCreators)
{
if (TypeHelper.IsTypeAssignableFrom(creatorType, t))
{
string addInTypeName = creatorType.Name.Substring(1, creatorType.Name.Length - 8);
return (AddInType)Enum.Parse(typeof(AddInType), addInTypeName);
}
}
return AddInType.Unknown;
}
#endregion
}
}