feat(UXAssist): public ModFeature lifecycle registry

This commit is contained in:
2026-06-23 02:18:32 +08:00
parent bfe0787923
commit cb7a965d12
4 changed files with 109 additions and 0 deletions
@@ -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;
}
}