remove the IEmulatorService requirement from IEmulatorServiceProvider and BasicServiceProvider

This commit is contained in:
goyuken 2014-12-15 21:35:09 +00:00
parent ba6f740382
commit b23294a68f
2 changed files with 25 additions and 77 deletions

View File

@ -8,54 +8,29 @@ namespace BizHawk.Emulation.Common
{ {
public class BasicServiceProvider : IEmulatorServiceProvider public class BasicServiceProvider : IEmulatorServiceProvider
{ {
private Dictionary<Type, IEmulatorService> Services = new Dictionary<Type, IEmulatorService>(); private Dictionary<Type, object> Services = new Dictionary<Type, object>();
public BasicServiceProvider(IEmulator core) public BasicServiceProvider(IEmulator core)
{ {
var services = Assembly // simplified logic here doesn't scan for possible services; just adds what it knows is implemented by the core
.GetAssembly(typeof(IEmulator)) // this removes the possibility of automagically picking up a service in a nested class, (find the type, then
.GetTypes() // find the field), but we're going to keep such logic out of the basic provider. anything the passed
.Where(t => t.IsInterface) // core doesn't implement directly needs to be added with Register()
.Where(t => typeof(IEmulatorService).IsAssignableFrom(t))
.Where(t => t != typeof(IEmulatorService))
.ToList();
var coreType = core.GetType(); // this also fully allows services that are not IEmulatorService
foreach (var service in services) Type coreType = core.GetType();
{
if (service.IsAssignableFrom(coreType))
{
Services.Add(service, core);
}
}
// Add the core itself since we know a core implements IEmulatorService foreach (Type service in coreType.GetInterfaces())
Services.Add(core.GetType(), core);
// Any IEmulatorServices the core might have that are core specific (and therefore not in Emulation.Common)
var coreSpecificServices = core
.GetType()
.GetInterfaces()
.Where(i => !services.Contains(i))
.Where(t => typeof(IEmulatorService).IsAssignableFrom(t))
.Where(t => !t.FullName.Contains("ISettable")) // adelikat: TODO: Hack! but I need a way around this, every core implements their own specific ISettable
.ToList();
foreach (var service in coreSpecificServices)
{ {
Services.Add(service, core); Services.Add(service, core);
} }
foreach (var service in core.GetType().GetNestedTypes(BindingFlags.Public) // add the actual instantiated type and any types in the hierarchy
.Where(t => typeof(IEmulatorService).IsAssignableFrom(t)) while (coreType != null)
.Where(t => t.IsClass))
{ {
if (service.IsAssignableFrom(coreType)) Services.Add(coreType, core);
{ coreType = coreType.BaseType;
// TODO: get the instance from the core
//Services.Add(service, core);
}
} }
} }
@ -65,62 +40,34 @@ namespace BizHawk.Emulation.Common
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
/// <param name="provider"></param> /// <param name="provider"></param>
public void Register<T>(T provider) public void Register<T>(T provider)
where T : IEmulatorService
{ {
if (provider == null) if (provider == null)
throw new ArgumentNullException("provider"); throw new ArgumentNullException("provider");
Services[typeof(T)] = provider; Services[typeof(T)] = provider;
} }
public IEmulatorService GetService<T>() public T GetService<T>()
where T : IEmulatorService
{ {
IEmulatorService service; return (T)GetService(typeof(T));
if (Services.TryGetValue(typeof(T), out service))
{
return (T)service;
}
else
{
return null;
}
} }
public IEmulatorService GetService(Type t) public object GetService(Type t)
{ {
if (typeof(IEmulatorService).IsAssignableFrom(t)) object service;
{ if (Services.TryGetValue(t, out service))
IEmulatorService service; return service;
if (Services.TryGetValue(t, out service))
return service;
else
return null;
}
else else
{ return null;
throw new Exception(String.Format("Type {0} does not implement IEmulatorService.", t.Name));
}
} }
public bool HasService<T>() public bool HasService<T>()
where T : IEmulatorService
{ {
IEmulatorService service; return HasService(typeof(T));
return Services.TryGetValue(typeof(T), out service);
} }
public bool HasService(Type t) public bool HasService(Type t)
{ {
if (typeof(IEmulatorService).IsAssignableFrom(t)) return Services.ContainsKey(t);
{
IEmulatorService service;
return Services.TryGetValue(t, out service);
}
else
{
throw new Exception(String.Format("Type {0} does not implement IEmulatorService.", t.Name));
}
} }
} }
} }

View File

@ -1,4 +1,5 @@
using System; using System;
namespace BizHawk.Emulation.Common namespace BizHawk.Emulation.Common
{ {
public interface IEmulatorServiceProvider public interface IEmulatorServiceProvider
@ -6,7 +7,7 @@ namespace BizHawk.Emulation.Common
/// <summary> /// <summary>
/// Returns whether or not T is available /// Returns whether or not T is available
/// </summary> /// </summary>
bool HasService<T>() where T : IEmulatorService; bool HasService<T>();
/// <summary> /// <summary>
/// Returns whether or not t is available /// Returns whether or not t is available
@ -17,12 +18,12 @@ namespace BizHawk.Emulation.Common
/// Returns an instance of T if T is available /// Returns an instance of T if T is available
/// Else returns null /// Else returns null
/// </summary> /// </summary>
IEmulatorService GetService<T>() where T : IEmulatorService; T GetService<T>();
/// <summary> /// <summary>
/// Returns an instance of t if t is available /// Returns an instance of t if t is available
/// Else returns null /// Else returns null
/// </summary> /// </summary>
IEmulatorService GetService(Type t); object GetService(Type t);
} }
} }