BITKit/Packages/Core/SubSystem/SubBITSystem.cs

137 lines
4.7 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Reflection;
using System.Linq;
using Cysharp.Threading.Tasks;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Threading;
namespace BITKit.SubSystems
{
[AttributeUsage(System.AttributeTargets.Class)]
public sealed class SubSystemConfigAttribute : Attribute
{
public bool isMainThread = false;
}
public interface IBITSubSystem
{
string GetName();
void RuntimeInitialize();
void OnCreate();
void OnDestory();
void OnStart();
void OnUpdate(float deltaTime);
void OnFixedUpdate(float deltaTime);
}
public abstract class SubBITSystem : IBITSubSystem
{
public virtual string GetName() { return GetType().Name; }
public virtual void RuntimeInitialize() { }
public virtual void OnCreate() { }
public virtual void OnDestory() { }
public virtual void OnStart() { }
public virtual void OnUpdate(float deltaTime) { }
public virtual void OnFixedUpdate(float deltaTime) { }
}
public class BITSystems
{
public static InitializationState State;
static ConcurrentDictionary<Type, IBITSubSystem> dictionary = new();
public static T GetOrCreate<T>() where T : IBITSubSystem
{
lock (dictionary)
{
var system = GetOrCreate(typeof(T));
if (system is T subSystem)
{
return subSystem;
}
else
{
throw new NullReferenceException();
}
}
}
public static IBITSubSystem GetOrCreate(Type type)
{
lock (dictionary)
{
if (dictionary.TryGetValue(type, out var subSystem))
{
}
else
{
subSystem = dictionary.GetOrAdd(type, Create(type));
}
IBITSubSystem Create(Type type)
{
var config = type.GetCustomAttribute<SubSystemConfigAttribute>() ?? new();
var subSystem = Activator.CreateInstance(type) as IBITSubSystem;
//ITicker ticker = DI.GetOrCreate<ThreadHelper>();
ITicker ticker = config.isMainThread ? DI.Get<IMainTicker>() : DI.Get<IThreadTicker>();
DI.Register(type, subSystem);
ticker.Add(subSystem.OnCreate);
ticker.Add(subSystem.OnStart);
ticker.AddUpdate(subSystem.OnUpdate);
ticker.AddFixedUpdate(subSystem.OnFixedUpdate);
BIT4Log.Log<BITSystems>($"已创建子系统:{subSystem.GetName()}");
dictionary.AddOrUpdate(type, subSystem, (x, y) => subSystem);
return subSystem;
}
return subSystem;
}
}
public static IEnumerable<IBITSubSystem> GetAllInstance()
{
return dictionary.Values.Select(x => x as IBITSubSystem);
}
public static void Reload()
{
State = 0;
dictionary.Clear();
}
}
public static class SubSystemManager
{
[ExcuteOnStop]
public static async void Stop()
{
foreach (var subSystem in BITSystems.GetAllInstance())
{
subSystem.OnDestory();
}
await UniTask.Yield();
BITSystems.Reload();
}
[ExcuteOnStart]
public static async void Init()
{
BIT4Log.Log<BITSystems>("正在初始化子系统");
BITSystems.State = InitializationState.Initializing;
await UniTask.SwitchToThreadPool();
BIT4Log.Log<BITSystems>("正在加载计时器");
Stopwatch stopwatch = new();
stopwatch.Start();
try
{
BIT4Log.Log<BITSystems>("正在等待加载反射类型");
var types = await ReflectionHelper.GetTypes<SubSystems.IBITSubSystem>();
BIT4Log.Log<BITSystems>("已获取所有反射类型");
foreach (var item in types)
{
BITSystems.GetOrCreate(item);
}
}
catch (System.Exception e)
{
BIT4Log.LogException(e);
}
BITSystems.State = InitializationState.Initialized;
stopwatch.Stop();
BIT4Log.Log<BITSystems>($"初始化耗时:{stopwatch.ElapsedMilliseconds}ms");
}
}
}