This commit is contained in:
CortexCore
2024-03-31 23:31:00 +08:00
parent e179d2eb53
commit b7b89ee71a
641 changed files with 31286 additions and 22134 deletions

View File

@@ -7,15 +7,20 @@ using System.Text;
using System.Threading;
using BITKit.Entities;
using Cysharp.Threading.Tasks;
using UnityEngine.Profiling;
using UnityEngine.UIElements;
// ReSharper disable RedundantTypeArgumentsOfMethod
namespace BITKit.Entities
{
[CustomType(typeof(IUnityEntity))]
[CustomType(typeof(IEntity))]
public class Entity : MonoBehaviour, IUnityEntity
{
private readonly GenericEvent genericEvent = new();
public ulong Id { get; private set; }
public ulong Id { get; set; }
public CancellationToken CancellationToken { get; private set; }
public IEntityBehavior[] Behaviors { get;private set; }
public IEntityComponent[] Components => Behaviors.Cast<IEntityComponent>().ToArray();
@@ -31,7 +36,7 @@ namespace BITKit.Entities
foreach (var fieldInfo in obj
.GetType()
.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.Where(fieldInfo=>fieldInfo.GetCustomAttribute<InjectAttribute>() is not null))
.Where(fieldInfo=>fieldInfo.GetCustomAttribute<InjectAttribute>(true) is not null))
{
var type = fieldInfo.FieldType;
var attribute = fieldInfo.GetCustomAttribute<InjectAttribute>();
@@ -83,19 +88,30 @@ namespace BITKit.Entities
}
private bool isInitialized;
public void WaitForInitializationComplete()
{
if (isInitialized) return;
Start();
isInitialized = true;
}
private void Awake()
{
Id = (ulong)Guid.NewGuid().GetHashCode();
if (Id.IsDefault())
Id = (ulong)Guid.NewGuid().GetHashCode();
CancellationToken = gameObject.GetCancellationTokenOnDestroy();
Set(CancellationToken);
Behaviors = GetComponentsInChildren<IEntityBehavior>(true).Distinct().ToArray();
}
private void Start()
{
if (isInitialized) return;
try
{
AddService<IEntity>(this);
AddService<Entity>(this);
AddService<IUnityEntity>(this);
Behaviors = GetComponentsInChildren<IEntityBehavior>(true).Distinct().ToArray();
var monoBehaviours = GetComponentsInChildren<MonoBehaviour>(true);
Behaviors.ForEach(x => x.Initialize(this));
foreach (var x in monoBehaviours)
@@ -108,8 +124,11 @@ namespace BITKit.Entities
.OfType<CustomTypeAttribute>()
)
{
AddService(att.Type, x);
AddService(att.Type, x);
if (att.AsGlobal)
DI.Register(att.Type, x);
}
genericEvent.Set(x.GetType(),x);
}
foreach (var x in monoBehaviours)
@@ -143,23 +162,26 @@ namespace BITKit.Entities
private void Update()
{
var deltaTime = Time.fixedDeltaTime;
foreach (var x in Behaviors)
{
x.OnUpdate(Time.deltaTime);
x.OnUpdate(deltaTime);
}
}
private void FixedUpdate()
{
var deltaTime = Time.fixedDeltaTime;
foreach (var x in Behaviors)
{
x.OnFixedUpdate(Time.fixedDeltaTime);
x.OnFixedUpdate(deltaTime);
}
}
private void LateUpdate()
{
var deltaTime = Time.fixedDeltaTime;
foreach (var x in Behaviors)
{
x.OnLateUpdate(Time.deltaTime);
x.OnLateUpdate(deltaTime);
}
}
public void AddListener<T>(Action<T> action) => genericEvent.AddListener<T>(action);

View File

@@ -0,0 +1,17 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BITKit.Entities
{
[CustomType(typeof(IAddressable))]
public class EntityAddressableComponent : MonoBehaviour,IAddressable
{
[SerializeField] private string addressablePath;
[SerializeField] private ulong addressableId;
public string AddressablePath => addressablePath;
public ulong AddressableId => addressableId;
}
}

View File

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

View File

@@ -1,4 +1,5 @@
using System;
using System.Threading;
using BITKit.Entities;
#if UNITY_EDITOR
using UnityEditor;

View File

@@ -0,0 +1,73 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
namespace BITKit.Entities
{
[CustomType(typeof(IEntityBinaryHeader))]
public class EntityBinaryHeader : EntityBehavior,IEntityBinaryHeader
{
public int Id => (int)Entity.Id;
public IDictionary<int, IEntityBinaryComponent> ComponentDictionary { get; } =
new Dictionary<int, IEntityBinaryComponent>();
public override void OnStart()
{
base.OnStart();
foreach (var component in Entity.Components.OfType<IEntityBinaryComponent>())
{
ComponentDictionary.Add(component.Id, component);
}
}
public void Serialize(BinaryWriter writer)
{
//写入组件数量
//写入组件ID
//写入组件数据
//写入组件数据长度
var length = ComponentDictionary.Count;
writer.Write(length);
foreach (var component in ComponentDictionary.Values)
{
writer.Write(component.Id);
}
foreach (var component in ComponentDictionary.Values)
{
using var ms = new MemoryStream();
using var binaryWriter = new BinaryWriter(ms);
component.Serialize(binaryWriter);
binaryWriter.Flush();
ms.Flush();
var bytes = ms.ToArray();
writer.Write(bytes.Length);
writer.Write(bytes);
}
}
public void Deserialize(BinaryReader reader)
{
//BIT4Log.Log<EntityBinaryHeader>("源数据长度:"+reader.BaseStream.Length);
//读取组件数量
//读取组件ID
//读取组件数据
var count = reader.ReadInt32();
//BIT4Log.Log<EntityBinaryHeader>($"count:{count}");
var ids = new int[count];
for (var i = 0; i < count; i++)
{
ids[i] = reader.ReadInt32();
}
foreach (var id in ids)
{
var length = reader.ReadInt32();
var bytes = reader.ReadBytes(length);
using var stream = new MemoryStream(bytes);
using var binaryReader = new BinaryReader(stream);
//BIT4Log.Log<EntityBinaryHeader>($"id:{id},length:{length},bytes:\n{JsonHelper.Get(bytes)}");
ComponentDictionary[id].Deserialize(binaryReader);
}
}
}
}

View File

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

View File

@@ -4,21 +4,52 @@ using System.Collections.Generic;
using UnityEngine;
namespace BITKit.Entities
{
public interface IEntityOverride
{
/// <summary>
/// 是否正在被覆盖
/// </summary>
bool IsOvering { get; }
void AddOverride(object key);
void RemoveOverride(object key);
/// <summary>
/// 当前对象,用于判断是否是自己的覆盖
/// </summary>
object CurrentObject { get; }
/// <summary>
/// 当开始覆盖或者结束覆盖时触发
/// </summary>
event Action<bool> OnOverride;
/// <summary>
/// 添加覆盖
/// </summary>
void AddOverride(object key,int priority=0);
/// <summary>
/// 移除覆盖
/// </summary>
void RemoveOverride(object key,int priority=0);
}
[CustomType(typeof(IEntityOverride))]
public class EntityOverride : EntityBehavior,IEntityOverride
{
[SerializeField,ReadOnly] private bool isOvering;
[SerializeField, ReadOnly(HideLabel = true)] private string overrideKeys;
public bool IsOvering => _allowOverrideHandle;
public object CurrentObject => _prioritySelector.Current;
private readonly ValidHandle _allowOverrideHandle = new();
public void AddOverride(object key) => _allowOverrideHandle.AddElement(key);
public void RemoveOverride(object key)=>_allowOverrideHandle.RemoveElement(key);
private readonly PrioritySelector<object> _prioritySelector = new();
public void AddOverride(object key,int priority=0)
{
_prioritySelector.Set(priority,key);
_allowOverrideHandle.AddElement(key);
}
public void RemoveOverride(object key,int priority=0)
{
_prioritySelector.Remove(priority);
_allowOverrideHandle.RemoveElement(key);
}
public event Action<bool> OnOverride;
public override void Initialize(IEntity entity)
@@ -35,6 +66,7 @@ namespace BITKit.Entities
{
OnOverride?.Invoke(@override);
isOvering=@override;
overrideKeys = _allowOverrideHandle.ToString();
}
}
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using BITKit.Entities;
using BITKit.StateMachine;
using UnityEngine;
@@ -27,20 +28,27 @@ namespace BITKit.Entities
add => stateMachine.OnStateChanged += value;
remove => stateMachine.OnStateChanged -= value;
}
public event Action<T> OnStateRegistered;
public event Action<T> OnStateUnRegistered;
public IDictionary<Type, T> StateDictionary => stateMachine.StateDictionary;
public override void Initialize(IEntity entity)
public override void OnAwake()
{
base.Initialize(entity);
base.OnAwake();
if (stateMachine is null)
{
Debug.LogWarning(GetType().Name);
}
else
{
foreach (var x in stateMachine.states)
{
Entity.Inject(x);
}
stateMachine.Initialize();
}
}
void IStateMachine<T>.Initialize()
void IStateMachine<T>.Initialize()
{
stateMachine.Initialize();
}
@@ -62,6 +70,23 @@ namespace BITKit.Entities
{
stateMachine.TransitionState(state);
}
public virtual void Register(T newState)
{
Entity.Inject(newState);
StateMachineUtils.Register(this, newState);
}
public virtual void UnRegister(T newState)=>StateMachineUtils.UnRegister(this,newState);
public void InvokeOnStateRegistered(T state)
{
OnStateRegistered?.Invoke(state);
}
public void InvokeOnStateUnRegistered(T state)
{
OnStateUnRegistered?.Invoke(state);
}
}
}

View File

@@ -39,6 +39,10 @@ public class UnityEntitiesServiceSingleton:IEntitiesService
public CancellationToken CancellationToken => UnityEntitiesService.CancellationToken;
public IEntity Get(ulong id) => UnityEntitiesService.Get(id);
public bool TryGetEntity(ulong id, out IEntity entity) => UnityEntitiesService.TryGetEntity(id, out entity);
public IEntity GetOrAdd(ulong id, Func<ulong, IEntity> factory)=>UnityEntitiesService.GetOrAdd(id,factory);
public IEntity[] Query<T>()
{
@@ -124,6 +128,17 @@ public class UnityEntitiesService : MonoBehaviour,IEntitiesService
CancellationToken IEntitiesService.CancellationToken => CancellationToken;
public static IEntity Get(ulong id)=>Dictionary[id];
IEntity IEntitiesService.Get(ulong id)=>Get(id);
public static bool TryGetEntity(ulong id, out IEntity entity)
{
return Dictionary.TryGetValue(id, out entity);
}
bool IEntitiesService.TryGetEntity(ulong id, out IEntity entity)=>TryGetEntity(id,out entity);
public static IEntity GetOrAdd(ulong id, Func<ulong, IEntity> factory)
{
return Dictionary.GetOrAdd(id, factory);
}
IEntity IEntitiesService.GetOrAdd(ulong id, Func<ulong, IEntity> factory)=>GetOrAdd(id,factory);
IEntity[] IEntitiesService.Query<T>()=>Query<T>();
public static IEntity[] Query<T>()
{