mirror of
https://github.com/soarqin/DSP_Mods.git
synced 2026-08-05 10:00:21 +08:00
feat(UXAssist): public ModFeature lifecycle registry
This commit is contained in:
@@ -0,0 +1,10 @@
|
|||||||
|
namespace UXAssist.Common.ModFeatures;
|
||||||
|
|
||||||
|
public interface IModFeature
|
||||||
|
{
|
||||||
|
void Init();
|
||||||
|
void Start();
|
||||||
|
void Uninit();
|
||||||
|
void OnInputUpdate();
|
||||||
|
void OnUpdate();
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace UXAssist.Common.ModFeatures;
|
||||||
|
|
||||||
|
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
|
||||||
|
public sealed class ModFeatureAttribute : Attribute
|
||||||
|
{
|
||||||
|
public string Name { get; }
|
||||||
|
public int Order { get; set; }
|
||||||
|
|
||||||
|
public ModFeatureAttribute(string name = null)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace UXAssist.Common.ModFeatures;
|
||||||
|
|
||||||
|
public static class ModFeatureRegistry
|
||||||
|
{
|
||||||
|
private static readonly List<Type> _staticFeatures = [];
|
||||||
|
private static readonly List<IModFeature> _instanceFeatures = [];
|
||||||
|
private static readonly HashSet<Assembly> _discoveredAssemblies = [];
|
||||||
|
|
||||||
|
public static void Discover(Assembly assembly)
|
||||||
|
{
|
||||||
|
if (!_discoveredAssemblies.Add(assembly)) return;
|
||||||
|
|
||||||
|
var staticTypes = Util.GetTypesFiltered(assembly, t =>
|
||||||
|
t.IsClass && t.IsAbstract && t.IsSealed &&
|
||||||
|
Attribute.IsDefined(t, typeof(ModFeatureAttribute)));
|
||||||
|
|
||||||
|
foreach (var type in staticTypes.OrderBy(GetOrder))
|
||||||
|
{
|
||||||
|
if (!_staticFeatures.Contains(type))
|
||||||
|
_staticFeatures.Add(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Register<T>() where T : class, IModFeature, new()
|
||||||
|
{
|
||||||
|
var instance = new T();
|
||||||
|
_instanceFeatures.Add(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void InitAll()
|
||||||
|
{
|
||||||
|
ForEachStatic("Init");
|
||||||
|
foreach (var f in _instanceFeatures) f.Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void StartAll()
|
||||||
|
{
|
||||||
|
ForEachStatic("Start");
|
||||||
|
foreach (var f in _instanceFeatures) f.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UninitAll()
|
||||||
|
{
|
||||||
|
ForEachStatic("Uninit");
|
||||||
|
foreach (var f in _instanceFeatures) f.Uninit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void OnInputUpdateAll()
|
||||||
|
{
|
||||||
|
ForEachStatic("OnInputUpdate");
|
||||||
|
foreach (var f in _instanceFeatures) f.OnInputUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void OnUpdateAll()
|
||||||
|
{
|
||||||
|
ForEachStatic("OnUpdate");
|
||||||
|
foreach (var f in _instanceFeatures) f.OnUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ForEachStatic(string methodName)
|
||||||
|
{
|
||||||
|
foreach (var type in _staticFeatures)
|
||||||
|
{
|
||||||
|
var method = type.GetMethod(methodName,
|
||||||
|
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
|
||||||
|
method?.Invoke(null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int GetOrder(Type type)
|
||||||
|
{
|
||||||
|
return type.GetCustomAttribute<ModFeatureAttribute>()?.Order ?? 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,6 +15,11 @@ public static class Util
|
|||||||
|
|
||||||
public static Type[] GetTypesInNamespace(Assembly assembly, string nameSpace) => GetTypesFiltered(assembly, t => string.Equals(t.Namespace, nameSpace, StringComparison.Ordinal));
|
public static Type[] GetTypesInNamespace(Assembly assembly, string nameSpace) => GetTypesFiltered(assembly, t => string.Equals(t.Namespace, nameSpace, StringComparison.Ordinal));
|
||||||
|
|
||||||
|
public static Type[] GetTypesInNamespacePrefix(Assembly assembly, string prefix)
|
||||||
|
{
|
||||||
|
return GetTypesFiltered(assembly, t => t.Namespace != null && t.Namespace.StartsWith(prefix, StringComparison.Ordinal));
|
||||||
|
}
|
||||||
|
|
||||||
public static byte[] LoadEmbeddedResource(string path, Assembly assembly = null)
|
public static byte[] LoadEmbeddedResource(string path, Assembly assembly = null)
|
||||||
{
|
{
|
||||||
if (assembly == null)
|
if (assembly == null)
|
||||||
|
|||||||
Reference in New Issue
Block a user