using System;
using System.Linq;
using BizHawk.Common.ReflectionExtensions;
namespace BizHawk.Client.ApiHawk
{
///
/// injects Apis into other classes
///
public static class ApiInjector
{
///
/// clears all Apis from a target
///
public static void ClearApis(object target)
{
Type targetType = target.GetType();
object[] tmp = new object[1];
foreach (var propinfo in
targetType.GetPropertiesWithAttrib(typeof(RequiredApiAttribute))
.Concat(targetType.GetPropertiesWithAttrib(typeof(OptionalApiAttribute))))
{
propinfo.GetSetMethod(true).Invoke(target, tmp);
}
}
///
/// Feeds the target its required Apis.
///
/// false if update failed
public static bool UpdateApis(IExternalApiProvider source, object target)
{
Type targetType = target.GetType();
object[] tmp = new object[1];
foreach (var propinfo in targetType.GetPropertiesWithAttrib(typeof(RequiredApiAttribute)))
{
tmp[0] = source.GetApi(propinfo.PropertyType);
if (tmp[0] == null)
{
return false;
}
propinfo.GetSetMethod(true).Invoke(target, tmp);
}
foreach (var propinfo in targetType.GetPropertiesWithAttrib(typeof(OptionalApiAttribute)))
{
tmp[0] = source.GetApi(propinfo.PropertyType);
propinfo.GetSetMethod(true).Invoke(target, tmp);
}
return true;
}
///
/// Determines whether a target is available, considering its dependencies
/// and the Apis provided by the emulator core.
///
public static bool IsAvailable(IExternalApiProvider source, Type targetType)
{
return targetType.GetPropertiesWithAttrib(typeof(RequiredApiAttribute))
.Select(pi => pi.PropertyType)
.All(source.HasApi);
}
}
[AttributeUsage(AttributeTargets.Property)]
public class RequiredApiAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Property)]
public class OptionalApiAttribute : Attribute
{
}
}