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 { } }