提交修改

This commit is contained in:
Bob.Song
2025-10-29 17:59:36 +08:00
parent b390cf2051
commit 5750c4fe56
2148 changed files with 13962 additions and 5549 deletions

View File

@@ -1,15 +0,0 @@
namespace NBC
{
internal interface ISceneUpdate
{
void Update();
}
internal sealed class EmptySceneUpdate : ISceneUpdate
{
public void Update()
{
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 459c867d43e7443cd8e9b181b1f61b8c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,399 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NBC.Scheduler;
using NBC.Async;
using NBC.Entitas;
using NBC.Event;
using NBC.IdFactory;
using NBC.Network;
using NBC.Network.Interface;
using NBC.Pool;
// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
#pragma warning disable CS8601 // Possible null reference assignment.
#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
#pragma warning disable CS8603 // Possible null reference return.
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
#pragma warning disable CS8602 // Dereference of a possibly null reference.
#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type.
namespace NBC
{
/// <summary>
/// 当Scene创建完成后发送的事件参数
/// </summary>
public struct OnCreateScene
{
/// <summary>
/// 获取与事件关联的场景实体。
/// </summary>
public readonly Scene Scene;
/// <summary>
/// 初始化一个新的 OnCreateScene 实例。
/// </summary>
/// <param name="scene"></param>
public OnCreateScene(Scene scene)
{
Scene = scene;
}
}
/// <summary>
/// 表示一个场景实体,用于创建与管理特定的游戏场景信息。
/// </summary>
public partial class Scene : Entity
{
#region Members
/// <summary>
/// Scene的运行类型
/// </summary>
public SceneRuntimeType SceneRuntimeType { get; protected set; }
/// <summary>
/// 当前Scene的上下文
/// </summary>
public ThreadSynchronizationContext ThreadSynchronizationContext { get; internal set; }
/// <summary>
/// 当前Scene的下创建的Entity
/// </summary>
private readonly Dictionary<long, Entity> _entities = new Dictionary<long, Entity>();
internal readonly Dictionary<Type, Func<IPool>> TypeInstance = new Dictionary<Type, Func<IPool>>();
#endregion
#region IdFactory
/// <summary>
/// Entity实体Id的生成器
/// </summary>
public IEntityIdFactory EntityIdFactory { get; protected set; }
/// <summary>
/// Entity实体RuntimeId的生成器
/// </summary>
public IRuntimeIdFactory RuntimeIdFactory { get; protected set; }
#endregion
#region Pool
internal EntityPool EntityPool;
internal EntityListPool<Entity> EntityListPool;
internal EntitySortedDictionaryPool<long, Entity> EntitySortedDictionaryPool;
#endregion
#region Component
/// <summary>
/// Scene下的任务调度器系统组件
/// </summary>
public TimerComponent TimerComponent { get; internal set; }
/// <summary>
/// Scene下的事件系统组件
/// </summary>
public EventComponent EventComponent { get; internal set; }
/// <summary>
/// Scene下的ESC系统组件
/// </summary>
public EntityComponent EntityComponent { get; internal set; }
/// <summary>
/// Scene下的网络消息对象池组件
/// </summary>
public MessagePoolComponent MessagePoolComponent { get; internal set; }
/// <summary>
/// Scene下的协程锁组件
/// </summary>
public CoroutineLockComponent CoroutineLockComponent { get; internal set; }
/// <summary>
/// Scene下的网络消息派发组件
/// </summary>
internal MessageDispatcherComponent MessageDispatcherComponent { get; set; }
#endregion
#region Initialize
private async FTask Initialize()
{
EntityPool = new EntityPool();
EntityListPool = new EntityListPool<Entity>();
EntitySortedDictionaryPool = new EntitySortedDictionaryPool<long, Entity>();
SceneUpdate = EntityComponent = await Create<EntityComponent>(this, false, false).Initialize();
MessagePoolComponent = Create<MessagePoolComponent>(this, false, true);
EventComponent = await Create<EventComponent>(this, false, true).Initialize();
TimerComponent = Create<TimerComponent>(this, false, true).Initialize();
CoroutineLockComponent = Create<CoroutineLockComponent>(this, false, true).Initialize();
MessageDispatcherComponent = await Create<MessageDispatcherComponent>(this, false, true).Initialize();
}
/// <summary>
/// Scene销毁方法执行了该方法会把当前Scene下的所有实体都销毁掉。
/// </summary>
public override void Dispose()
{
if (IsDisposed)
{
return;
}
base.Dispose();
_entities.Remove(RuntimeId);
switch (SceneRuntimeType)
{
case SceneRuntimeType.Root:
{
_entities.Remove(EntityComponent.RuntimeId);
foreach (var (runtimeId, entity) in _entities.ToList())
{
if (runtimeId != entity.RuntimeId)
{
continue;
}
entity.Dispose();
}
_entities.Clear();
_unityWorldId--;
_unitySceneId--;
TypeInstance.Clear();
EntityComponent.Dispose();
EntityPool.Dispose();
EntityListPool.Dispose();
EntitySortedDictionaryPool.Dispose();
break;
}
case SceneRuntimeType.SubScene:
{
break;
}
default:
{
Log.Error(
$"SceneRuntimeType: {SceneRuntimeType} The unsupported SceneRuntimeType of the Scene executed Dispose.");
break;
}
}
SceneUpdate = null;
EntityIdFactory = null;
RuntimeIdFactory = null;
EntityPool = null;
EntityListPool = null;
EntitySortedDictionaryPool = null;
EntityComponent = null;
TimerComponent = null;
EventComponent = null;
MessagePoolComponent = null;
CoroutineLockComponent = null;
MessageDispatcherComponent = null;
Session = null;
UnityNetwork = null;
ThreadSynchronizationContext = null;
SceneRuntimeType = SceneRuntimeType.None;
}
#endregion
internal ISceneUpdate SceneUpdate { get; set; }
internal void Update()
{
try
{
SceneUpdate.Update();
}
catch (Exception e)
{
Log.Error(e);
}
}
#region Create
private static uint _unitySceneId = 0;
private static byte _unityWorldId = 0;
public Session Session { get; private set; }
private AClientNetwork UnityNetwork { get; set; }
/// <summary>
/// 创建一个Unity的Scene注意:该方法只能在主线程下使用。
/// </summary>
/// <param name="sceneRuntimeMode">选择Scene的运行方式</param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static async FTask<Scene> Create(string sceneRuntimeMode = SceneRuntimeMode.MainThread)
{
var world = ++_unityWorldId;
if (world > byte.MaxValue - 1)
{
throw new Exception($"World ID ({world}) exceeds the maximum allowed value of 255.");
}
var sceneId = (uint)(++_unitySceneId + world * 1000);
if (sceneId > 255255)
{
throw new Exception($"Scene ID ({sceneId}) exceeds the maximum allowed value of 255255.");
}
var scene = new Scene();
scene.Scene = scene;
scene.Parent = scene;
scene.Type = typeof(Scene);
scene.SceneRuntimeType = SceneRuntimeType.Root;
scene.EntityIdFactory = IdFactoryHelper.EntityIdFactory(sceneId, world);
scene.RuntimeIdFactory = IdFactoryHelper.RuntimeIdFactory(0, sceneId, world);
scene.Id = IdFactoryHelper.EntityId(0, sceneId, world, 0);
scene.RuntimeId = IdFactoryHelper.RuntimeId(0, sceneId, world, 0);
scene.AddEntity(scene);
await SetScheduler(scene, sceneRuntimeMode);
scene.ThreadSynchronizationContext.Post(() =>
{
scene.EventComponent.PublishAsync(new OnCreateScene(scene)).Coroutine();
});
return scene;
}
public Session Connect(string remoteAddress, NetworkProtocolType networkProtocolType, Action onConnectComplete,
Action onConnectFail, Action onConnectDisconnect, bool isHttps, int connectTimeout = 5000)
{
UnityNetwork?.Dispose();
UnityNetwork = NetworkProtocolFactory.CreateClient(this, networkProtocolType, NetworkTarget.Outer);
Session = UnityNetwork.Connect(remoteAddress, onConnectComplete, onConnectFail, onConnectDisconnect,
isHttps, connectTimeout);
return Session;
}
private static async FTask SetScheduler(Scene scene, string sceneRuntimeMode)
{
switch (sceneRuntimeMode)
{
case "MainThread":
{
scene.ThreadSynchronizationContext = ThreadScheduler.MainScheduler.ThreadSynchronizationContext;
scene.SceneUpdate = new EmptySceneUpdate();
ThreadScheduler.AddMainScheduler(scene);
await scene.Initialize();
break;
}
case "MultiThread":
{
scene.ThreadSynchronizationContext = new ThreadSynchronizationContext();
scene.SceneUpdate = new EmptySceneUpdate();
ThreadScheduler.AddToMultiThreadScheduler(scene);
await scene.Initialize();
break;
}
case "ThreadPool":
{
scene.ThreadSynchronizationContext = new ThreadSynchronizationContext();
scene.SceneUpdate = new EmptySceneUpdate();
ThreadScheduler.AddToThreadPoolScheduler(scene);
await scene.Initialize();
break;
}
}
}
#endregion
#region Entities
/// <summary>
/// 添加一个实体到当前Scene下
/// </summary>
/// <param name="entity">实体实例</param>
public virtual void AddEntity(Entity entity)
{
_entities.Add(entity.RuntimeId, entity);
}
/// <summary>
/// 根据RunTimeId查询一个实体
/// </summary>
/// <param name="runTimeId">实体的RunTimeId</param>
/// <returns>返回的实体</returns>
public virtual Entity GetEntity(long runTimeId)
{
return _entities.TryGetValue(runTimeId, out var entity) ? entity : null;
}
/// <summary>
/// 根据RunTimeId查询一个实体
/// </summary>
/// <param name="runTimeId">实体的RunTimeId</param>
/// <param name="entity">实体实例</param>
/// <returns>返回一个bool值来提示是否查找到这个实体</returns>
public virtual bool TryGetEntity(long runTimeId, out Entity entity)
{
return _entities.TryGetValue(runTimeId, out entity);
}
/// <summary>
/// 根据RunTimeId查询一个实体
/// </summary>
/// <param name="runTimeId">实体的RunTimeId</param>
/// <typeparam name="T">要查询实体的泛型类型</typeparam>
/// <returns>返回的实体</returns>
public virtual T GetEntity<T>(long runTimeId) where T : Entity
{
return _entities.TryGetValue(runTimeId, out var entity) ? (T)entity : null;
}
/// <summary>
/// 根据RunTimeId查询一个实体
/// </summary>
/// <param name="runTimeId">实体的RunTimeId</param>
/// <param name="entity">实体实例</param>
/// <typeparam name="T">要查询实体的泛型类型</typeparam>
/// <returns>返回一个bool值来提示是否查找到这个实体</returns>
public virtual bool TryGetEntity<T>(long runTimeId, out T entity) where T : Entity
{
if (_entities.TryGetValue(runTimeId, out var getEntity))
{
entity = (T)getEntity;
return true;
}
entity = null;
return false;
}
/// <summary>
/// 删除一个实体,仅是删除不会指定实体的销毁方法
/// </summary>
/// <param name="runTimeId">实体的RunTimeId</param>
/// <returns>返回一个bool值来提示是否删除了这个实体</returns>
public virtual bool RemoveEntity(long runTimeId)
{
return _entities.Remove(runTimeId);
}
/// <summary>
/// 删除一个实体,仅是删除不会指定实体的销毁方法
/// </summary>
/// <param name="entity">实体实例</param>
/// <returns>返回一个bool值来提示是否删除了这个实体</returns>
public virtual bool RemoveEntity(Entity entity)
{
return _entities.Remove(entity.RuntimeId);
}
#endregion
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 968a867914cca474581795824737b521
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,21 +0,0 @@
namespace NBC
{
/// <summary>
/// Scene的运行类型
/// </summary>
public class SceneRuntimeMode
{
/// <summary>
/// Scene在主线程中运行.
/// </summary>
public const string MainThread = "MainThread";
/// <summary>
/// Scene在一个独立的线程中运行.
/// </summary>
public const string MultiThread = "MultiThread";
/// <summary>
/// Scene在一个根据当前CPU核心数创建的线程池中运行.
/// </summary>
public const string ThreadPool = "ThreadPool";
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: b7079cf6927ff4903b7c15488592e6d9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,21 +0,0 @@
namespace NBC
{
/// <summary>
/// 代表一个Scene的类型
/// </summary>
public enum SceneRuntimeType
{
/// <summary>
/// 默认
/// </summary>
None = 0,
/// <summary>
/// 代表一个普通的Scene一个普通的Scene肯定是是Root的
/// </summary>
Root = 1,
/// <summary>
/// 代表一个子场景,子场景肯定是有父场景的
/// </summary>
SubScene = 2,
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: fce1a72d9b59c4611b4355bc1246a582
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 430e21e71c301427fb3a568d44ec6afa
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,11 +0,0 @@
using System;
namespace NBC
{
internal interface ISceneScheduler : IDisposable
{
void Add(Scene scene);
void Remove(Scene scene);
void Update();
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: f39eba01f7f4a4b4eb94287997144b26
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,77 +0,0 @@
using System.Collections.Generic;
using System.Threading;
namespace NBC
{
internal sealed class MainScheduler : ISceneScheduler
{
private readonly Queue<Scene> _queue = new Queue<Scene>();
public readonly ThreadSynchronizationContext ThreadSynchronizationContext;
public MainScheduler()
{
ThreadSynchronizationContext = new ThreadSynchronizationContext();
SynchronizationContext.SetSynchronizationContext(ThreadSynchronizationContext);
}
public void Dispose()
{
_queue.Clear();
}
public void Add(Scene scene)
{
ThreadSynchronizationContext.Post(() =>
{
if (scene.IsDisposed)
{
return;
}
_queue.Enqueue(scene);
});
}
public void Remove(Scene scene)
{
ThreadSynchronizationContext.Post(() =>
{
if (scene.IsDisposed)
{
return;
}
var initialCount = _queue.Count;
for (var i = 0; i < initialCount; i++)
{
var currentScene = _queue.Dequeue();
if (currentScene != scene)
{
_queue.Enqueue(currentScene);
}
}
});
}
public void Update()
{
ThreadSynchronizationContext.Update();
var initialCount = _queue.Count;
while (initialCount-- > 0)
{
if(!_queue.TryDequeue(out var scene))
{
continue;
}
if (scene.IsDisposed)
{
continue;
}
scene.Update();
_queue.Enqueue(scene);
}
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 6c7398438bdaa4c1aa3ae9bd545acc76
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,103 +0,0 @@
#if !FANTASY_WEBGL || !FANTASY_SINGLETHREAD
using System;
using System.Collections.Concurrent;
using System.Threading;
namespace NBC
{
internal struct MultiThreadStruct : IDisposable
{
public readonly Thread Thread;
public readonly CancellationTokenSource Cts;
public MultiThreadStruct(Thread thread, CancellationTokenSource cts)
{
Thread = thread;
Cts = cts;
}
public void Dispose()
{
Cts.Cancel();
if (Thread.IsAlive)
{
Thread.Join();
}
Cts.Dispose();
}
}
internal sealed class MultiThreadScheduler : ISceneScheduler
{
private bool _isDisposed;
private readonly ConcurrentDictionary<long, MultiThreadStruct> _threads = new ConcurrentDictionary<long, MultiThreadStruct>();
public int ThreadCount => _threads.Count;
public void Dispose()
{
if (_isDisposed)
{
return;
}
_isDisposed = true;
foreach (var (_, multiThreadStruct) in _threads.ToArray())
{
multiThreadStruct.Dispose();
}
_threads.Clear();
}
public void Add(Scene scene)
{
var cts = new CancellationTokenSource();
var thread = new Thread(() => Loop(scene, cts.Token));
_threads.TryAdd(scene.RuntimeId, new MultiThreadStruct(thread, cts));
thread.Start();
}
public void Remove(Scene scene)
{
if (_threads.TryRemove(scene.RuntimeId, out var multiThreadStruct))
{
multiThreadStruct.Dispose();
}
}
public void Update()
{
throw new NotImplementedException();
}
private void Loop(Scene scene, CancellationToken cancellationToken)
{
var sceneThreadSynchronizationContext = scene.ThreadSynchronizationContext;
SynchronizationContext.SetSynchronizationContext(sceneThreadSynchronizationContext);
while (!cancellationToken.IsCancellationRequested)
{
try
{
if (scene.IsDisposed)
{
Remove(scene);
return;
}
sceneThreadSynchronizationContext.Update();
scene.Update();
}
catch (Exception e)
{
Log.Error($"Error in MultiThreadScheduler loop: {e.Message}");
}
finally
{
Thread.Sleep(1);
}
}
}
}
}
#endif

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 36b6da87c3a674cb5b2d2d9d270c397d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,140 +0,0 @@
#if !FANTASY_WEBGL || !FANTASY_SINGLETHREAD
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
#pragma warning disable CS8604 // Possible null reference argument.
namespace NBC
{
internal sealed class ThreadPoolScheduler : ISceneScheduler
{
private bool _isDisposed;
private readonly List<Thread> _threads;
private readonly ConcurrentBag<Scene> _queue = new ConcurrentBag<Scene>();
private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
public ThreadPoolScheduler()
{
// 最大线程数、避免线程过多发生的资源抢占问题。
// 但如果使用了MultiThreadScheduler那么这里的线程数就算是设置了也有可能导致线程过多的问题。
// 线程过多看每个线程的抢占情况,如果抢占资源占用不是很大也没什么大问题。如果过大的情况,就会有性能问题。
// 所以根据情况来使用不同的调度器。
var maxThreadCount = Environment.ProcessorCount;
_threads = new List<Thread>(maxThreadCount);
for (var i = 0; i < maxThreadCount; ++i)
{
Thread thread = new(() => Loop(_cancellationTokenSource.Token))
{
IsBackground = true
};
_threads.Add(thread);
thread.Start();
}
}
public void Dispose()
{
if (_isDisposed)
{
return;
}
_isDisposed = true;
_cancellationTokenSource.Cancel();
foreach (var thread in _threads)
{
if (thread.IsAlive)
{
thread.Join();
}
}
_cancellationTokenSource.Dispose();
_threads.Clear();
}
public void Add(Scene scene)
{
if (_isDisposed)
{
return;
}
_queue.Add(scene);
}
public void Remove(Scene scene)
{
if (_isDisposed)
{
return;
}
var newQueue = new Queue<Scene>();
while (!_queue.IsEmpty)
{
if (_queue.TryTake(out var currentScene))
{
if (currentScene != scene)
{
newQueue.Enqueue(currentScene);
}
}
}
while (newQueue.TryDequeue(out var newScene))
{
_queue.Add(newScene);
}
}
public void Update()
{
throw new NotImplementedException();
}
private void Loop(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
if (_queue.TryTake(out var scene))
{
if (scene == null || scene.IsDisposed)
{
continue;
}
var sceneThreadSynchronizationContext = scene.ThreadSynchronizationContext;
SynchronizationContext.SetSynchronizationContext(sceneThreadSynchronizationContext);
try
{
sceneThreadSynchronizationContext.Update();
scene.Update();
}
catch (Exception e)
{
Log.Error($"Error in ThreadPoolScheduler scene: {e.Message}");
}
finally
{
SynchronizationContext.SetSynchronizationContext(null);
}
_queue.Add(scene);
Thread.Sleep(1);
}
else
{
// 当队列为空的时候、避免无效循环消耗CPU。
Thread.Sleep(10);
}
}
}
}
}
#endif

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 12f33fe68e2b64ac98ecd79b8158e420
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,66 +0,0 @@
// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
namespace NBC
{
/// <summary>
/// 线程调度器
/// </summary>
internal static class ThreadScheduler
{
/// <summary>
/// 主线程调度器
/// </summary>
public static MainScheduler MainScheduler { get; private set; }
/// <summary>
/// 多线程调度器根据当前CPU核心数量创建的固定线程。
/// </summary>
public static ISceneScheduler MultiThreadScheduler { get; private set; }
/// <summary>
/// 线程池调度器
/// </summary>
public static ISceneScheduler ThreadPoolScheduler { get; private set; }
static ThreadScheduler()
{
MainScheduler = new MainScheduler();
}
internal static void Update()
{
MainScheduler.Update();
}
internal static void AddMainScheduler(Scene scene)
{
MainScheduler.Add(scene);
}
internal static void AddToMultiThreadScheduler(Scene scene)
{
if (MultiThreadScheduler == null)
{
#if FANTASY_SINGLETHREAD || FANTASY_WEBGL
MultiThreadScheduler = MainScheduler;
#else
MultiThreadScheduler = new MultiThreadScheduler();
#endif
}
MultiThreadScheduler.Add(scene);
}
internal static void AddToThreadPoolScheduler(Scene scene)
{
if (ThreadPoolScheduler == null)
{
#if FANTASY_SINGLETHREAD || FANTASY_WEBGL
ThreadPoolScheduler = MainScheduler;
#else
ThreadPoolScheduler = new ThreadPoolScheduler();
#endif
}
ThreadPoolScheduler.Add(scene);
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: d9807e33a9ca94371885c6934ff42523
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,154 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using NBC.Network;
using NBC.Entitas;
#pragma warning disable CS8601 // Possible null reference assignment.
#pragma warning disable CS8603 // Possible null reference return.
#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
namespace NBC
{
/// <summary>
/// 代表一个Scene下的子Scene
/// </summary>
public sealed partial class SubScene : Scene
{
/// <summary>
/// 子Scene的根Scene
/// </summary>
public Scene RootScene { get; internal set; }
/// <summary>
/// 存储当前Scene下管理的实体。
/// </summary>
private readonly Dictionary<long, Entity> _entities = new Dictionary<long, Entity>();
internal void Initialize(Scene rootScene)
{
EntityPool = rootScene.EntityPool;
EntityListPool = rootScene.EntityListPool;
EntitySortedDictionaryPool = rootScene.EntitySortedDictionaryPool;
SceneUpdate = rootScene.SceneUpdate;
TimerComponent = rootScene.TimerComponent;
EventComponent = rootScene.EventComponent;
EntityComponent = rootScene.EntityComponent;
MessagePoolComponent = rootScene.MessagePoolComponent;
CoroutineLockComponent = rootScene.CoroutineLockComponent;
MessageDispatcherComponent = rootScene.MessageDispatcherComponent;
ThreadSynchronizationContext = rootScene.ThreadSynchronizationContext;
}
/// <summary>
/// 当子Scene销毁时执行
/// </summary>
public override void Dispose()
{
if (IsDisposed)
{
return;
}
ThreadSynchronizationContext.Post(() =>
{
if (IsDisposed)
{
return;
}
foreach (var (runtimeId, entity) in _entities.ToList())
{
if (runtimeId != entity.RuntimeId)
{
continue;
}
entity.Dispose();
}
_entities.Clear();
base.Dispose();
});
}
/// <summary>
/// 添加一个实体到当前Scene下
/// </summary>
/// <param name="entity">实体实例</param>
public override void AddEntity(Entity entity)
{
_entities.Add(entity.RuntimeId, entity);
RootScene.AddEntity(entity);
}
/// <summary>
/// 根据RunTimeId查询一个实体
/// </summary>
/// <param name="runTimeId">实体的RunTimeId</param>
/// <returns>返回的实体</returns>
public override Entity GetEntity(long runTimeId)
{
return _entities.GetValueOrDefault(runTimeId);
}
/// <summary>
/// 根据RunTimeId查询一个实体
/// </summary>
/// <param name="runTimeId">实体的RunTimeId</param>
/// <param name="entity">实体实例</param>
/// <returns>返回一个bool值来提示是否查找到这个实体</returns>
public override bool TryGetEntity(long runTimeId, out Entity entity)
{
return _entities.TryGetValue(runTimeId, out entity);
}
/// <summary>
/// 根据RunTimeId查询一个实体
/// </summary>
/// <param name="runTimeId">实体的RunTimeId</param>
/// <typeparam name="T">要查询实体的泛型类型</typeparam>
/// <returns>返回的实体</returns>
public override T GetEntity<T>(long runTimeId)
{
return _entities.TryGetValue(runTimeId, out var entity) ? (T)entity : null;
}
/// <summary>
/// 根据RunTimeId查询一个实体
/// </summary>
/// <param name="runTimeId">实体的RunTimeId</param>
/// <param name="entity">实体实例</param>
/// <typeparam name="T">要查询实体的泛型类型</typeparam>
/// <returns>返回一个bool值来提示是否查找到这个实体</returns>
public override bool TryGetEntity<T>(long runTimeId, out T entity)
{
if (_entities.TryGetValue(runTimeId, out var getEntity))
{
entity = (T)getEntity;
return true;
}
entity = null;
return false;
}
/// <summary>
/// 删除一个实体,仅是删除不会指定实体的销毁方法
/// </summary>
/// <param name="runTimeId">实体的RunTimeId</param>
/// <returns>返回一个bool值来提示是否删除了这个实体</returns>
public override bool RemoveEntity(long runTimeId)
{
return _entities.Remove(runTimeId) && RootScene.RemoveEntity(runTimeId);
}
/// <summary>
/// 删除一个实体,仅是删除不会指定实体的销毁方法
/// </summary>
/// <param name="entity">实体实例</param>
/// <returns>返回一个bool值来提示是否删除了这个实体</returns>
public override bool RemoveEntity(Entity entity)
{
return RemoveEntity(entity.RuntimeId);
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 38f07f37ebbca4379903da052249b06b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: