mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-07 16:45:10 +00:00
[+] TEngineServer
[+] TEngineServer
This commit is contained in:
184
Assets/GameScripts/DotNet/Core/Entitas/EntitiesSystem.cs
Normal file
184
Assets/GameScripts/DotNet/Core/Entitas/EntitiesSystem.cs
Normal file
@@ -0,0 +1,184 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using TEngine.DataStructure;
|
||||
using TEngine.Core;
|
||||
|
||||
namespace TEngine
|
||||
{
|
||||
public sealed class EntitiesSystem : Singleton<EntitiesSystem>, IUpdateSingleton
|
||||
{
|
||||
private readonly OneToManyList<int, Type> _assemblyList = new();
|
||||
private readonly Dictionary<Type, IAwakeSystem> _awakeSystems = new();
|
||||
private readonly Dictionary<Type, IUpdateSystem> _updateSystems = new();
|
||||
private readonly Dictionary<Type, IDestroySystem> _destroySystems = new();
|
||||
private readonly Dictionary<Type, IEntitiesSystem> _deserializeSystems = new();
|
||||
|
||||
private readonly Queue<long> _updateQueue = new Queue<long>();
|
||||
|
||||
protected override void OnLoad(int assemblyName)
|
||||
{
|
||||
foreach (var entitiesSystemType in AssemblyManager.ForEach(assemblyName, typeof(IEntitiesSystem)))
|
||||
{
|
||||
var entity = Activator.CreateInstance(entitiesSystemType);
|
||||
|
||||
switch (entity)
|
||||
{
|
||||
case IAwakeSystem iAwakeSystem:
|
||||
{
|
||||
_awakeSystems.Add(iAwakeSystem.EntitiesType(), iAwakeSystem);
|
||||
break;
|
||||
}
|
||||
case IDestroySystem iDestroySystem:
|
||||
{
|
||||
_destroySystems.Add(iDestroySystem.EntitiesType(), iDestroySystem);
|
||||
break;
|
||||
}
|
||||
case IDeserializeSystem iDeserializeSystem:
|
||||
{
|
||||
_deserializeSystems.Add(iDeserializeSystem.EntitiesType(), iDeserializeSystem);
|
||||
break;
|
||||
}
|
||||
case IUpdateSystem iUpdateSystem:
|
||||
{
|
||||
_updateSystems.Add(iUpdateSystem.EntitiesType(), iUpdateSystem);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_assemblyList.Add(assemblyName, entitiesSystemType);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnUnLoad(int assemblyName)
|
||||
{
|
||||
if (!_assemblyList.TryGetValue(assemblyName, out var assembly))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_assemblyList.RemoveByKey(assemblyName);
|
||||
|
||||
foreach (var type in assembly)
|
||||
{
|
||||
_awakeSystems.Remove(type);
|
||||
_updateSystems.Remove(type);
|
||||
_destroySystems.Remove(type);
|
||||
_deserializeSystems.Remove(type);
|
||||
}
|
||||
}
|
||||
|
||||
public void Awake<T>(T entity) where T : Entity
|
||||
{
|
||||
var type = entity.GetType();
|
||||
|
||||
if (!_awakeSystems.TryGetValue(type, out var awakeSystem))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
awakeSystem.Invoke(entity);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error($"{type.Name} Error {e}");
|
||||
}
|
||||
}
|
||||
|
||||
public void Destroy<T>(T entity) where T : Entity
|
||||
{
|
||||
var type = entity.GetType();
|
||||
|
||||
if (!_destroySystems.TryGetValue(type, out var system))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
system.Invoke(entity);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error($"{type.Name} Error {e}");
|
||||
}
|
||||
}
|
||||
|
||||
public void Deserialize<T>(T entity) where T : Entity
|
||||
{
|
||||
var type = entity.GetType();
|
||||
|
||||
if (!_deserializeSystems.TryGetValue(type, out var system))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
system.Invoke(entity);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error($"{type.Name} Error {e}");
|
||||
}
|
||||
}
|
||||
|
||||
public void StartUpdate(Entity entity)
|
||||
{
|
||||
if (!_updateSystems.ContainsKey(entity.GetType()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_updateQueue.Enqueue(entity.RuntimeId);
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
var updateQueueCount = _updateQueue.Count;
|
||||
|
||||
while (updateQueueCount-- > 0)
|
||||
{
|
||||
var runtimeId = _updateQueue.Dequeue();
|
||||
var entity = Entity.GetEntity(runtimeId);
|
||||
|
||||
if (entity == null || entity.IsDisposed)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var type = entity.GetType();
|
||||
|
||||
if (!_updateSystems.TryGetValue(type, out var updateSystem))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
_updateQueue.Enqueue(runtimeId);
|
||||
|
||||
try
|
||||
{
|
||||
updateSystem.Invoke(entity);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error($"{type} Error {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
_assemblyList.Clear();
|
||||
_awakeSystems.Clear();
|
||||
_updateSystems.Clear();
|
||||
_destroySystems.Clear();
|
||||
_deserializeSystems.Clear();
|
||||
AssemblyManager.OnLoadAssemblyEvent -= OnLoad;
|
||||
AssemblyManager.OnUnLoadAssemblyEvent -= OnUnLoad;
|
||||
base.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2ebd4150be3b67b4bafd633a97a738c8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
553
Assets/GameScripts/DotNet/Core/Entitas/Entity.cs
Normal file
553
Assets/GameScripts/DotNet/Core/Entitas/Entity.cs
Normal file
@@ -0,0 +1,553 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TEngine.Core;
|
||||
using System.Runtime.Serialization;
|
||||
using TEngine.DataStructure;
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
using Newtonsoft.Json;
|
||||
#pragma warning disable CS8618
|
||||
#pragma warning disable CS8625
|
||||
#pragma warning disable CS8601
|
||||
#pragma warning disable CS8603
|
||||
#pragma warning disable CS0436
|
||||
|
||||
// ReSharper disable SuspiciousTypeConversion.Global
|
||||
// ReSharper disable InconsistentNaming
|
||||
|
||||
namespace TEngine
|
||||
{
|
||||
public abstract class Entity : IDisposable
|
||||
{
|
||||
#region Entities
|
||||
|
||||
private static readonly Dictionary<long, Entity> Entities = new Dictionary<long, Entity>();
|
||||
private static readonly OneToManyQueue<Type, Entity> Pool = new OneToManyQueue<Type, Entity>();
|
||||
|
||||
public static Entity GetEntity(long runTimeId)
|
||||
{
|
||||
return Entities.TryGetValue(runTimeId, out var entity) ? entity : null;
|
||||
}
|
||||
|
||||
public static bool TryGetEntity(long runTimeId, out Entity entity)
|
||||
{
|
||||
return Entities.TryGetValue(runTimeId, out entity);
|
||||
}
|
||||
|
||||
public static T GetEntity<T>(long runTimeId) where T : Entity, new()
|
||||
{
|
||||
if (!Entities.TryGetValue(runTimeId, out var entity))
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
return (T) entity;
|
||||
}
|
||||
|
||||
public static bool TryGetEntity<T>(long runTimeId, out T outEntity) where T : Entity, new()
|
||||
{
|
||||
if (!Entities.TryGetValue(runTimeId, out var entity))
|
||||
{
|
||||
outEntity = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
outEntity = (T) entity;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static T Rent<T>(Type entityType) where T : Entity, new()
|
||||
{
|
||||
if (typeof(INotSupportedPool).IsAssignableFrom(entityType))
|
||||
{
|
||||
return Activator.CreateInstance<T>();
|
||||
}
|
||||
|
||||
T entity;
|
||||
|
||||
if (Pool.TryDequeue(entityType, out var poolEntity))
|
||||
{
|
||||
entity = (T) poolEntity;
|
||||
}
|
||||
else
|
||||
{
|
||||
entity = Activator.CreateInstance<T>();
|
||||
}
|
||||
|
||||
entity._isFromPool = true;
|
||||
return entity;
|
||||
}
|
||||
|
||||
private static void Return(Entity entity)
|
||||
{
|
||||
entity.Id = 0;
|
||||
|
||||
if (!entity._isFromPool)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
entity._isFromPool = false;
|
||||
Pool.Enqueue(entity.GetType(), entity);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Create
|
||||
|
||||
public static T Create<T>(Scene scene, bool isRunEvent = true) where T : Entity, new()
|
||||
{
|
||||
var entity = Create<T>(scene.RouteId, isRunEvent);
|
||||
entity.Scene = scene;
|
||||
return entity;
|
||||
}
|
||||
|
||||
public static T Create<T>(Scene scene, long id, bool isRunEvent = true) where T : Entity, new()
|
||||
{
|
||||
var entity = Create<T>(id, scene.RouteId, isRunEvent);
|
||||
entity.Scene = scene;
|
||||
return entity;
|
||||
}
|
||||
|
||||
private static T Create<T>(uint routeId, bool isRunEvent = true) where T : Entity, new()
|
||||
{
|
||||
var entity = Rent<T>(typeof(T));
|
||||
#if TENGINE_NET
|
||||
entity.Id = entity.RuntimeId = IdFactory.NextEntityId(routeId);
|
||||
#else
|
||||
entity.Id = entity.RuntimeId = IdFactory.NextRunTimeId();
|
||||
#endif
|
||||
Entities.Add(entity.RuntimeId, entity);
|
||||
|
||||
if (isRunEvent)
|
||||
{
|
||||
EntitiesSystem.Instance.Awake(entity);
|
||||
EntitiesSystem.Instance.StartUpdate(entity);
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
private static T Create<T>(long id, uint routeId, bool isRunEvent = true) where T : Entity, new()
|
||||
{
|
||||
return Create<T>(id, IdFactory.NextEntityId(routeId), isRunEvent);
|
||||
}
|
||||
|
||||
private static T Create<T>(long id, long runtimeId, bool isRunEvent = true) where T : Entity, new()
|
||||
{
|
||||
var entity = Rent<T>(typeof(T));
|
||||
entity.Id = id;
|
||||
entity.RuntimeId = runtimeId;
|
||||
Entities.Add(entity.RuntimeId, entity);
|
||||
|
||||
if (isRunEvent)
|
||||
{
|
||||
EntitiesSystem.Instance.Awake(entity);
|
||||
EntitiesSystem.Instance.StartUpdate(entity);
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
protected static Scene CreateScene(long id, bool isRunEvent = true)
|
||||
{
|
||||
var entity = Create<Scene>(id, id, isRunEvent);
|
||||
entity.Scene = entity;
|
||||
return entity;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Members
|
||||
|
||||
[BsonId]
|
||||
[BsonElement]
|
||||
[BsonIgnoreIfDefault]
|
||||
[BsonDefaultValue(0L)]
|
||||
public long Id { get; private set; }
|
||||
|
||||
[BsonIgnore]
|
||||
[IgnoreDataMember]
|
||||
public long RuntimeId { get; private set; }
|
||||
|
||||
[BsonIgnore]
|
||||
[JsonIgnore]
|
||||
[IgnoreDataMember]
|
||||
public bool IsDisposed => RuntimeId == 0;
|
||||
|
||||
[BsonIgnore]
|
||||
[JsonIgnore]
|
||||
[IgnoreDataMember]
|
||||
public Scene Scene { get; private set; }
|
||||
|
||||
[BsonIgnore]
|
||||
[JsonIgnore]
|
||||
[IgnoreDataMember]
|
||||
public Entity Parent { get; private set; }
|
||||
|
||||
[BsonElement("t")]
|
||||
[BsonIgnoreIfNull]
|
||||
private ListPool<Entity> _treeDb;
|
||||
|
||||
[BsonIgnore]
|
||||
[IgnoreDataMember]
|
||||
private DictionaryPool<Type, Entity> _tree;
|
||||
|
||||
[BsonElement("m")]
|
||||
[BsonIgnoreIfNull]
|
||||
private ListPool<Entity> _multiDb;
|
||||
|
||||
[BsonIgnore]
|
||||
[IgnoreDataMember]
|
||||
private DictionaryPool<long, ISupportedMultiEntity> _multi;
|
||||
|
||||
[BsonIgnore]
|
||||
[IgnoreDataMember]
|
||||
private bool _isFromPool;
|
||||
|
||||
#endregion
|
||||
|
||||
#region AddComponent
|
||||
|
||||
public T AddComponent<T>() where T : Entity, new()
|
||||
{
|
||||
var entity = Create<T>(Scene.RouteId, false);
|
||||
AddComponent(entity);
|
||||
EntitiesSystem.Instance.Awake(entity);
|
||||
EntitiesSystem.Instance.StartUpdate(entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
public T AddComponent<T>(long id) where T : Entity, new()
|
||||
{
|
||||
var entity = Create<T>(id, Scene.RouteId, false);
|
||||
AddComponent(entity);
|
||||
EntitiesSystem.Instance.Awake(entity);
|
||||
EntitiesSystem.Instance.StartUpdate(entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
public void AddComponent(Entity component)
|
||||
{
|
||||
if (this == component)
|
||||
{
|
||||
Log.Error("Cannot add oneself to one's own components");
|
||||
return;
|
||||
}
|
||||
|
||||
if (component.IsDisposed)
|
||||
{
|
||||
Log.Error($"component is Disposed {component.GetType().FullName}");
|
||||
return;
|
||||
}
|
||||
|
||||
var type = component.GetType();
|
||||
component.Parent?.RemoveComponent(component, false);
|
||||
|
||||
if (component is ISupportedMultiEntity multiEntity)
|
||||
{
|
||||
_multi ??= DictionaryPool<long, ISupportedMultiEntity>.Create();
|
||||
_multi.Add(component.Id, multiEntity);
|
||||
|
||||
if (component is ISupportedDataBase)
|
||||
{
|
||||
_multiDb ??= ListPool<Entity>.Create();
|
||||
_multiDb.Add(component);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_tree == null)
|
||||
{
|
||||
_tree = DictionaryPool<Type, Entity>.Create();
|
||||
}
|
||||
else if(_tree.ContainsKey(type))
|
||||
{
|
||||
Log.Error($"type:{type.FullName} If you want to add multiple components of the same type, please implement IMultiEntity");
|
||||
return;
|
||||
}
|
||||
|
||||
_tree.Add(type, component);
|
||||
|
||||
if (component is ISupportedDataBase)
|
||||
{
|
||||
_treeDb ??= ListPool<Entity>.Create();
|
||||
_treeDb.Add(component);
|
||||
}
|
||||
}
|
||||
|
||||
component.Parent = this;
|
||||
component.Scene = Scene;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetComponent
|
||||
|
||||
public T GetComponent<T>() where T : Entity, new()
|
||||
{
|
||||
return GetComponent(typeof(T)) as T;
|
||||
}
|
||||
|
||||
public Entity GetComponent(Type componentType)
|
||||
{
|
||||
if (_tree == null)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
return _tree.TryGetValue(componentType, out var component) ? component : default;
|
||||
}
|
||||
|
||||
public T GetComponent<T>(long id) where T : ISupportedMultiEntity, new()
|
||||
{
|
||||
if (_multi == null)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
return _multi.TryGetValue(id, out var entity) ? (T) entity : default;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region RemoveComponent
|
||||
|
||||
public void RemoveComponent<T>(bool isDispose = true) where T : Entity, new()
|
||||
{
|
||||
if (_tree == null || !_tree.TryGetValue(typeof(T), out var component))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RemoveComponent(component, isDispose);
|
||||
}
|
||||
|
||||
public void RemoveComponent<T>(long id, bool isDispose = true) where T : ISupportedMultiEntity, new()
|
||||
{
|
||||
if (_multi == null || !_multi.TryGetValue(id, out var component))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RemoveComponent((Entity)component, isDispose);
|
||||
}
|
||||
|
||||
public void RemoveComponent(Entity component, bool isDispose = true)
|
||||
{
|
||||
if (this == component)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (component is ISupportedMultiEntity)
|
||||
{
|
||||
if (_multi != null)
|
||||
{
|
||||
#if TENGINE_NET
|
||||
if (component is ISupportedDataBase && _multiDb != null)
|
||||
{
|
||||
_multiDb.Remove(component);
|
||||
|
||||
if (_multiDb.Count == 0)
|
||||
{
|
||||
_multiDb.Dispose();
|
||||
_multiDb = null;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
_multi.Remove(component.Id);
|
||||
|
||||
if (_multi.Count == 0)
|
||||
{
|
||||
_multi.Dispose();
|
||||
_multi = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (_tree != null)
|
||||
{
|
||||
#if TENGINE_NET
|
||||
if (component is ISupportedDataBase && _treeDb != null)
|
||||
{
|
||||
_treeDb.Remove(component);
|
||||
|
||||
if (_treeDb.Count == 0)
|
||||
{
|
||||
_treeDb.Dispose();
|
||||
_treeDb = null;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
_tree.Remove(component.GetType());
|
||||
|
||||
if (_tree.Count == 0)
|
||||
{
|
||||
_tree.Dispose();
|
||||
_tree = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (isDispose)
|
||||
{
|
||||
component.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Deserialize
|
||||
|
||||
public void Deserialize(Scene scene, bool resetId = false)
|
||||
{
|
||||
if (IsDisposed)
|
||||
{
|
||||
Log.Error($"component is Disposed {this.GetType().FullName}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (RuntimeId != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
#if TENGINE_NET
|
||||
RuntimeId = IdFactory.NextEntityId(scene.RouteId);
|
||||
#else
|
||||
RuntimeId = IdFactory.NextRunTimeId();
|
||||
#endif
|
||||
if (resetId)
|
||||
{
|
||||
Id = RuntimeId;
|
||||
}
|
||||
|
||||
Entities.Add(RuntimeId, this);
|
||||
|
||||
if (_treeDb != null && _treeDb.Count > 0)
|
||||
{
|
||||
_tree = DictionaryPool<Type, Entity>.Create();
|
||||
foreach (var entity in _treeDb)
|
||||
{
|
||||
entity.Parent = this;
|
||||
entity.Scene = scene;
|
||||
entity.Deserialize(scene, resetId);
|
||||
_tree.Add(entity.GetType(), entity);
|
||||
}
|
||||
}
|
||||
|
||||
if (_multiDb != null && _multiDb.Count > 0)
|
||||
{
|
||||
_multi = DictionaryPool<long, ISupportedMultiEntity>.Create();
|
||||
foreach (var entity in _multiDb)
|
||||
{
|
||||
entity.Parent = this;
|
||||
entity.Scene = scene;
|
||||
entity.Deserialize(scene, resetId);
|
||||
_multi.Add(entity.Id, (ISupportedMultiEntity)entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (RuntimeId != 0)
|
||||
{
|
||||
Entities.Remove(RuntimeId);
|
||||
}
|
||||
|
||||
Log.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Clone
|
||||
|
||||
public Entity Clone()
|
||||
{
|
||||
#if TENGINE_NET
|
||||
var entity = MongoHelper.Instance.Clone(this);
|
||||
entity.Deserialize(Scene, true);
|
||||
return entity;
|
||||
#elif TENGINE_UNITY
|
||||
var entity = ProtoBufHelper.Clone(this);
|
||||
entity.Deserialize(Scene, true);
|
||||
return entity;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Dispose
|
||||
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if (IsDisposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var runtimeId = RuntimeId;
|
||||
RuntimeId = 0;
|
||||
|
||||
if (_tree != null)
|
||||
{
|
||||
foreach (var (_, entity) in _tree)
|
||||
{
|
||||
entity.Dispose();
|
||||
}
|
||||
|
||||
_tree.Dispose();
|
||||
_tree = null;
|
||||
}
|
||||
|
||||
if (_multi != null)
|
||||
{
|
||||
foreach (var (_, entity) in _multi)
|
||||
{
|
||||
entity.Dispose();
|
||||
}
|
||||
|
||||
_multi.Dispose();
|
||||
_multi = null;
|
||||
}
|
||||
|
||||
#if TENGINE_NET
|
||||
if (_treeDb != null)
|
||||
{
|
||||
foreach (var entity in _treeDb)
|
||||
{
|
||||
entity.Dispose();
|
||||
}
|
||||
|
||||
_treeDb.Dispose();
|
||||
_treeDb = null;
|
||||
}
|
||||
|
||||
if (_multiDb != null)
|
||||
{
|
||||
foreach (var entity in _multiDb)
|
||||
{
|
||||
entity.Dispose();
|
||||
}
|
||||
|
||||
_multiDb.Dispose();
|
||||
_multiDb = null;
|
||||
}
|
||||
#endif
|
||||
EntitiesSystem.Instance?.Destroy(this);
|
||||
|
||||
if (Parent != null && Parent != this && !Parent.IsDisposed)
|
||||
{
|
||||
Parent.RemoveComponent(this, false);
|
||||
Parent = null;
|
||||
}
|
||||
|
||||
Entities.Remove(runtimeId);
|
||||
Scene = null;
|
||||
Return(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
11
Assets/GameScripts/DotNet/Core/Entitas/Entity.cs.meta
Normal file
11
Assets/GameScripts/DotNet/Core/Entitas/Entity.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f4ac3a7a2c87dab48819ea8ad865ec76
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/GameScripts/DotNet/Core/Entitas/Interface.meta
Normal file
8
Assets/GameScripts/DotNet/Core/Entitas/Interface.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2c5e09a29bcfe7c4f9f84422354a6d2c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0c3ff31e66c8ca44b8e99c068cdcc04a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
namespace TEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Entity不支持对象池创建和回收
|
||||
/// </summary>
|
||||
public interface INotSupportedPool { }
|
||||
}
|
||||
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b9eceeefe7ee19f47bac590bc44d57d6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
namespace TEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Entity支持数据库
|
||||
/// </summary>
|
||||
// ReSharper disable once InconsistentNaming
|
||||
public interface ISupportedDataBase { }
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fa02a2282c8866746a60eaaa35afb0de
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace TEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// 支持再一个组件里添加多个同类型组件
|
||||
/// </summary>
|
||||
public interface ISupportedMultiEntity : IDisposable { }
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 17d0f9fb53e07414991160d50cf133e1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3473ee41e6d3cfa489bcf20bc8f6d546
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
|
||||
namespace TEngine
|
||||
{
|
||||
public interface IAwakeSystem : IEntitiesSystem { }
|
||||
|
||||
public abstract class AwakeSystem<T> : IAwakeSystem where T : Entity
|
||||
{
|
||||
public Type EntitiesType() => typeof(T);
|
||||
|
||||
protected abstract void Awake(T self);
|
||||
|
||||
public void Invoke(Entity self)
|
||||
{
|
||||
Awake((T) self);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e152a700f49f0748bfbdd03108a4a5e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
|
||||
namespace TEngine
|
||||
{
|
||||
public interface IDeserializeSystem : IEntitiesSystem { }
|
||||
|
||||
public abstract class DeserializeSystem<T> : IDeserializeSystem where T : Entity
|
||||
{
|
||||
public Type EntitiesType() => typeof(T);
|
||||
protected abstract void Deserialize(T self);
|
||||
public void Invoke(Entity self)
|
||||
{
|
||||
Deserialize((T) self);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: be8b21b9058e78343abfeea9277be75e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
|
||||
namespace TEngine
|
||||
{
|
||||
public interface IDestroySystem : IEntitiesSystem { }
|
||||
|
||||
public abstract class DestroySystem<T> : IDestroySystem where T : Entity
|
||||
{
|
||||
public Type EntitiesType() => typeof(T);
|
||||
protected abstract void Destroy(T self);
|
||||
public void Invoke(Entity self)
|
||||
{
|
||||
Destroy((T) self);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7140fd5ab56bd3b4ba04cfe40470ad23
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,10 @@
|
||||
using System;
|
||||
|
||||
namespace TEngine
|
||||
{
|
||||
public interface IEntitiesSystem
|
||||
{
|
||||
public Type EntitiesType();
|
||||
void Invoke(Entity entity);
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4e4fa4e598c849148a0dd63e785716f3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
|
||||
namespace TEngine
|
||||
{
|
||||
public interface IUpdateSystem : IEntitiesSystem { }
|
||||
|
||||
public abstract class UpdateSystem<T> : IUpdateSystem where T : Entity
|
||||
{
|
||||
public Type EntitiesType() => typeof(T);
|
||||
protected abstract void Update(T self);
|
||||
public void Invoke(Entity self)
|
||||
{
|
||||
Update((T) self);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f39edd76db52bd84aa385cd02fa98db8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/GameScripts/DotNet/Core/Entitas/Scene.meta
Normal file
8
Assets/GameScripts/DotNet/Core/Entitas/Scene.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d9f783d00ec372489401151473f8d7e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
169
Assets/GameScripts/DotNet/Core/Entitas/Scene/Scene.cs
Normal file
169
Assets/GameScripts/DotNet/Core/Entitas/Scene/Scene.cs
Normal file
@@ -0,0 +1,169 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TEngine.Core.Network;
|
||||
using TEngine.Core;
|
||||
#if TENGINE_NET
|
||||
using TEngine.Core.DataBase;
|
||||
#endif
|
||||
#pragma warning disable CS8625
|
||||
#pragma warning disable CS8618
|
||||
namespace TEngine
|
||||
{
|
||||
public sealed class Scene : Entity, INotSupportedPool
|
||||
{
|
||||
public string Name { get; private set; }
|
||||
public uint RouteId { get; private set; }
|
||||
#if TENGINE_UNITY
|
||||
public Session Session { get; private set; }
|
||||
public SceneConfigInfo SceneInfo { get; private set; }
|
||||
#endif
|
||||
#if TENGINE_NET
|
||||
public World World { get; private set; }
|
||||
public Server Server { get; private set; }
|
||||
public uint SceneConfigId { get; private set; }
|
||||
public SceneConfigInfo SceneInfo => ConfigTableManage.SceneConfig(SceneConfigId);
|
||||
#endif
|
||||
public static readonly List<Scene> Scenes = new List<Scene>();
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
if (IsDisposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Name = null;
|
||||
RouteId = 0;
|
||||
#if TENGINE_NET
|
||||
World = null;
|
||||
Server = null;
|
||||
SceneConfigId = 0;
|
||||
#endif
|
||||
#if TENGINE_UNITY
|
||||
SceneInfo = null;
|
||||
if (Session is { IsDisposed: false })
|
||||
{
|
||||
Session.Dispose();
|
||||
Session = null;
|
||||
}
|
||||
#endif
|
||||
Scenes.Remove(this);
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
public static void DisposeAllScene()
|
||||
{
|
||||
foreach (var scene in Scenes.ToArray())
|
||||
{
|
||||
scene.Dispose();
|
||||
}
|
||||
}
|
||||
#if TENGINE_UNITY
|
||||
public static Scene Create(string name)
|
||||
{
|
||||
var runTimeId = IdFactory.NextRunTimeId();
|
||||
var scene = CreateScene(runTimeId);
|
||||
scene.Name = name;
|
||||
Scenes.Add(scene);
|
||||
return scene;
|
||||
}
|
||||
public void CreateSession(string remoteAddress, NetworkProtocolType networkProtocolType, Action onConnectComplete, Action onConnectFail, int connectTimeout = 5000)
|
||||
{
|
||||
var address = NetworkHelper.ToIPEndPoint(remoteAddress);
|
||||
var clientNetworkComponent = AddComponent<ClientNetworkComponent>();
|
||||
clientNetworkComponent.Initialize(networkProtocolType, NetworkTarget.Outer);
|
||||
clientNetworkComponent.Connect(address, onConnectComplete, onConnectFail, connectTimeout);
|
||||
Session = clientNetworkComponent.Session;
|
||||
}
|
||||
#else
|
||||
/// <summary>
|
||||
/// 创建一个Scene
|
||||
/// </summary>
|
||||
/// <param name="server"></param>
|
||||
/// <param name="outerBindIp"></param>
|
||||
/// <param name="sceneInfo"></param>
|
||||
/// <param name="runEvent"></param>
|
||||
/// <param name="onSetNetworkComplete"></param>
|
||||
/// <returns></returns>
|
||||
public static async FTask<Scene> Create(Server server, string outerBindIp, SceneConfigInfo sceneInfo, Action<Session> onSetNetworkComplete = null, bool runEvent = true)
|
||||
{
|
||||
var scene = CreateScene(sceneInfo.EntityId);
|
||||
sceneInfo.Scene = scene;
|
||||
scene.Name = sceneInfo.Name;
|
||||
scene.RouteId = sceneInfo.RouteId;
|
||||
scene.Server = server;
|
||||
scene.SceneConfigId = sceneInfo.Id;
|
||||
|
||||
if (sceneInfo.WorldId != 0)
|
||||
{
|
||||
// 有可能不需要数据库、所以这里默认0的情况下就不创建数据库了
|
||||
scene.World = World.Create(sceneInfo.WorldId);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(sceneInfo.NetworkProtocol) && !string.IsNullOrEmpty(outerBindIp) && sceneInfo.OuterPort != 0)
|
||||
{
|
||||
// 设置Scene的网络、目前只支持KCP和TCP
|
||||
var networkProtocolType = Enum.Parse<NetworkProtocolType>(sceneInfo.NetworkProtocol);
|
||||
var serverNetworkComponent = scene.AddComponent<ServerNetworkComponent>();
|
||||
var address = NetworkHelper.ToIPEndPoint($"{outerBindIp}:{sceneInfo.OuterPort}");
|
||||
serverNetworkComponent.Initialize(networkProtocolType, NetworkTarget.Outer, address);
|
||||
}
|
||||
|
||||
if (runEvent && sceneInfo.SceneType != null)
|
||||
{
|
||||
// 没有SceneType目前只有代码创建的Scene才会这样、目前只有Server的Scene是这样
|
||||
await EventSystem.Instance.PublishAsync(new OnCreateScene(sceneInfo, onSetNetworkComplete));
|
||||
}
|
||||
|
||||
Scenes.Add(scene);
|
||||
return scene;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 一般用于创建临时Scene、如果不是必要不建议使用这个接口
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="server"></param>
|
||||
/// <param name="entityId"></param>
|
||||
/// <param name="sceneConfigId"></param>
|
||||
/// <param name="networkProtocol"></param>
|
||||
/// <param name="outerBindIp"></param>
|
||||
/// <param name="outerPort"></param>
|
||||
/// <param name="runEvent"></param>
|
||||
/// <param name="onSetNetworkComplete"></param>
|
||||
/// <returns></returns>
|
||||
public static async FTask<Scene> Create(string name, Server server, long entityId, uint sceneConfigId = 0, string networkProtocol = null, string outerBindIp = null, int outerPort = 0, Action<Session> onSetNetworkComplete = null, bool runEvent = true)
|
||||
{
|
||||
var sceneInfo = new SceneConfigInfo()
|
||||
{
|
||||
Name = name,
|
||||
EntityId = entityId,
|
||||
Id = sceneConfigId,
|
||||
NetworkProtocol = networkProtocol,
|
||||
OuterPort = outerPort,
|
||||
WorldId = ((EntityIdStruct)entityId).WordId
|
||||
};
|
||||
|
||||
return await Create(server, outerBindIp, sceneInfo, onSetNetworkComplete, runEvent);
|
||||
}
|
||||
|
||||
public static List<SceneConfigInfo> GetSceneInfoByRouteId(uint routeId)
|
||||
{
|
||||
var list = new List<SceneConfigInfo>();
|
||||
var allSceneConfig = ConfigTableManage.AllSceneConfig();
|
||||
|
||||
foreach (var sceneConfigInfo in allSceneConfig)
|
||||
{
|
||||
if (sceneConfigInfo.RouteId != routeId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
list.Add(sceneConfigInfo);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
11
Assets/GameScripts/DotNet/Core/Entitas/Scene/Scene.cs.meta
Normal file
11
Assets/GameScripts/DotNet/Core/Entitas/Scene/Scene.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 12c279f9aa38cab41b3bf04be0eea700
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
18
Assets/GameScripts/DotNet/Core/Entitas/Scene/SceneEvent.cs
Normal file
18
Assets/GameScripts/DotNet/Core/Entitas/Scene/SceneEvent.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
#if TENGINE_NET
|
||||
using System;
|
||||
using TEngine.Core.Network;
|
||||
namespace TEngine
|
||||
{
|
||||
public struct OnCreateScene
|
||||
{
|
||||
public readonly SceneConfigInfo SceneInfo;
|
||||
public readonly Action<Session> OnSetNetworkComplete;
|
||||
|
||||
public OnCreateScene(SceneConfigInfo sceneInfo, Action<Session> onSetNetworkComplete)
|
||||
{
|
||||
SceneInfo = sceneInfo;
|
||||
OnSetNetworkComplete = onSetNetworkComplete;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e237f0cc7a65b51408d828a87535b4dc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/GameScripts/DotNet/Core/Entitas/Unity.meta
Normal file
8
Assets/GameScripts/DotNet/Core/Entitas/Unity.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7cdae026533d88e4684eca7b48850d12
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f3af894a35a86864fa02cf949eb89f03
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,11 @@
|
||||
#if TENGINE_UNITY
|
||||
using System;
|
||||
namespace MongoDB.Bson.Serialization.Attributes
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
|
||||
public class BsonDefaultValueAttribute : Attribute
|
||||
{
|
||||
public BsonDefaultValueAttribute(object defaultValue) { }
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 49dc7c79f6822c64e927ca4f5cad88f8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,13 @@
|
||||
#if TENGINE_UNITY
|
||||
using System;
|
||||
namespace MongoDB.Bson.Serialization.Attributes
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
|
||||
public class BsonElementAttribute : Attribute
|
||||
{
|
||||
public BsonElementAttribute() { }
|
||||
|
||||
public BsonElementAttribute(string elementName) { }
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9218b708df975ba428c2342e978cd473
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,13 @@
|
||||
#if TENGINE_UNITY
|
||||
using System;
|
||||
namespace MongoDB.Bson.Serialization.Attributes
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
|
||||
public class BsonIdAttribute : Attribute
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3e07e248c36907847adb96b09269689f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,11 @@
|
||||
#if TENGINE_UNITY
|
||||
using System;
|
||||
namespace MongoDB.Bson.Serialization.Attributes
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
|
||||
public class BsonIgnoreAttribute : Attribute
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a11815e9c0d9fe24f97da6a976538bfc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,13 @@
|
||||
#if TENGINE_UNITY
|
||||
using System;
|
||||
namespace MongoDB.Bson.Serialization.Attributes
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
|
||||
public class BsonIgnoreIfDefaultAttribute : Attribute
|
||||
{
|
||||
public BsonIgnoreIfDefaultAttribute() { }
|
||||
|
||||
public BsonIgnoreIfDefaultAttribute(bool value) { }
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 24366fa27fe479a439c306cae6a2cf98
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,11 @@
|
||||
#if TENGINE_UNITY
|
||||
using System;
|
||||
namespace MongoDB.Bson.Serialization.Attributes
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
|
||||
public class BsonIgnoreIfNullAttribute : Attribute
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fb14d1148e275bf4f8220694eab51fc0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user