mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-14 16:51:28 +00:00
[+] TEngineServer
[+] TEngineServer
This commit is contained in:
8
Assets/GameScripts/DotNet/Core/Singleton/Interface.meta
Normal file
8
Assets/GameScripts/DotNet/Core/Singleton/Interface.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 12455eea4412a9e468f0a3a4cc929a78
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TEngine.Core
|
||||
{
|
||||
public interface ISingleton : IDisposable
|
||||
{
|
||||
public bool IsDisposed { get; set; }
|
||||
public Task Initialize();
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 74fd4adc991154043a4cb8a74e974c55
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,7 @@
|
||||
namespace TEngine.Core
|
||||
{
|
||||
public interface IUpdateSingleton : ISingleton
|
||||
{
|
||||
public abstract void Update();
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1cacc43db095ef646b8e9894d0da431b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
37
Assets/GameScripts/DotNet/Core/Singleton/Singleton.cs
Normal file
37
Assets/GameScripts/DotNet/Core/Singleton/Singleton.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System.Threading.Tasks;
|
||||
#pragma warning disable CS8601
|
||||
#pragma warning disable CS8618
|
||||
|
||||
namespace TEngine.Core
|
||||
{
|
||||
public abstract class Singleton<T> : ISingleton where T : ISingleton, new()
|
||||
{
|
||||
public bool IsDisposed { get; set; }
|
||||
|
||||
public static T Instance { get; private set; }
|
||||
|
||||
private void RegisterSingleton(ISingleton singleton)
|
||||
{
|
||||
Instance = (T) singleton;
|
||||
AssemblyManager.OnLoadAssemblyEvent += OnLoad;
|
||||
AssemblyManager.OnUnLoadAssemblyEvent += OnUnLoad;
|
||||
}
|
||||
|
||||
public virtual Task Initialize()
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
protected virtual void OnLoad(int assemblyName) { }
|
||||
|
||||
protected virtual void OnUnLoad(int assemblyName) { }
|
||||
|
||||
public virtual void Dispose()
|
||||
{
|
||||
IsDisposed = true;
|
||||
Instance = default;
|
||||
AssemblyManager.OnLoadAssemblyEvent -= OnLoad;
|
||||
AssemblyManager.OnUnLoadAssemblyEvent -= OnUnLoad;
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/GameScripts/DotNet/Core/Singleton/Singleton.cs.meta
Normal file
11
Assets/GameScripts/DotNet/Core/Singleton/Singleton.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0b54004d9250cf744a5b58a655d7f4d5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
132
Assets/GameScripts/DotNet/Core/Singleton/SingletonSystem.cs
Normal file
132
Assets/GameScripts/DotNet/Core/Singleton/SingletonSystem.cs
Normal file
@@ -0,0 +1,132 @@
|
||||
// ReSharper disable StaticMemberInGenericType
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using TEngine.DataStructure;
|
||||
#pragma warning disable CS8601
|
||||
#pragma warning disable CS8604
|
||||
#pragma warning disable CS8600
|
||||
|
||||
namespace TEngine.Core
|
||||
{
|
||||
public static class SingletonSystem
|
||||
{
|
||||
private static readonly Queue<IUpdateSingleton> Updates = new Queue<IUpdateSingleton>();
|
||||
private static readonly OneToManyQueue<int, ISingleton> Singletons = new OneToManyQueue<int, ISingleton>();
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
AssemblyManager.OnLoadAssemblyEvent += Load;
|
||||
AssemblyManager.OnUnLoadAssemblyEvent += UnLoad;
|
||||
}
|
||||
|
||||
private static void Load(int assemblyName)
|
||||
{
|
||||
var count = 0;
|
||||
var task = new List<Task>();
|
||||
|
||||
UnLoad(assemblyName);
|
||||
|
||||
foreach (var singletonType in AssemblyManager.ForEach(assemblyName, typeof(ISingleton)))
|
||||
{
|
||||
var instance = (ISingleton) Activator.CreateInstance(singletonType);
|
||||
var registerMethodInfo = singletonType.BaseType?.GetMethod("RegisterSingleton", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
var initializeMethodInfo = singletonType.GetMethod("Initialize", BindingFlags.Instance | BindingFlags.Public);
|
||||
var onLoadMethodInfo = singletonType.GetMethod("OnLoad", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
|
||||
if (initializeMethodInfo != null)
|
||||
{
|
||||
task.Add((Task) initializeMethodInfo.Invoke(instance, null));
|
||||
}
|
||||
|
||||
registerMethodInfo?.Invoke(instance, new object[] {instance});
|
||||
onLoadMethodInfo?.Invoke(instance, new object[] {assemblyName});
|
||||
|
||||
count++;
|
||||
|
||||
switch (instance)
|
||||
{
|
||||
case IUpdateSingleton iUpdateSingleton:
|
||||
{
|
||||
Updates.Enqueue(iUpdateSingleton);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Singletons.Enqueue(assemblyName, instance);
|
||||
}
|
||||
|
||||
Task.WaitAll(task.ToArray());
|
||||
Log.Info($"assembly:{assemblyName} load Singleton count:{count}");
|
||||
}
|
||||
|
||||
private static void UnLoad(Queue<ISingleton> singletons)
|
||||
{
|
||||
while (singletons.Count > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
singletons.Dequeue().Dispose();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void UnLoad(int assemblyName)
|
||||
{
|
||||
if (!Singletons.TryGetValue(assemblyName, out var singletons))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var count = singletons.Count;
|
||||
UnLoad(singletons);
|
||||
Singletons.RemoveKey(assemblyName);
|
||||
// Log.Info($"assembly:{assemblyName} Unload Singleton count:{count}");
|
||||
}
|
||||
|
||||
public static void Update()
|
||||
{
|
||||
var updatesCount = Updates.Count;
|
||||
|
||||
while (updatesCount-- > 0)
|
||||
{
|
||||
var updateSingleton = Updates.Dequeue();
|
||||
|
||||
if (updateSingleton.IsDisposed)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Updates.Enqueue(updateSingleton);
|
||||
|
||||
try
|
||||
{
|
||||
updateSingleton.Update();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Dispose()
|
||||
{
|
||||
foreach (var (_, singletons) in Singletons)
|
||||
{
|
||||
UnLoad(singletons);
|
||||
}
|
||||
|
||||
Updates.Clear();
|
||||
Singletons.Clear();
|
||||
AssemblyManager.OnLoadAssemblyEvent -= Load;
|
||||
AssemblyManager.OnUnLoadAssemblyEvent -= UnLoad;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 31f7155596debed429793d1d408935d7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user