diff --git a/Assets/Scenes/DemoScene.unity b/Assets/Scenes/DemoScene.unity index 431b2d4b..b6a2d8de 100644 --- a/Assets/Scenes/DemoScene.unity +++ b/Assets/Scenes/DemoScene.unity @@ -254,6 +254,14 @@ PrefabInstance: m_Modification: m_TransformParent: {fileID: 0} m_Modifications: + - target: {fileID: 96376813, guid: 161ff7c8132079c4a95e2e4e70ddd41b, type: 3} + propertyPath: m_EntityHelperTypeName + value: TEngine.Runtime.Entity.DefaultEntityHelper + objectReference: {fileID: 0} + - target: {fileID: 96376813, guid: 161ff7c8132079c4a95e2e4e70ddd41b, type: 3} + propertyPath: m_EntityGroupHelperTypeName + value: TEngine.Runtime.Entity.DefaultEntityGroupHelper + objectReference: {fileID: 0} - target: {fileID: 3463045026180535776, guid: 161ff7c8132079c4a95e2e4e70ddd41b, type: 3} propertyPath: m_Name diff --git a/Assets/TEngine/EntryPrefab/TEngine.prefab b/Assets/TEngine/EntryPrefab/TEngine.prefab index 9a78b3a8..b91749fd 100644 --- a/Assets/TEngine/EntryPrefab/TEngine.prefab +++ b/Assets/TEngine/EntryPrefab/TEngine.prefab @@ -1,5 +1,56 @@ %YAML 1.1 %TAG !u! tag:unity3d.com,2011: +--- !u!1 &96376811 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 96376812} + - component: {fileID: 96376813} + m_Layer: 0 + m_Name: Entity + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &96376812 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 96376811} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 3463045026180535779} + m_RootOrder: 7 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &96376813 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 96376811} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fc62b60a444ff0c4a952566cb2ecd2fa, type: 3} + m_Name: + m_EditorClassIdentifier: + m_EnableShowEntityUpdateEvent: 0 + m_EnableShowEntityDependencyAssetEvent: 0 + m_InstanceRoot: {fileID: 0} + m_EntityHelperTypeName: UnityGameFramework.Runtime.DefaultEntityHelper + m_CustomEntityHelper: {fileID: 0} + m_EntityGroupHelperTypeName: UnityGameFramework.Runtime.DefaultEntityGroupHelper + m_CustomEntityGroupHelper: {fileID: 0} + m_EntityGroups: [] --- !u!1 &1672025513 GameObject: m_ObjectHideFlags: 0 @@ -334,6 +385,7 @@ Transform: - {fileID: 3463045026010536331} - {fileID: 3463045025307533286} - {fileID: 1672025514} + - {fileID: 96376812} m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/Assets/TEngine/Scripts/Editor/Inspector/EntityComponentInspector.cs b/Assets/TEngine/Scripts/Editor/Inspector/EntityComponentInspector.cs new file mode 100644 index 00000000..6efba58d --- /dev/null +++ b/Assets/TEngine/Scripts/Editor/Inspector/EntityComponentInspector.cs @@ -0,0 +1,84 @@ +using UnityEditor; +using TEngine.Runtime; +using TEngine.Runtime.Entity; + +namespace TEngine.Editor +{ + [CustomEditor(typeof(EntityComponent))] + internal sealed class EntityComponentInspector : TEngineInspector + { + private SerializedProperty m_EnableShowEntityUpdateEvent = null; + private SerializedProperty m_EnableShowEntityDependencyAssetEvent = null; + private SerializedProperty m_InstanceRoot = null; + private SerializedProperty m_EntityGroups = null; + + private HelperInfo m_EntityHelperInfo = new HelperInfo("Entity"); + + private HelperInfo m_EntityGroupHelperInfo = + new HelperInfo("EntityGroup"); + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + serializedObject.Update(); + + EntityComponent t = (EntityComponent)target; + + EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode); + { + EditorGUILayout.PropertyField(m_EnableShowEntityUpdateEvent); + EditorGUILayout.PropertyField(m_EnableShowEntityDependencyAssetEvent); + EditorGUILayout.PropertyField(m_InstanceRoot); + m_EntityHelperInfo.Draw(); + m_EntityGroupHelperInfo.Draw(); + EditorGUILayout.PropertyField(m_EntityGroups, true); + } + EditorGUI.EndDisabledGroup(); + + if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject)) + { + EditorGUILayout.LabelField("Entity Group Count", t.EntityGroupCount.ToString()); + EditorGUILayout.LabelField("Entity Count (Total)", t.EntityCount.ToString()); + IEntityGroup[] entityGroups = t.GetAllEntityGroups(); + foreach (IEntityGroup entityGroup in entityGroups) + { + EditorGUILayout.LabelField(Utility.Text.Format("Entity Count ({0})", entityGroup.Name), + entityGroup.EntityCount.ToString()); + } + } + + serializedObject.ApplyModifiedProperties(); + + Repaint(); + } + + protected override void OnCompileComplete() + { + base.OnCompileComplete(); + + RefreshTypeNames(); + } + + private void OnEnable() + { + m_EnableShowEntityUpdateEvent = serializedObject.FindProperty("m_EnableShowEntityUpdateEvent"); + m_EnableShowEntityDependencyAssetEvent = + serializedObject.FindProperty("m_EnableShowEntityDependencyAssetEvent"); + m_InstanceRoot = serializedObject.FindProperty("m_InstanceRoot"); + m_EntityGroups = serializedObject.FindProperty("m_EntityGroups"); + + m_EntityHelperInfo.Init(serializedObject); + m_EntityGroupHelperInfo.Init(serializedObject); + + RefreshTypeNames(); + } + + private void RefreshTypeNames() + { + m_EntityHelperInfo.Refresh(); + m_EntityGroupHelperInfo.Refresh(); + serializedObject.ApplyModifiedProperties(); + } + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Editor/Inspector/EntityComponentInspector.cs.meta b/Assets/TEngine/Scripts/Editor/Inspector/EntityComponentInspector.cs.meta new file mode 100644 index 00000000..602fc87e --- /dev/null +++ b/Assets/TEngine/Scripts/Editor/Inspector/EntityComponentInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1af7d751dbbd0b747abf134b41b933e3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Entity.meta b/Assets/TEngine/Scripts/Runtime/Entity.meta new file mode 100644 index 00000000..840fc872 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4f0f5b0fa0da6bd4796b1653da8b5f30 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core.meta b/Assets/TEngine/Scripts/Runtime/Entity/Core.meta new file mode 100644 index 00000000..48f98bcc --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b1890cc3fe06b2b4da111ef7ddf8a427 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/AttachEntityInfo.cs b/Assets/TEngine/Scripts/Runtime/Entity/Core/AttachEntityInfo.cs new file mode 100644 index 00000000..cd9e1707 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/AttachEntityInfo.cs @@ -0,0 +1,40 @@ +using UnityEngine; + +namespace TEngine.Runtime.Entity +{ + internal sealed class AttachEntityInfo : IMemory + { + private Transform m_ParentTransform; + private object m_UserData; + + public AttachEntityInfo() + { + m_ParentTransform = null; + m_UserData = null; + } + + public Transform ParentTransform + { + get { return m_ParentTransform; } + } + + public object UserData + { + get { return m_UserData; } + } + + public static AttachEntityInfo Create(Transform parentTransform, object userData) + { + AttachEntityInfo attachEntityInfo = MemoryPool.Acquire(); + attachEntityInfo.m_ParentTransform = parentTransform; + attachEntityInfo.m_UserData = userData; + return attachEntityInfo; + } + + public void Clear() + { + m_ParentTransform = null; + m_UserData = null; + } + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/AttachEntityInfo.cs.meta b/Assets/TEngine/Scripts/Runtime/Entity/Core/AttachEntityInfo.cs.meta new file mode 100644 index 00000000..a9b05601 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/AttachEntityInfo.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a3c6e44db8714628925debf2ddb7f77e +timeCreated: 1662367448 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/Entity.meta b/Assets/TEngine/Scripts/Runtime/Entity/Core/Entity.meta new file mode 100644 index 00000000..1e4ce1d3 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/Entity.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f6741e1112b8479b80f987aa31465d11 +timeCreated: 1662367755 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/Entity/Entity.cs b/Assets/TEngine/Scripts/Runtime/Entity/Core/Entity/Entity.cs new file mode 100644 index 00000000..11aa6359 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/Entity/Entity.cs @@ -0,0 +1,271 @@ +using System; +using UnityEngine; + +namespace TEngine.Runtime.Entity +{ + /// + /// 实体。 + /// + public sealed class Entity : MonoBehaviour, IEntity + { + private int m_Id; + private string m_EntityAssetName; + private IEntityGroup m_EntityGroup; + private EntityLogic m_EntityLogic; + + /// + /// 获取实体编号。 + /// + public int Id + { + get + { + return m_Id; + } + } + + /// + /// 获取实体资源名称。 + /// + public string EntityAssetName + { + get + { + return m_EntityAssetName; + } + } + + /// + /// 获取实体实例。 + /// + public object Handle + { + get + { + return gameObject; + } + } + + /// + /// 获取实体所属的实体组。 + /// + public IEntityGroup EntityGroup + { + get + { + return m_EntityGroup; + } + } + + /// + /// 获取实体逻辑。 + /// + public EntityLogic Logic + { + get + { + return m_EntityLogic; + } + } + + /// + /// 实体初始化。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体所属的实体组。 + /// 是否是新实例。 + /// 用户自定义数据。 + public void OnInit(int entityId, string entityAssetName, IEntityGroup entityGroup, bool isNewInstance, object userData) + { + m_Id = entityId; + m_EntityAssetName = entityAssetName; + if (isNewInstance) + { + m_EntityGroup = entityGroup; + } + else if (m_EntityGroup != entityGroup) + { + Log.Error("Entity group is inconsistent for non-new-instance entity."); + return; + } + + ShowEntityInfo showEntityInfo = (ShowEntityInfo)userData; + Type entityLogicType = showEntityInfo.EntityLogicType; + if (entityLogicType == null) + { + Log.Error("Entity logic type is invalid."); + return; + } + + if (m_EntityLogic != null) + { + if (m_EntityLogic.GetType() == entityLogicType) + { + m_EntityLogic.enabled = true; + return; + } + + Destroy(m_EntityLogic); + m_EntityLogic = null; + } + + m_EntityLogic = gameObject.AddComponent(entityLogicType) as EntityLogic; + if (m_EntityLogic == null) + { + Log.Error("Entity '{0}' can not add entity logic.", entityAssetName); + return; + } + + try + { + m_EntityLogic.OnInit(showEntityInfo.UserData); + } + catch (Exception exception) + { + Log.Error("Entity '[{0}]{1}' OnInit with exception '{2}'.", m_Id.ToString(), m_EntityAssetName, exception.ToString()); + } + } + + /// + /// 实体回收。 + /// + public void OnRecycle() + { + try + { + m_EntityLogic.OnRecycle(); + m_EntityLogic.enabled = false; + } + catch (Exception exception) + { + Log.Error("Entity '[{0}]{1}' OnRecycle with exception '{2}'.", m_Id.ToString(), m_EntityAssetName, exception.ToString()); + } + + m_Id = 0; + } + + /// + /// 实体显示。 + /// + /// 用户自定义数据。 + public void OnShow(object userData) + { + ShowEntityInfo showEntityInfo = (ShowEntityInfo)userData; + try + { + m_EntityLogic.OnShow(showEntityInfo.UserData); + } + catch (Exception exception) + { + Log.Error("Entity '[{0}]{1}' OnShow with exception '{2}'.", m_Id.ToString(), m_EntityAssetName, exception.ToString()); + } + } + + /// + /// 实体隐藏。 + /// + /// 是否是关闭实体管理器时触发。 + /// 用户自定义数据。 + public void OnHide(bool isShutdown, object userData) + { + try + { + m_EntityLogic.OnHide(isShutdown, userData); + } + catch (Exception exception) + { + Log.Error("Entity '[{0}]{1}' OnHide with exception '{2}'.", m_Id.ToString(), m_EntityAssetName, exception.ToString()); + } + } + + /// + /// 实体附加子实体。 + /// + /// 附加的子实体。 + /// 用户自定义数据。 + public void OnAttached(IEntity childEntity, object userData) + { + AttachEntityInfo attachEntityInfo = (AttachEntityInfo)userData; + try + { + m_EntityLogic.OnAttached(((Entity)childEntity).Logic, attachEntityInfo.ParentTransform, attachEntityInfo.UserData); + } + catch (Exception exception) + { + Log.Error("Entity '[{0}]{1}' OnAttached with exception '{2}'.", m_Id.ToString(), m_EntityAssetName, exception.ToString()); + } + } + + /// + /// 实体解除子实体。 + /// + /// 解除的子实体。 + /// 用户自定义数据。 + public void OnDetached(IEntity childEntity, object userData) + { + try + { + m_EntityLogic.OnDetached(((Entity)childEntity).Logic, userData); + } + catch (Exception exception) + { + Log.Error("Entity '[{0}]{1}' OnDetached with exception '{2}'.", m_Id.ToString(), m_EntityAssetName, exception.ToString()); + } + } + + /// + /// 实体附加子实体。 + /// + /// 被附加的父实体。 + /// 用户自定义数据。 + public void OnAttachTo(IEntity parentEntity, object userData) + { + AttachEntityInfo attachEntityInfo = (AttachEntityInfo)userData; + try + { + m_EntityLogic.OnAttachTo(((Entity)parentEntity).Logic, attachEntityInfo.ParentTransform, attachEntityInfo.UserData); + } + catch (Exception exception) + { + Log.Error("Entity '[{0}]{1}' OnAttachTo with exception '{2}'.", m_Id.ToString(), m_EntityAssetName, exception.ToString()); + } + + MemoryPool.Release(attachEntityInfo); + } + + /// + /// 实体解除子实体。 + /// + /// 被解除的父实体。 + /// 用户自定义数据。 + public void OnDetachFrom(IEntity parentEntity, object userData) + { + try + { + m_EntityLogic.OnDetachFrom(((Entity)parentEntity).Logic, userData); + } + catch (Exception exception) + { + Log.Error("Entity '[{0}]{1}' OnDetachFrom with exception '{2}'.", m_Id.ToString(), m_EntityAssetName, exception.ToString()); + } + } + + /// + /// 实体轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + public void OnUpdate(float elapseSeconds, float realElapseSeconds) + { + try + { + m_EntityLogic.OnUpdate(elapseSeconds, realElapseSeconds); + } + catch (Exception exception) + { + Log.Error("Entity '[{0}]{1}' OnUpdate with exception '{2}'.", m_Id.ToString(), m_EntityAssetName, exception.ToString()); + } + } + } +} diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/Entity/Entity.cs.meta b/Assets/TEngine/Scripts/Runtime/Entity/Core/Entity/Entity.cs.meta new file mode 100644 index 00000000..c134f550 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/Entity/Entity.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 903e6994d2a2425dbb2de4a6db599fc4 +timeCreated: 1662367797 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/Entity/EntityLogic.cs b/Assets/TEngine/Scripts/Runtime/Entity/Core/Entity/EntityLogic.cs new file mode 100644 index 00000000..95592269 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/Entity/EntityLogic.cs @@ -0,0 +1,195 @@ +using UnityEngine; + +namespace TEngine.Runtime.Entity +{ + /// + /// 实体逻辑基类。 + /// + public abstract class EntityLogic : MonoBehaviour + { + private bool m_Available = false; + private bool m_Visible = false; + private Entity m_Entity = null; + private Transform m_CachedTransform = null; + private int m_OriginalLayer = 0; + private Transform m_OriginalTransform = null; + + /// + /// 获取实体。 + /// + public Entity Entity + { + get + { + return m_Entity; + } + } + + /// + /// 获取或设置实体名称。 + /// + public string Name + { + get + { + return gameObject.name; + } + set + { + gameObject.name = value; + } + } + + /// + /// 获取实体是否可用。 + /// + public bool Available + { + get + { + return m_Available; + } + } + + /// + /// 获取或设置实体是否可见。 + /// + public bool Visible + { + get + { + return m_Available && m_Visible; + } + set + { + if (!m_Available) + { + Log.Warning("Entity '{0}' is not available.", Name); + return; + } + + if (m_Visible == value) + { + return; + } + + m_Visible = value; + InternalSetVisible(value); + } + } + + /// + /// 获取已缓存的 Transform。 + /// + public Transform CachedTransform + { + get + { + return m_CachedTransform; + } + } + + /// + /// 实体初始化。 + /// + /// 用户自定义数据。 + protected internal virtual void OnInit(object userData) + { + if (m_CachedTransform == null) + { + m_CachedTransform = transform; + } + + m_Entity = GetComponent(); + m_OriginalLayer = gameObject.layer; + m_OriginalTransform = CachedTransform.parent; + } + + /// + /// 实体回收。 + /// + protected internal virtual void OnRecycle() + { + } + + /// + /// 实体显示。 + /// + /// 用户自定义数据。 + protected internal virtual void OnShow(object userData) + { + m_Available = true; + Visible = true; + } + + /// + /// 实体隐藏。 + /// + /// 是否是关闭实体管理器时触发。 + /// 用户自定义数据。 + protected internal virtual void OnHide(bool isShutdown, object userData) + { + gameObject.SetLayerRecursively(m_OriginalLayer); + Visible = false; + m_Available = false; + } + + /// + /// 实体附加子实体。 + /// + /// 附加的子实体。 + /// 被附加父实体的位置。 + /// 用户自定义数据。 + protected internal virtual void OnAttached(EntityLogic childEntity, Transform parentTransform, object userData) + { + } + + /// + /// 实体解除子实体。 + /// + /// 解除的子实体。 + /// 用户自定义数据。 + protected internal virtual void OnDetached(EntityLogic childEntity, object userData) + { + } + + /// + /// 实体附加子实体。 + /// + /// 被附加的父实体。 + /// 被附加父实体的位置。 + /// 用户自定义数据。 + protected internal virtual void OnAttachTo(EntityLogic parentEntity, Transform parentTransform, object userData) + { + CachedTransform.SetParent(parentTransform); + } + + /// + /// 实体解除子实体。 + /// + /// 被解除的父实体。 + /// 用户自定义数据。 + protected internal virtual void OnDetachFrom(EntityLogic parentEntity, object userData) + { + CachedTransform.SetParent(m_OriginalTransform); + } + + /// + /// 实体轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + protected internal virtual void OnUpdate(float elapseSeconds, float realElapseSeconds) + { + } + + /// + /// 设置实体的可见性。 + /// + /// 实体的可见性。 + protected virtual void InternalSetVisible(bool visible) + { + gameObject.SetActive(visible); + } + } +} diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/Entity/EntityLogic.cs.meta b/Assets/TEngine/Scripts/Runtime/Entity/Core/Entity/EntityLogic.cs.meta new file mode 100644 index 00000000..b13b5c2b --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/Entity/EntityLogic.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 329de04d1e564c0c93db5b8798db4805 +timeCreated: 1662367765 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager.meta b/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager.meta new file mode 100644 index 00000000..1d75cc47 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d6610a9afbe2b144184f6503487276c2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.EntityGroup.cs b/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.EntityGroup.cs new file mode 100644 index 00000000..067ed70d --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.EntityGroup.cs @@ -0,0 +1,361 @@ +using System; +using System.Collections.Generic; +using TEngine.Runtime.ObjectPool; + +namespace TEngine.Runtime.Entity +{ + internal sealed partial class EntityManager + { + /// + /// 实体组。 + /// + private sealed class EntityGroup : IEntityGroup + { + private readonly string m_Name; + private readonly IEntityGroupHelper m_EntityGroupHelper; + private readonly IObjectPool m_InstancePool; + private readonly LinkedList m_Entities; + private LinkedListNode m_CachedNode; + + /// + /// 初始化实体组的新实例。 + /// + /// 实体组名称。 + /// 实体实例对象池自动释放可释放对象的间隔秒数。 + /// 实体实例对象池容量。 + /// 实体实例对象池对象过期秒数。 + /// 实体实例对象池的优先级。 + /// 实体组辅助器。 + /// 对象池管理器。 + public EntityGroup(string name, float instanceAutoReleaseInterval, int instanceCapacity, + float instanceExpireTime, int instancePriority, IEntityGroupHelper entityGroupHelper, + IObjectPoolManager objectPoolManager) + { + if (string.IsNullOrEmpty(name)) + { + throw new Exception("Entity group name is invalid."); + } + + if (entityGroupHelper == null) + { + throw new Exception("Entity group helper is invalid."); + } + + m_Name = name; + m_EntityGroupHelper = entityGroupHelper; + m_InstancePool = objectPoolManager.CreateSingleSpawnObjectPool( + Utility.Text.Format("Entity Instance Pool ({0})", name), instanceCapacity, instanceExpireTime, + instancePriority); + m_InstancePool.AutoReleaseInterval = instanceAutoReleaseInterval; + m_Entities = new LinkedList(); + m_CachedNode = null; + } + + /// + /// 获取实体组名称。 + /// + public string Name + { + get { return m_Name; } + } + + /// + /// 获取实体组中实体数量。 + /// + public int EntityCount + { + get { return m_Entities.Count; } + } + + /// + /// 获取或设置实体组实例对象池自动释放可释放对象的间隔秒数。 + /// + public float InstanceAutoReleaseInterval + { + get { return m_InstancePool.AutoReleaseInterval; } + set { m_InstancePool.AutoReleaseInterval = value; } + } + + /// + /// 获取或设置实体组实例对象池的容量。 + /// + public int InstanceCapacity + { + get { return m_InstancePool.Capacity; } + set { m_InstancePool.Capacity = value; } + } + + /// + /// 获取或设置实体组实例对象池对象过期秒数。 + /// + public float InstanceExpireTime + { + get { return m_InstancePool.ExpireTime; } + set { m_InstancePool.ExpireTime = value; } + } + + /// + /// 获取或设置实体组实例对象池的优先级。 + /// + public int InstancePriority + { + get { return m_InstancePool.Priority; } + set { m_InstancePool.Priority = value; } + } + + /// + /// 获取实体组辅助器。 + /// + public IEntityGroupHelper Helper + { + get { return m_EntityGroupHelper; } + } + + /// + /// 实体组轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + public void Update(float elapseSeconds, float realElapseSeconds) + { + LinkedListNode current = m_Entities.First; + while (current != null) + { + m_CachedNode = current.Next; + current.Value.OnUpdate(elapseSeconds, realElapseSeconds); + current = m_CachedNode; + m_CachedNode = null; + } + } + + /// + /// 实体组中是否存在实体。 + /// + /// 实体序列编号。 + /// 实体组中是否存在实体。 + public bool HasEntity(int entityId) + { + foreach (IEntity entity in m_Entities) + { + if (entity.Id == entityId) + { + return true; + } + } + + return false; + } + + /// + /// 实体组中是否存在实体。 + /// + /// 实体资源名称。 + /// 实体组中是否存在实体。 + public bool HasEntity(string entityAssetName) + { + if (string.IsNullOrEmpty(entityAssetName)) + { + throw new Exception("Entity asset name is invalid."); + } + + foreach (IEntity entity in m_Entities) + { + if (entity.EntityAssetName == entityAssetName) + { + return true; + } + } + + return false; + } + + /// + /// 从实体组中获取实体。 + /// + /// 实体序列编号。 + /// 要获取的实体。 + public IEntity GetEntity(int entityId) + { + foreach (IEntity entity in m_Entities) + { + if (entity.Id == entityId) + { + return entity; + } + } + + return null; + } + + /// + /// 从实体组中获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + public IEntity GetEntity(string entityAssetName) + { + if (string.IsNullOrEmpty(entityAssetName)) + { + throw new Exception("Entity asset name is invalid."); + } + + foreach (IEntity entity in m_Entities) + { + if (entity.EntityAssetName == entityAssetName) + { + return entity; + } + } + + return null; + } + + /// + /// 从实体组中获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + public IEntity[] GetEntities(string entityAssetName) + { + if (string.IsNullOrEmpty(entityAssetName)) + { + throw new Exception("Entity asset name is invalid."); + } + + List results = new List(); + foreach (IEntity entity in m_Entities) + { + if (entity.EntityAssetName == entityAssetName) + { + results.Add(entity); + } + } + + return results.ToArray(); + } + + /// + /// 从实体组中获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + public void GetEntities(string entityAssetName, List results) + { + if (string.IsNullOrEmpty(entityAssetName)) + { + throw new Exception("Entity asset name is invalid."); + } + + if (results == null) + { + throw new Exception("Results is invalid."); + } + + results.Clear(); + foreach (IEntity entity in m_Entities) + { + if (entity.EntityAssetName == entityAssetName) + { + results.Add(entity); + } + } + } + + /// + /// 从实体组中获取所有实体。 + /// + /// 实体组中的所有实体。 + public IEntity[] GetAllEntities() + { + List results = new List(); + foreach (IEntity entity in m_Entities) + { + results.Add(entity); + } + + return results.ToArray(); + } + + /// + /// 从实体组中获取所有实体。 + /// + /// 实体组中的所有实体。 + public void GetAllEntities(List results) + { + if (results == null) + { + throw new Exception("Results is invalid."); + } + + results.Clear(); + foreach (IEntity entity in m_Entities) + { + results.Add(entity); + } + } + + /// + /// 往实体组增加实体。 + /// + /// 要增加的实体。 + public void AddEntity(IEntity entity) + { + m_Entities.AddLast(entity); + } + + /// + /// 从实体组移除实体。 + /// + /// 要移除的实体。 + public void RemoveEntity(IEntity entity) + { + if (m_CachedNode != null && m_CachedNode.Value == entity) + { + m_CachedNode = m_CachedNode.Next; + } + + if (!m_Entities.Remove(entity)) + { + throw new Exception(Utility.Text.Format( + "Entity group '{0}' not exists specified entity '[{1}]{2}'.", m_Name, entity.Id, + entity.EntityAssetName)); + } + } + + public void RegisterEntityInstanceObject(EntityInstanceObject obj, bool spawned) + { + m_InstancePool.Register(obj, spawned); + } + + public EntityInstanceObject SpawnEntityInstanceObject(string name) + { + return m_InstancePool.Spawn(name); + } + + public void UnspawnEntity(IEntity entity) + { + m_InstancePool.Unspawn(entity.Handle); + } + + public void SetEntityInstanceLocked(object entityInstance, bool locked) + { + if (entityInstance == null) + { + throw new Exception("Entity instance is invalid."); + } + + m_InstancePool.SetLocked(entityInstance, locked); + } + + public void SetEntityInstancePriority(object entityInstance, int priority) + { + if (entityInstance == null) + { + throw new Exception("Entity instance is invalid."); + } + + m_InstancePool.SetPriority(entityInstance, priority); + } + } + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.EntityGroup.cs.meta b/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.EntityGroup.cs.meta new file mode 100644 index 00000000..396ca013 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.EntityGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a1c60ef7d4f16f04891e04a86c657264 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.EntityInfo.cs b/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.EntityInfo.cs new file mode 100644 index 00000000..51c905c1 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.EntityInfo.cs @@ -0,0 +1,130 @@ +using System; +using System.Collections.Generic; + +namespace TEngine.Runtime.Entity +{ + internal sealed partial class EntityManager + { + /// + /// 实体信息。 + /// + private sealed class EntityInfo : IMemory + { + private IEntity m_Entity; + private EntityStatus m_Status; + private IEntity m_ParentEntity; + private List m_ChildEntities; + + public EntityInfo() + { + m_Entity = null; + m_Status = EntityStatus.Unknown; + m_ParentEntity = null; + m_ChildEntities = new List(); + } + + public IEntity Entity + { + get + { + return m_Entity; + } + } + + public EntityStatus Status + { + get + { + return m_Status; + } + set + { + m_Status = value; + } + } + + public IEntity ParentEntity + { + get + { + return m_ParentEntity; + } + set + { + m_ParentEntity = value; + } + } + + public int ChildEntityCount + { + get + { + return m_ChildEntities.Count; + } + } + + public static EntityInfo Create(IEntity entity) + { + if (entity == null) + { + throw new Exception("Entity is invalid."); + } + + EntityInfo entityInfo = MemoryPool.Acquire(); + entityInfo.m_Entity = entity; + entityInfo.m_Status = EntityStatus.WillInit; + return entityInfo; + } + + public void Clear() + { + m_Entity = null; + m_Status = EntityStatus.Unknown; + m_ParentEntity = null; + m_ChildEntities.Clear(); + } + + public IEntity GetChildEntity() + { + return m_ChildEntities.Count > 0 ? m_ChildEntities[0] : null; + } + + public IEntity[] GetChildEntities() + { + return m_ChildEntities.ToArray(); + } + + public void GetChildEntities(List results) + { + if (results == null) + { + throw new Exception("Results is invalid."); + } + + results.Clear(); + foreach (IEntity childEntity in m_ChildEntities) + { + results.Add(childEntity); + } + } + + public void AddChildEntity(IEntity childEntity) + { + if (m_ChildEntities.Contains(childEntity)) + { + throw new Exception("Can not add child entity which is already exist."); + } + + m_ChildEntities.Add(childEntity); + } + + public void RemoveChildEntity(IEntity childEntity) + { + if (!m_ChildEntities.Remove(childEntity)) + { + throw new Exception("Can not remove child entity which is not exist."); + } + } + } + } +} diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.EntityInfo.cs.meta b/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.EntityInfo.cs.meta new file mode 100644 index 00000000..44877300 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.EntityInfo.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5adfe04298f84665915103f3b7570e4d +timeCreated: 1662358455 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.EntityInstanceObject.cs b/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.EntityInstanceObject.cs new file mode 100644 index 00000000..a61efe41 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.EntityInstanceObject.cs @@ -0,0 +1,54 @@ +using System; +using TEngine.Runtime.ObjectPool; + +namespace TEngine.Runtime.Entity +{ + internal sealed partial class EntityManager + { + /// + /// 实体实例对象。 + /// + private sealed class EntityInstanceObject : ObjectBase + { + private object m_EntityAsset; + private IEntityHelper m_EntityHelper; + + public EntityInstanceObject() + { + m_EntityAsset = null; + m_EntityHelper = null; + } + + public static EntityInstanceObject Create(string name, object entityAsset, object entityInstance, IEntityHelper entityHelper) + { + if (entityAsset == null) + { + throw new Exception("Entity asset is invalid."); + } + + if (entityHelper == null) + { + throw new Exception("Entity helper is invalid."); + } + + EntityInstanceObject entityInstanceObject = MemoryPool.Acquire(); + entityInstanceObject.Initialize(name, entityInstance); + entityInstanceObject.m_EntityAsset = entityAsset; + entityInstanceObject.m_EntityHelper = entityHelper; + return entityInstanceObject; + } + + public override void Clear() + { + base.Clear(); + m_EntityAsset = null; + m_EntityHelper = null; + } + + protected internal override void Release(bool isShutdown) + { + m_EntityHelper.ReleaseEntity(m_EntityAsset, Target); + } + } + } +} diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.EntityInstanceObject.cs.meta b/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.EntityInstanceObject.cs.meta new file mode 100644 index 00000000..142f0ffe --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.EntityInstanceObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: da6cc3aa119f9204382ef80b4fe5a9fc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.EntityStatus.cs b/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.EntityStatus.cs new file mode 100644 index 00000000..19407041 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.EntityStatus.cs @@ -0,0 +1,21 @@ +namespace TEngine.Runtime.Entity +{ + internal sealed partial class EntityManager + { + /// + /// 实体状态。 + /// + private enum EntityStatus : byte + { + Unknown = 0, + WillInit, + Inited, + WillShow, + Showed, + WillHide, + Hidden, + WillRecycle, + Recycled + } + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.EntityStatus.cs.meta b/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.EntityStatus.cs.meta new file mode 100644 index 00000000..f0a85954 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.EntityStatus.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 870878f06eb048a6b3be7129c316cbd8 +timeCreated: 1662358523 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.ShowEntityInfo.cs b/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.ShowEntityInfo.cs new file mode 100644 index 00000000..c97a19f5 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.ShowEntityInfo.cs @@ -0,0 +1,59 @@ +namespace TEngine.Runtime.Entity +{ + internal sealed partial class EntityManager + { + private sealed class ShowEntityInfo : IMemory + { + private int m_SerialId; + private int m_EntityId; + private EntityGroup m_EntityGroup; + private object m_UserData; + + public ShowEntityInfo() + { + m_SerialId = 0; + m_EntityId = 0; + m_EntityGroup = null; + m_UserData = null; + } + + public int SerialId + { + get { return m_SerialId; } + } + + public int EntityId + { + get { return m_EntityId; } + } + + public EntityGroup EntityGroup + { + get { return m_EntityGroup; } + } + + public object UserData + { + get { return m_UserData; } + } + + public static ShowEntityInfo Create(int serialId, int entityId, EntityGroup entityGroup, object userData) + { + ShowEntityInfo showEntityInfo = MemoryPool.Acquire(); + showEntityInfo.m_SerialId = serialId; + showEntityInfo.m_EntityId = entityId; + showEntityInfo.m_EntityGroup = entityGroup; + showEntityInfo.m_UserData = userData; + return showEntityInfo; + } + + public void Clear() + { + m_SerialId = 0; + m_EntityId = 0; + m_EntityGroup = null; + m_UserData = null; + } + } + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.ShowEntityInfo.cs.meta b/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.ShowEntityInfo.cs.meta new file mode 100644 index 00000000..7a87c084 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.ShowEntityInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5a4dce96f95bd01438468b6ad9cef7f7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.cs b/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.cs new file mode 100644 index 00000000..4df7311a --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.cs @@ -0,0 +1,1286 @@ +using System; +using System.Collections.Generic; +using TEngine.Runtime.ObjectPool; + +namespace TEngine.Runtime.Entity +{ + /// + /// 实体管理器。 + /// + internal sealed partial class EntityManager : IEntityManager + { + private readonly Dictionary m_EntityInfos; + private readonly Dictionary m_EntityGroups; + private readonly Dictionary m_EntitiesBeingLoaded; + private readonly HashSet m_EntitiesToReleaseOnLoad; + private readonly Queue m_RecycleQueue; + private readonly LoadAssetCallbacks m_LoadAssetCallbacks; + private IObjectPoolManager m_ObjectPoolManager; + private IEntityHelper m_EntityHelper; + private int m_Serial; + private bool m_IsShutdown; + private Action m_ShowEntitySuccessEventHandler; + private Action m_ShowEntityFailureEventHandler; + private Action m_ShowEntityUpdateEventHandler; + private Action m_ShowEntityDependencyAssetEventHandler; + private Action m_HideEntityCompleteEventHandler; + + /// + /// 初始化实体管理器的新实例。 + /// + public EntityManager() + { + m_EntityInfos = new Dictionary(); + m_EntityGroups = new Dictionary(StringComparer.Ordinal); + m_EntitiesBeingLoaded = new Dictionary(); + m_EntitiesToReleaseOnLoad = new HashSet(); + m_RecycleQueue = new Queue(); + m_LoadAssetCallbacks = new LoadAssetCallbacks(LoadAssetSuccessCallback, LoadAssetFailureCallback, + LoadAssetUpdateCallback, LoadAssetDependencyAssetCallback); + m_ObjectPoolManager = null; + m_EntityHelper = null; + m_Serial = 0; + m_IsShutdown = false; + m_ShowEntitySuccessEventHandler = null; + m_ShowEntityFailureEventHandler = null; + m_ShowEntityUpdateEventHandler = null; + m_ShowEntityDependencyAssetEventHandler = null; + m_HideEntityCompleteEventHandler = null; + } + + /// + /// 获取实体数量。 + /// + public int EntityCount + { + get { return m_EntityInfos.Count; } + } + + /// + /// 获取实体组数量。 + /// + public int EntityGroupCount + { + get { return m_EntityGroups.Count; } + } + + /// + /// 显示实体成功事件。 + /// + public event Action ShowEntitySuccess + { + add { m_ShowEntitySuccessEventHandler += value; } + remove { m_ShowEntitySuccessEventHandler -= value; } + } + + /// + /// 显示实体失败事件。 + /// + public event Action ShowEntityFailure + { + add { m_ShowEntityFailureEventHandler += value; } + remove { m_ShowEntityFailureEventHandler -= value; } + } + + /// + /// 显示实体更新事件。 + /// + public event Action ShowEntityUpdate + { + add { m_ShowEntityUpdateEventHandler += value; } + remove { m_ShowEntityUpdateEventHandler -= value; } + } + + /// + /// 显示实体时加载依赖资源事件。 + /// + public event Action ShowEntityDependencyAsset + { + add { m_ShowEntityDependencyAssetEventHandler += value; } + remove { m_ShowEntityDependencyAssetEventHandler -= value; } + } + + /// + /// 隐藏实体完成事件。 + /// + public event Action HideEntityComplete + { + add { m_HideEntityCompleteEventHandler += value; } + remove { m_HideEntityCompleteEventHandler -= value; } + } + + /// + /// 实体管理器轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + public void Update(float elapseSeconds, float realElapseSeconds) + { + while (m_RecycleQueue.Count > 0) + { + EntityInfo entityInfo = m_RecycleQueue.Dequeue(); + IEntity entity = entityInfo.Entity; + EntityGroup entityGroup = (EntityGroup)entity.EntityGroup; + if (entityGroup == null) + { + throw new Exception("Entity group is invalid."); + } + + entityInfo.Status = EntityStatus.WillRecycle; + entity.OnRecycle(); + entityInfo.Status = EntityStatus.Recycled; + entityGroup.UnspawnEntity(entity); + MemoryPool.Release(entityInfo); + } + + foreach (KeyValuePair entityGroup in m_EntityGroups) + { + entityGroup.Value.Update(elapseSeconds, realElapseSeconds); + } + } + + /// + /// 关闭并清理实体管理器。 + /// + public void ShutDown() + { + m_IsShutdown = true; + HideAllLoadedEntities(); + m_EntityGroups.Clear(); + m_EntitiesBeingLoaded.Clear(); + m_EntitiesToReleaseOnLoad.Clear(); + m_RecycleQueue.Clear(); + } + + /// + /// 设置对象池管理器。 + /// + /// 对象池管理器。 + public void SetObjectPoolManager(IObjectPoolManager objectPoolManager) + { + if (objectPoolManager == null) + { + throw new Exception("Object pool manager is invalid."); + } + + m_ObjectPoolManager = objectPoolManager; + } + + /// + /// 设置实体辅助器。 + /// + /// 实体辅助器。 + public void SetEntityHelper(IEntityHelper entityHelper) + { + if (entityHelper == null) + { + throw new Exception("Entity helper is invalid."); + } + + m_EntityHelper = entityHelper; + } + + /// + /// 是否存在实体组。 + /// + /// 实体组名称。 + /// 是否存在实体组。 + public bool HasEntityGroup(string entityGroupName) + { + if (string.IsNullOrEmpty(entityGroupName)) + { + throw new Exception("Entity group name is invalid."); + } + + return m_EntityGroups.ContainsKey(entityGroupName); + } + + /// + /// 获取实体组。 + /// + /// 实体组名称。 + /// 要获取的实体组。 + public IEntityGroup GetEntityGroup(string entityGroupName) + { + if (string.IsNullOrEmpty(entityGroupName)) + { + throw new Exception("Entity group name is invalid."); + } + + EntityGroup entityGroup = null; + if (m_EntityGroups.TryGetValue(entityGroupName, out entityGroup)) + { + return entityGroup; + } + + return null; + } + + /// + /// 获取所有实体组。 + /// + /// 所有实体组。 + public IEntityGroup[] GetAllEntityGroups() + { + int index = 0; + IEntityGroup[] results = new IEntityGroup[m_EntityGroups.Count]; + foreach (KeyValuePair entityGroup in m_EntityGroups) + { + results[index++] = entityGroup.Value; + } + + return results; + } + + /// + /// 获取所有实体组。 + /// + /// 所有实体组。 + public void GetAllEntityGroups(List results) + { + if (results == null) + { + throw new Exception("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair entityGroup in m_EntityGroups) + { + results.Add(entityGroup.Value); + } + } + + /// + /// 增加实体组。 + /// + /// 实体组名称。 + /// 实体实例对象池自动释放可释放对象的间隔秒数。 + /// 实体实例对象池容量。 + /// 实体实例对象池对象过期秒数。 + /// 实体实例对象池的优先级。 + /// 实体组辅助器。 + /// 是否增加实体组成功。 + public bool AddEntityGroup(string entityGroupName, float instanceAutoReleaseInterval, int instanceCapacity, + float instanceExpireTime, int instancePriority, IEntityGroupHelper entityGroupHelper) + { + if (string.IsNullOrEmpty(entityGroupName)) + { + throw new Exception("Entity group name is invalid."); + } + + if (entityGroupHelper == null) + { + throw new Exception("Entity group helper is invalid."); + } + + if (m_ObjectPoolManager == null) + { + throw new Exception("You must set object pool manager first."); + } + + if (HasEntityGroup(entityGroupName)) + { + return false; + } + + m_EntityGroups.Add(entityGroupName, + new EntityGroup(entityGroupName, instanceAutoReleaseInterval, instanceCapacity, instanceExpireTime, + instancePriority, entityGroupHelper, m_ObjectPoolManager)); + + return true; + } + + /// + /// 是否存在实体。 + /// + /// 实体编号。 + /// 是否存在实体。 + public bool HasEntity(int entityId) + { + return m_EntityInfos.ContainsKey(entityId); + } + + /// + /// 是否存在实体。 + /// + /// 实体资源名称。 + /// 是否存在实体。 + public bool HasEntity(string entityAssetName) + { + if (string.IsNullOrEmpty(entityAssetName)) + { + throw new Exception("Entity asset name is invalid."); + } + + foreach (KeyValuePair entityInfo in m_EntityInfos) + { + if (entityInfo.Value.Entity.EntityAssetName == entityAssetName) + { + return true; + } + } + + return false; + } + + /// + /// 获取实体。 + /// + /// 实体编号。 + /// 要获取的实体。 + public IEntity GetEntity(int entityId) + { + EntityInfo entityInfo = GetEntityInfo(entityId); + if (entityInfo == null) + { + return null; + } + + return entityInfo.Entity; + } + + /// + /// 获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + public IEntity GetEntity(string entityAssetName) + { + if (string.IsNullOrEmpty(entityAssetName)) + { + throw new Exception("Entity asset name is invalid."); + } + + foreach (KeyValuePair entityInfo in m_EntityInfos) + { + if (entityInfo.Value.Entity.EntityAssetName == entityAssetName) + { + return entityInfo.Value.Entity; + } + } + + return null; + } + + /// + /// 获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + public IEntity[] GetEntities(string entityAssetName) + { + if (string.IsNullOrEmpty(entityAssetName)) + { + throw new Exception("Entity asset name is invalid."); + } + + List results = new List(); + foreach (KeyValuePair entityInfo in m_EntityInfos) + { + if (entityInfo.Value.Entity.EntityAssetName == entityAssetName) + { + results.Add(entityInfo.Value.Entity); + } + } + + return results.ToArray(); + } + + /// + /// 获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + public void GetEntities(string entityAssetName, List results) + { + if (string.IsNullOrEmpty(entityAssetName)) + { + throw new Exception("Entity asset name is invalid."); + } + + if (results == null) + { + throw new Exception("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair entityInfo in m_EntityInfos) + { + if (entityInfo.Value.Entity.EntityAssetName == entityAssetName) + { + results.Add(entityInfo.Value.Entity); + } + } + } + + /// + /// 获取所有已加载的实体。 + /// + /// 所有已加载的实体。 + public IEntity[] GetAllLoadedEntities() + { + int index = 0; + IEntity[] results = new IEntity[m_EntityInfos.Count]; + foreach (KeyValuePair entityInfo in m_EntityInfos) + { + results[index++] = entityInfo.Value.Entity; + } + + return results; + } + + /// + /// 获取所有已加载的实体。 + /// + /// 所有已加载的实体。 + public void GetAllLoadedEntities(List results) + { + if (results == null) + { + throw new Exception("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair entityInfo in m_EntityInfos) + { + results.Add(entityInfo.Value.Entity); + } + } + + /// + /// 获取所有正在加载实体的编号。 + /// + /// 所有正在加载实体的编号。 + public int[] GetAllLoadingEntityIds() + { + int index = 0; + int[] results = new int[m_EntitiesBeingLoaded.Count]; + foreach (KeyValuePair entityBeingLoaded in m_EntitiesBeingLoaded) + { + results[index++] = entityBeingLoaded.Key; + } + + return results; + } + + /// + /// 获取所有正在加载实体的编号。 + /// + /// 所有正在加载实体的编号。 + public void GetAllLoadingEntityIds(List results) + { + if (results == null) + { + throw new Exception("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair entityBeingLoaded in m_EntitiesBeingLoaded) + { + results.Add(entityBeingLoaded.Key); + } + } + + /// + /// 是否正在加载实体。 + /// + /// 实体编号。 + /// 是否正在加载实体。 + public bool IsLoadingEntity(int entityId) + { + return m_EntitiesBeingLoaded.ContainsKey(entityId); + } + + /// + /// 是否是合法的实体。 + /// + /// 实体。 + /// 实体是否合法。 + public bool IsValidEntity(IEntity entity) + { + if (entity == null) + { + return false; + } + + return HasEntity(entity.Id); + } + + /// + /// 显示实体。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + public void ShowEntity(int entityId, string entityAssetName, string entityGroupName) + { + ShowEntity(entityId, entityAssetName, entityGroupName, Constant.DefaultPriority, null); + } + + /// + /// 显示实体。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + /// 加载实体资源的优先级。 + public void ShowEntity(int entityId, string entityAssetName, string entityGroupName, int priority) + { + ShowEntity(entityId, entityAssetName, entityGroupName, priority, null); + } + + /// + /// 显示实体。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + /// 用户自定义数据。 + public void ShowEntity(int entityId, string entityAssetName, string entityGroupName, object userData) + { + ShowEntity(entityId, entityAssetName, entityGroupName, Constant.DefaultPriority, userData); + } + + /// + /// 显示实体。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + /// 加载实体资源的优先级。 + /// 用户自定义数据。 + public void ShowEntity(int entityId, string entityAssetName, string entityGroupName, int priority, + object userData) + { + if (m_EntityHelper == null) + { + throw new Exception("You must set entity helper first."); + } + + if (string.IsNullOrEmpty(entityAssetName)) + { + throw new Exception("Entity asset name is invalid."); + } + + if (string.IsNullOrEmpty(entityGroupName)) + { + throw new Exception("Entity group name is invalid."); + } + + if (HasEntity(entityId)) + { + throw new Exception(Utility.Text.Format("Entity id '{0}' is already exist.", entityId)); + } + + if (IsLoadingEntity(entityId)) + { + throw new Exception(Utility.Text.Format("Entity '{0}' is already being loaded.", + entityId)); + } + + EntityGroup entityGroup = (EntityGroup)GetEntityGroup(entityGroupName); + if (entityGroup == null) + { + throw new Exception(Utility.Text.Format("Entity group '{0}' is not exist.", + entityGroupName)); + } + + EntityInstanceObject entityInstanceObject = entityGroup.SpawnEntityInstanceObject(entityAssetName); + if (entityInstanceObject == null) + { + int serialId = ++m_Serial; + m_EntitiesBeingLoaded.Add(entityId, serialId); + TResources.LoadAsset(entityAssetName, priority, m_LoadAssetCallbacks, + ShowEntityInfo.Create(serialId, entityId, entityGroup, userData)); + return; + } + + InternalShowEntity(entityId, entityAssetName, entityGroup, entityInstanceObject.Target, false, 0f, + userData); + } + + /// + /// 隐藏实体。 + /// + /// 实体编号。 + public void HideEntity(int entityId) + { + HideEntity(entityId, null); + } + + /// + /// 隐藏实体。 + /// + /// 实体编号。 + /// 用户自定义数据。 + public void HideEntity(int entityId, object userData) + { + if (IsLoadingEntity(entityId)) + { + m_EntitiesToReleaseOnLoad.Add(m_EntitiesBeingLoaded[entityId]); + m_EntitiesBeingLoaded.Remove(entityId); + return; + } + + EntityInfo entityInfo = GetEntityInfo(entityId); + if (entityInfo == null) + { + throw new Exception(Utility.Text.Format("Can not find entity '{0}'.", entityId)); + } + + InternalHideEntity(entityInfo, userData); + } + + /// + /// 隐藏实体。 + /// + /// 实体。 + public void HideEntity(IEntity entity) + { + HideEntity(entity, null); + } + + /// + /// 隐藏实体。 + /// + /// 实体。 + /// 用户自定义数据。 + public void HideEntity(IEntity entity, object userData) + { + if (entity == null) + { + throw new Exception("Entity is invalid."); + } + + HideEntity(entity.Id, userData); + } + + /// + /// 隐藏所有已加载的实体。 + /// + public void HideAllLoadedEntities() + { + HideAllLoadedEntities(null); + } + + /// + /// 隐藏所有已加载的实体。 + /// + /// 用户自定义数据。 + public void HideAllLoadedEntities(object userData) + { + while (m_EntityInfos.Count > 0) + { + foreach (KeyValuePair entityInfo in m_EntityInfos) + { + InternalHideEntity(entityInfo.Value, userData); + break; + } + } + } + + /// + /// 隐藏所有正在加载的实体。 + /// + public void HideAllLoadingEntities() + { + foreach (KeyValuePair entityBeingLoaded in m_EntitiesBeingLoaded) + { + m_EntitiesToReleaseOnLoad.Add(entityBeingLoaded.Value); + } + + m_EntitiesBeingLoaded.Clear(); + } + + /// + /// 获取父实体。 + /// + /// 要获取父实体的子实体的实体编号。 + /// 子实体的父实体。 + public IEntity GetParentEntity(int childEntityId) + { + EntityInfo childEntityInfo = GetEntityInfo(childEntityId); + if (childEntityInfo == null) + { + throw new Exception(Utility.Text.Format("Can not find child entity '{0}'.", + childEntityId)); + } + + return childEntityInfo.ParentEntity; + } + + /// + /// 获取父实体。 + /// + /// 要获取父实体的子实体。 + /// 子实体的父实体。 + public IEntity GetParentEntity(IEntity childEntity) + { + if (childEntity == null) + { + throw new Exception("Child entity is invalid."); + } + + return GetParentEntity(childEntity.Id); + } + + /// + /// 获取子实体数量。 + /// + /// 要获取子实体数量的父实体的实体编号。 + /// 子实体数量。 + public int GetChildEntityCount(int parentEntityId) + { + EntityInfo parentEntityInfo = GetEntityInfo(parentEntityId); + if (parentEntityInfo == null) + { + throw new Exception(Utility.Text.Format("Can not find parent entity '{0}'.", + parentEntityId)); + } + + return parentEntityInfo.ChildEntityCount; + } + + /// + /// 获取子实体。 + /// + /// 要获取子实体的父实体的实体编号。 + /// 子实体。 + public IEntity GetChildEntity(int parentEntityId) + { + EntityInfo parentEntityInfo = GetEntityInfo(parentEntityId); + if (parentEntityInfo == null) + { + throw new Exception(Utility.Text.Format("Can not find parent entity '{0}'.", + parentEntityId)); + } + + return parentEntityInfo.GetChildEntity(); + } + + /// + /// 获取子实体。 + /// + /// 要获取子实体的父实体。 + /// 子实体。 + public IEntity GetChildEntity(IEntity parentEntity) + { + if (parentEntity == null) + { + throw new Exception("Parent entity is invalid."); + } + + return GetChildEntity(parentEntity.Id); + } + + /// + /// 获取所有子实体。 + /// + /// 要获取所有子实体的父实体的实体编号。 + /// 所有子实体。 + public IEntity[] GetChildEntities(int parentEntityId) + { + EntityInfo parentEntityInfo = GetEntityInfo(parentEntityId); + if (parentEntityInfo == null) + { + throw new Exception(Utility.Text.Format("Can not find parent entity '{0}'.", + parentEntityId)); + } + + return parentEntityInfo.GetChildEntities(); + } + + /// + /// 获取所有子实体。 + /// + /// 要获取所有子实体的父实体的实体编号。 + /// 所有子实体。 + public void GetChildEntities(int parentEntityId, List results) + { + EntityInfo parentEntityInfo = GetEntityInfo(parentEntityId); + if (parentEntityInfo == null) + { + throw new Exception(Utility.Text.Format("Can not find parent entity '{0}'.", + parentEntityId)); + } + + parentEntityInfo.GetChildEntities(results); + } + + /// + /// 获取所有子实体。 + /// + /// 要获取所有子实体的父实体。 + /// 所有子实体。 + public IEntity[] GetChildEntities(IEntity parentEntity) + { + if (parentEntity == null) + { + throw new Exception("Parent entity is invalid."); + } + + return GetChildEntities(parentEntity.Id); + } + + /// + /// 获取所有子实体。 + /// + /// 要获取所有子实体的父实体。 + /// 所有子实体。 + public void GetChildEntities(IEntity parentEntity, List results) + { + if (parentEntity == null) + { + throw new Exception("Parent entity is invalid."); + } + + GetChildEntities(parentEntity.Id, results); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体的实体编号。 + public void AttachEntity(int childEntityId, int parentEntityId) + { + AttachEntity(childEntityId, parentEntityId, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体的实体编号。 + /// 用户自定义数据。 + public void AttachEntity(int childEntityId, int parentEntityId, object userData) + { + if (childEntityId == parentEntityId) + { + throw new Exception(Utility.Text.Format( + "Can not attach entity when child entity id equals to parent entity id '{0}'.", parentEntityId)); + } + + EntityInfo childEntityInfo = GetEntityInfo(childEntityId); + if (childEntityInfo == null) + { + throw new Exception(Utility.Text.Format("Can not find child entity '{0}'.", + childEntityId)); + } + + if (childEntityInfo.Status >= EntityStatus.WillHide) + { + throw new Exception( + Utility.Text.Format("Can not attach entity when child entity status is '{0}'.", + childEntityInfo.Status)); + } + + EntityInfo parentEntityInfo = GetEntityInfo(parentEntityId); + if (parentEntityInfo == null) + { + throw new Exception(Utility.Text.Format("Can not find parent entity '{0}'.", + parentEntityId)); + } + + if (parentEntityInfo.Status >= EntityStatus.WillHide) + { + throw new Exception(Utility.Text.Format( + "Can not attach entity when parent entity status is '{0}'.", parentEntityInfo.Status)); + } + + IEntity childEntity = childEntityInfo.Entity; + IEntity parentEntity = parentEntityInfo.Entity; + DetachEntity(childEntity.Id, userData); + childEntityInfo.ParentEntity = parentEntity; + parentEntityInfo.AddChildEntity(childEntity); + parentEntity.OnAttached(childEntity, userData); + childEntity.OnAttachTo(parentEntity, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体。 + public void AttachEntity(int childEntityId, IEntity parentEntity) + { + AttachEntity(childEntityId, parentEntity, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体。 + /// 用户自定义数据。 + public void AttachEntity(int childEntityId, IEntity parentEntity, object userData) + { + if (parentEntity == null) + { + throw new Exception("Parent entity is invalid."); + } + + AttachEntity(childEntityId, parentEntity.Id, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体的实体编号。 + public void AttachEntity(IEntity childEntity, int parentEntityId) + { + AttachEntity(childEntity, parentEntityId, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体的实体编号。 + /// 用户自定义数据。 + public void AttachEntity(IEntity childEntity, int parentEntityId, object userData) + { + if (childEntity == null) + { + throw new Exception("Child entity is invalid."); + } + + AttachEntity(childEntity.Id, parentEntityId, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体。 + public void AttachEntity(IEntity childEntity, IEntity parentEntity) + { + AttachEntity(childEntity, parentEntity, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体。 + /// 用户自定义数据。 + public void AttachEntity(IEntity childEntity, IEntity parentEntity, object userData) + { + if (childEntity == null) + { + throw new Exception("Child entity is invalid."); + } + + if (parentEntity == null) + { + throw new Exception("Parent entity is invalid."); + } + + AttachEntity(childEntity.Id, parentEntity.Id, userData); + } + + /// + /// 解除子实体。 + /// + /// 要解除的子实体的实体编号。 + public void DetachEntity(int childEntityId) + { + DetachEntity(childEntityId, null); + } + + /// + /// 解除子实体。 + /// + /// 要解除的子实体的实体编号。 + /// 用户自定义数据。 + public void DetachEntity(int childEntityId, object userData) + { + EntityInfo childEntityInfo = GetEntityInfo(childEntityId); + if (childEntityInfo == null) + { + throw new Exception(Utility.Text.Format("Can not find child entity '{0}'.", + childEntityId)); + } + + IEntity parentEntity = childEntityInfo.ParentEntity; + if (parentEntity == null) + { + return; + } + + EntityInfo parentEntityInfo = GetEntityInfo(parentEntity.Id); + if (parentEntityInfo == null) + { + throw new Exception(Utility.Text.Format("Can not find parent entity '{0}'.", + parentEntity.Id)); + } + + IEntity childEntity = childEntityInfo.Entity; + childEntityInfo.ParentEntity = null; + parentEntityInfo.RemoveChildEntity(childEntity); + parentEntity.OnDetached(childEntity, userData); + childEntity.OnDetachFrom(parentEntity, userData); + } + + /// + /// 解除子实体。 + /// + /// 要解除的子实体。 + public void DetachEntity(IEntity childEntity) + { + DetachEntity(childEntity, null); + } + + /// + /// 解除子实体。 + /// + /// 要解除的子实体。 + /// 用户自定义数据。 + public void DetachEntity(IEntity childEntity, object userData) + { + if (childEntity == null) + { + throw new Exception("Child entity is invalid."); + } + + DetachEntity(childEntity.Id, userData); + } + + /// + /// 解除所有子实体。 + /// + /// 被解除的父实体的实体编号。 + public void DetachChildEntities(int parentEntityId) + { + DetachChildEntities(parentEntityId, null); + } + + /// + /// 解除所有子实体。 + /// + /// 被解除的父实体的实体编号。 + /// 用户自定义数据。 + public void DetachChildEntities(int parentEntityId, object userData) + { + EntityInfo parentEntityInfo = GetEntityInfo(parentEntityId); + if (parentEntityInfo == null) + { + throw new Exception(Utility.Text.Format("Can not find parent entity '{0}'.", + parentEntityId)); + } + + while (parentEntityInfo.ChildEntityCount > 0) + { + IEntity childEntity = parentEntityInfo.GetChildEntity(); + DetachEntity(childEntity.Id, userData); + } + } + + /// + /// 解除所有子实体。 + /// + /// 被解除的父实体。 + public void DetachChildEntities(IEntity parentEntity) + { + DetachChildEntities(parentEntity, null); + } + + /// + /// 解除所有子实体。 + /// + /// 被解除的父实体。 + /// 用户自定义数据。 + public void DetachChildEntities(IEntity parentEntity, object userData) + { + if (parentEntity == null) + { + throw new Exception("Parent entity is invalid."); + } + + DetachChildEntities(parentEntity.Id, userData); + } + + /// + /// 获取实体信息。 + /// + /// 实体编号。 + /// 实体信息。 + private EntityInfo GetEntityInfo(int entityId) + { + EntityInfo entityInfo = null; + if (m_EntityInfos.TryGetValue(entityId, out entityInfo)) + { + return entityInfo; + } + + return null; + } + + private void InternalShowEntity(int entityId, string entityAssetName, EntityGroup entityGroup, + object entityInstance, bool isNewInstance, float duration, object userData) + { + try + { + IEntity entity = m_EntityHelper.CreateEntity(entityInstance, entityGroup, userData); + if (entity == null) + { + throw new Exception("Can not create entity in entity helper."); + } + + EntityInfo entityInfo = EntityInfo.Create(entity); + m_EntityInfos.Add(entityId, entityInfo); + entityInfo.Status = EntityStatus.WillInit; + entity.OnInit(entityId, entityAssetName, entityGroup, isNewInstance, userData); + entityInfo.Status = EntityStatus.Inited; + entityGroup.AddEntity(entity); + entityInfo.Status = EntityStatus.WillShow; + entity.OnShow(userData); + entityInfo.Status = EntityStatus.Showed; + + if (m_ShowEntitySuccessEventHandler != null) + { + m_ShowEntitySuccessEventHandler(entity, duration, userData); + } + } + catch (Exception exception) + { + if (m_ShowEntityFailureEventHandler != null) + { + m_ShowEntityFailureEventHandler(entityId, + entityAssetName, entityGroup.Name, exception.ToString(), userData); + return; + } + + throw; + } + } + + private void InternalHideEntity(EntityInfo entityInfo, object userData) + { + while (entityInfo.ChildEntityCount > 0) + { + IEntity childEntity = entityInfo.GetChildEntity(); + HideEntity(childEntity.Id, userData); + } + + if (entityInfo.Status == EntityStatus.Hidden) + { + return; + } + + IEntity entity = entityInfo.Entity; + DetachEntity(entity.Id, userData); + entityInfo.Status = EntityStatus.WillHide; + entity.OnHide(m_IsShutdown, userData); + entityInfo.Status = EntityStatus.Hidden; + + EntityGroup entityGroup = (EntityGroup)entity.EntityGroup; + if (entityGroup == null) + { + throw new Exception("Entity group is invalid."); + } + + entityGroup.RemoveEntity(entity); + if (!m_EntityInfos.Remove(entity.Id)) + { + throw new Exception("Entity info is unmanaged."); + } + + if (m_HideEntityCompleteEventHandler != null) + { + m_HideEntityCompleteEventHandler(entity.Id, entity.EntityAssetName, entityGroup, userData); + } + + m_RecycleQueue.Enqueue(entityInfo); + } + + private void LoadAssetSuccessCallback(string entityAssetName, object entityAsset, float duration, + object userData) + { + ShowEntityInfo showEntityInfo = (ShowEntityInfo)userData; + if (showEntityInfo == null) + { + throw new Exception("Show entity info is invalid."); + } + + if (m_EntitiesToReleaseOnLoad.Contains(showEntityInfo.SerialId)) + { + m_EntitiesToReleaseOnLoad.Remove(showEntityInfo.SerialId); + MemoryPool.Release(showEntityInfo); + m_EntityHelper.ReleaseEntity(entityAsset, null); + return; + } + + m_EntitiesBeingLoaded.Remove(showEntityInfo.EntityId); + EntityInstanceObject entityInstanceObject = EntityInstanceObject.Create(entityAssetName, entityAsset, + m_EntityHelper.InstantiateEntity(entityAsset), m_EntityHelper); + showEntityInfo.EntityGroup.RegisterEntityInstanceObject(entityInstanceObject, true); + + InternalShowEntity(showEntityInfo.EntityId, entityAssetName, showEntityInfo.EntityGroup, + entityInstanceObject.Target, true, duration, showEntityInfo.UserData); + MemoryPool.Release(showEntityInfo); + } + + private void LoadAssetFailureCallback(string entityAssetName, LoadResourceStatus status, string errorMessage, + object userData) + { + ShowEntityInfo showEntityInfo = (ShowEntityInfo)userData; + if (showEntityInfo == null) + { + throw new Exception("Show entity info is invalid."); + } + + if (m_EntitiesToReleaseOnLoad.Contains(showEntityInfo.SerialId)) + { + m_EntitiesToReleaseOnLoad.Remove(showEntityInfo.SerialId); + return; + } + + m_EntitiesBeingLoaded.Remove(showEntityInfo.EntityId); + string appendErrorMessage = + Utility.Text.Format("Load entity failure, asset name '{0}', status '{1}', error message '{2}'.", + entityAssetName, status, errorMessage); + if (m_ShowEntityFailureEventHandler != null) + { + m_ShowEntityFailureEventHandler(showEntityInfo.EntityId, entityAssetName, + showEntityInfo.EntityGroup.Name, appendErrorMessage, showEntityInfo.UserData); + return; + } + + throw new Exception(appendErrorMessage); + } + + private void LoadAssetUpdateCallback(string entityAssetName, float progress, object userData) + { + ShowEntityInfo showEntityInfo = (ShowEntityInfo)userData; + if (showEntityInfo == null) + { + throw new Exception("Show entity info is invalid."); + } + + if (m_ShowEntityUpdateEventHandler != null) + { + m_ShowEntityUpdateEventHandler(showEntityInfo.EntityId, entityAssetName, + showEntityInfo.EntityGroup.Name, progress, showEntityInfo.UserData); + } + } + + private void LoadAssetDependencyAssetCallback(string entityAssetName, string dependencyAssetName, + int loadedCount, int totalCount, object userData) + { + ShowEntityInfo showEntityInfo = (ShowEntityInfo)userData; + if (showEntityInfo == null) + { + throw new Exception("Show entity info is invalid."); + } + + if (m_ShowEntityDependencyAssetEventHandler != null) + { + m_ShowEntityDependencyAssetEventHandler(showEntityInfo.EntityId, entityAssetName, + showEntityInfo.EntityGroup.Name, dependencyAssetName, loadedCount, totalCount, + showEntityInfo.UserData); + } + } + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.cs.meta b/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.cs.meta new file mode 100644 index 00000000..831a1da7 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/EntityManager/EntityManager.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d0a1321b9ce04887a06a1c0dcec06269 +timeCreated: 1662358334 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/Helper.meta b/Assets/TEngine/Scripts/Runtime/Entity/Core/Helper.meta new file mode 100644 index 00000000..e23934ce --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/Helper.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fbd6ae736ae43794d84817469577cd4b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/Helper/EntityGroupHelperBase.cs b/Assets/TEngine/Scripts/Runtime/Entity/Core/Helper/EntityGroupHelperBase.cs new file mode 100644 index 00000000..016382c1 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/Helper/EntityGroupHelperBase.cs @@ -0,0 +1,11 @@ +using UnityEngine; + +namespace TEngine.Runtime.Entity +{ + /// + /// 实体组辅助器基类。 + /// + public abstract class EntityGroupHelperBase : MonoBehaviour, IEntityGroupHelper + { + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/Helper/EntityGroupHelperBase.cs.meta b/Assets/TEngine/Scripts/Runtime/Entity/Core/Helper/EntityGroupHelperBase.cs.meta new file mode 100644 index 00000000..b372dd5b --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/Helper/EntityGroupHelperBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fc047b6e51dd7ef4991643ff2142afcd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/Helper/EntityHelperBase.cs b/Assets/TEngine/Scripts/Runtime/Entity/Core/Helper/EntityHelperBase.cs new file mode 100644 index 00000000..d22a85d4 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/Helper/EntityHelperBase.cs @@ -0,0 +1,33 @@ +using UnityEngine; + +namespace TEngine.Runtime.Entity +{ + /// + /// 实体辅助器基类。 + /// + public abstract class EntityHelperBase : MonoBehaviour, IEntityHelper + { + /// + /// 实例化实体。 + /// + /// 要实例化的实体资源。 + /// 实例化后的实体。 + public abstract object InstantiateEntity(object entityAsset); + + /// + /// 创建实体。 + /// + /// 实体实例。 + /// 实体所属的实体组。 + /// 用户自定义数据。 + /// 实体。 + public abstract IEntity CreateEntity(object entityInstance, IEntityGroup entityGroup, object userData); + + /// + /// 释放实体。 + /// + /// 要释放的实体资源。 + /// 要释放的实体实例。 + public abstract void ReleaseEntity(object entityAsset, object entityInstance); + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/Helper/EntityHelperBase.cs.meta b/Assets/TEngine/Scripts/Runtime/Entity/Core/Helper/EntityHelperBase.cs.meta new file mode 100644 index 00000000..da99f192 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/Helper/EntityHelperBase.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3afe009e65b14bfbb07b98f3c033c740 +timeCreated: 1662367200 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface.meta b/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface.meta new file mode 100644 index 00000000..456bae34 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c5ed11bdb1bb4113bb3b499775670817 +timeCreated: 1662358264 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntity.cs b/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntity.cs new file mode 100644 index 00000000..ba2c6d46 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntity.cs @@ -0,0 +1,103 @@ +namespace TEngine.Runtime.Entity +{ + /// + /// 实体接口。 + /// + public interface IEntity + { + /// + /// 获取实体编号。 + /// + int Id + { + get; + } + + /// + /// 获取实体资源名称。 + /// + string EntityAssetName + { + get; + } + + /// + /// 获取实体实例。 + /// + object Handle + { + get; + } + + /// + /// 获取实体所属的实体组。 + /// + IEntityGroup EntityGroup + { + get; + } + + /// + /// 实体初始化。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体所属的实体组。 + /// 是否是新实例。 + /// 用户自定义数据。 + void OnInit(int entityId, string entityAssetName, IEntityGroup entityGroup, bool isNewInstance, object userData); + + /// + /// 实体回收。 + /// + void OnRecycle(); + + /// + /// 实体显示。 + /// + /// 用户自定义数据。 + void OnShow(object userData); + + /// + /// 实体隐藏。 + /// + /// 是否是关闭实体管理器时触发。 + /// 用户自定义数据。 + void OnHide(bool isShutdown, object userData); + + /// + /// 实体附加子实体。 + /// + /// 附加的子实体。 + /// 用户自定义数据。 + void OnAttached(IEntity childEntity, object userData); + + /// + /// 实体解除子实体。 + /// + /// 解除的子实体。 + /// 用户自定义数据。 + void OnDetached(IEntity childEntity, object userData); + + /// + /// 实体附加子实体。 + /// + /// 被附加的父实体。 + /// 用户自定义数据。 + void OnAttachTo(IEntity parentEntity, object userData); + + /// + /// 实体解除子实体。 + /// + /// 被解除的父实体。 + /// 用户自定义数据。 + void OnDetachFrom(IEntity parentEntity, object userData); + + /// + /// 实体轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + void OnUpdate(float elapseSeconds, float realElapseSeconds); + } +} diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntity.cs.meta b/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntity.cs.meta new file mode 100644 index 00000000..9fc597df --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntity.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e277c35f794ac274ca4b108ee863f8b1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntityGroup.cs b/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntityGroup.cs new file mode 100644 index 00000000..c593c46f --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntityGroup.cs @@ -0,0 +1,113 @@ +using System.Collections.Generic; + +namespace TEngine.Runtime.Entity +{ + /// + /// 实体组接口。 + /// + public interface IEntityGroup + { + /// + /// 获取实体组名称。 + /// + string Name { get; } + + /// + /// 获取实体组中实体数量。 + /// + int EntityCount { get; } + + /// + /// 获取或设置实体组实例对象池自动释放可释放对象的间隔秒数。 + /// + float InstanceAutoReleaseInterval { get; set; } + + /// + /// 获取或设置实体组实例对象池的容量。 + /// + int InstanceCapacity { get; set; } + + /// + /// 获取或设置实体组实例对象池对象过期秒数。 + /// + float InstanceExpireTime { get; set; } + + /// + /// 获取或设置实体组实例对象池的优先级。 + /// + int InstancePriority { get; set; } + + /// + /// 获取实体组辅助器。 + /// + IEntityGroupHelper Helper { get; } + + /// + /// 实体组中是否存在实体。 + /// + /// 实体序列编号。 + /// 实体组中是否存在实体。 + bool HasEntity(int entityId); + + /// + /// 实体组中是否存在实体。 + /// + /// 实体资源名称。 + /// 实体组中是否存在实体。 + bool HasEntity(string entityAssetName); + + /// + /// 从实体组中获取实体。 + /// + /// 实体序列编号。 + /// 要获取的实体。 + IEntity GetEntity(int entityId); + + /// + /// 从实体组中获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + IEntity GetEntity(string entityAssetName); + + /// + /// 从实体组中获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + IEntity[] GetEntities(string entityAssetName); + + /// + /// 从实体组中获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + void GetEntities(string entityAssetName, List results); + + /// + /// 从实体组中获取所有实体。 + /// + /// 实体组中的所有实体。 + IEntity[] GetAllEntities(); + + /// + /// 从实体组中获取所有实体。 + /// + /// 实体组中的所有实体。 + void GetAllEntities(List results); + + /// + /// 设置实体实例是否被加锁。 + /// + /// 实体实例。 + /// 实体实例是否被加锁。 + void SetEntityInstanceLocked(object entityInstance, bool locked); + + /// + /// 设置实体实例的优先级。 + /// + /// 实体实例。 + /// 实体实例优先级。 + void SetEntityInstancePriority(object entityInstance, int priority); + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntityGroup.cs.meta b/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntityGroup.cs.meta new file mode 100644 index 00000000..ee08322f --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntityGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e08cae97715f4184595d43d984e4678b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntityGroupHelper.cs b/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntityGroupHelper.cs new file mode 100644 index 00000000..efbc6c23 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntityGroupHelper.cs @@ -0,0 +1,7 @@ +namespace TEngine.Runtime.Entity +{ + public interface IEntityGroupHelper + { + + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntityGroupHelper.cs.meta b/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntityGroupHelper.cs.meta new file mode 100644 index 00000000..86eba2e4 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntityGroupHelper.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 93a0420819e041d88ad86f4a337525af +timeCreated: 1662358160 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntityHelper.cs b/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntityHelper.cs new file mode 100644 index 00000000..4db39873 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntityHelper.cs @@ -0,0 +1,31 @@ +namespace TEngine.Runtime.Entity +{ + /// + /// 实体辅助器接口。 + /// + public interface IEntityHelper + { + /// + /// 实例化实体。 + /// + /// 要实例化的实体资源。 + /// 实例化后的实体。 + object InstantiateEntity(object entityAsset); + + /// + /// 创建实体。 + /// + /// 实体实例。 + /// 实体所属的实体组。 + /// 用户自定义数据。 + /// 实体。 + IEntity CreateEntity(object entityInstance, IEntityGroup entityGroup, object userData); + + /// + /// 释放实体。 + /// + /// 要释放的实体资源。 + /// 要释放的实体实例。 + void ReleaseEntity(object entityAsset, object entityInstance); + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntityHelper.cs.meta b/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntityHelper.cs.meta new file mode 100644 index 00000000..a6a7dad9 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntityHelper.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5afe8f7284924202b37194d224d25300 +timeCreated: 1662358246 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntityManager.cs b/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntityManager.cs new file mode 100644 index 00000000..c8a8e69d --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntityManager.cs @@ -0,0 +1,443 @@ +using System; +using System.Collections.Generic; +using TEngine.Runtime.ObjectPool; + +namespace TEngine.Runtime.Entity +{ + /// + /// 实体管理器接口。 + /// + public interface IEntityManager + { + /// + /// 获取实体数量。 + /// + int EntityCount { get; } + + /// + /// 获取实体组数量。 + /// + int EntityGroupCount { get; } + + /// + /// 显示实体成功事件。 + /// + event Action ShowEntitySuccess; + + /// + /// 显示实体失败事件。 + /// + event Action ShowEntityFailure; + + /// + /// 显示实体更新事件。 + /// + event Action ShowEntityUpdate; + + /// + /// 显示实体时加载依赖资源事件。 + /// + event Action ShowEntityDependencyAsset; + + /// + /// 隐藏实体完成事件。 + /// + event Action HideEntityComplete; + + /// + /// 设置对象池管理器。 + /// + /// 对象池管理器。 + void SetObjectPoolManager(IObjectPoolManager objectPoolManager); + + /// + /// 设置实体辅助器。 + /// + /// 实体辅助器。 + void SetEntityHelper(IEntityHelper entityHelper); + + /// + /// 是否存在实体组。 + /// + /// 实体组名称。 + /// 是否存在实体组。 + bool HasEntityGroup(string entityGroupName); + + /// + /// 获取实体组。 + /// + /// 实体组名称。 + /// 要获取的实体组。 + IEntityGroup GetEntityGroup(string entityGroupName); + + /// + /// 获取所有实体组。 + /// + /// 所有实体组。 + IEntityGroup[] GetAllEntityGroups(); + + /// + /// 获取所有实体组。 + /// + /// 所有实体组。 + void GetAllEntityGroups(List results); + + /// + /// 增加实体组。 + /// + /// 实体组名称。 + /// 实体实例对象池自动释放可释放对象的间隔秒数。 + /// 实体实例对象池容量。 + /// 实体实例对象池对象过期秒数。 + /// 实体实例对象池的优先级。 + /// 实体组辅助器。 + /// 是否增加实体组成功。 + bool AddEntityGroup(string entityGroupName, float instanceAutoReleaseInterval, int instanceCapacity, + float instanceExpireTime, int instancePriority, IEntityGroupHelper entityGroupHelper); + + /// + /// 是否存在实体。 + /// + /// 实体编号。 + /// 是否存在实体。 + bool HasEntity(int entityId); + + /// + /// 是否存在实体。 + /// + /// 实体资源名称。 + /// 是否存在实体。 + bool HasEntity(string entityAssetName); + + /// + /// 获取实体。 + /// + /// 实体编号。 + /// 要获取的实体。 + IEntity GetEntity(int entityId); + + /// + /// 获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + IEntity GetEntity(string entityAssetName); + + /// + /// 获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + IEntity[] GetEntities(string entityAssetName); + + /// + /// 获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + void GetEntities(string entityAssetName, List results); + + /// + /// 获取所有已加载的实体。 + /// + /// 所有已加载的实体。 + IEntity[] GetAllLoadedEntities(); + + /// + /// 获取所有已加载的实体。 + /// + /// 所有已加载的实体。 + void GetAllLoadedEntities(List results); + + /// + /// 获取所有正在加载实体的编号。 + /// + /// 所有正在加载实体的编号。 + int[] GetAllLoadingEntityIds(); + + /// + /// 获取所有正在加载实体的编号。 + /// + /// 所有正在加载实体的编号。 + void GetAllLoadingEntityIds(List results); + + /// + /// 是否正在加载实体。 + /// + /// 实体编号。 + /// 是否正在加载实体。 + bool IsLoadingEntity(int entityId); + + /// + /// 是否是合法的实体。 + /// + /// 实体。 + /// 实体是否合法。 + bool IsValidEntity(IEntity entity); + + /// + /// 显示实体。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + void ShowEntity(int entityId, string entityAssetName, string entityGroupName); + + /// + /// 显示实体。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + /// 加载实体资源的优先级。 + void ShowEntity(int entityId, string entityAssetName, string entityGroupName, int priority); + + /// + /// 显示实体。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + /// 用户自定义数据。 + void ShowEntity(int entityId, string entityAssetName, string entityGroupName, object userData); + + /// + /// 显示实体。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + /// 加载实体资源的优先级。 + /// 用户自定义数据。 + void ShowEntity(int entityId, string entityAssetName, string entityGroupName, int priority, object userData); + + /// + /// 隐藏实体。 + /// + /// 实体编号。 + void HideEntity(int entityId); + + /// + /// 隐藏实体。 + /// + /// 实体编号。 + /// 用户自定义数据。 + void HideEntity(int entityId, object userData); + + /// + /// 隐藏实体。 + /// + /// 实体。 + void HideEntity(IEntity entity); + + /// + /// 隐藏实体。 + /// + /// 实体。 + /// 用户自定义数据。 + void HideEntity(IEntity entity, object userData); + + /// + /// 隐藏所有已加载的实体。 + /// + void HideAllLoadedEntities(); + + /// + /// 隐藏所有已加载的实体。 + /// + /// 用户自定义数据。 + void HideAllLoadedEntities(object userData); + + /// + /// 隐藏所有正在加载的实体。 + /// + void HideAllLoadingEntities(); + + /// + /// 获取父实体。 + /// + /// 要获取父实体的子实体的实体编号。 + /// 子实体的父实体。 + IEntity GetParentEntity(int childEntityId); + + /// + /// 获取父实体。 + /// + /// 要获取父实体的子实体。 + /// 子实体的父实体。 + IEntity GetParentEntity(IEntity childEntity); + + /// + /// 获取子实体数量。 + /// + /// 要获取子实体数量的父实体的实体编号。 + /// 子实体数量。 + int GetChildEntityCount(int parentEntityId); + + /// + /// 获取子实体。 + /// + /// 要获取子实体的父实体的实体编号。 + /// 子实体。 + IEntity GetChildEntity(int parentEntityId); + + /// + /// 获取子实体。 + /// + /// 要获取子实体的父实体。 + /// 子实体。 + IEntity GetChildEntity(IEntity parentEntity); + + /// + /// 获取所有子实体。 + /// + /// 要获取所有子实体的父实体的实体编号。 + /// 所有子实体。 + IEntity[] GetChildEntities(int parentEntityId); + + /// + /// 获取所有子实体。 + /// + /// 要获取所有子实体的父实体的实体编号。 + /// 所有子实体。 + void GetChildEntities(int parentEntityId, List results); + + /// + /// 获取所有子实体。 + /// + /// 要获取所有子实体的父实体。 + /// 所有子实体。 + IEntity[] GetChildEntities(IEntity parentEntity); + + /// + /// 获取所有子实体。 + /// + /// 要获取所有子实体的父实体。 + /// 所有子实体。 + void GetChildEntities(IEntity parentEntity, List results); + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体的实体编号。 + void AttachEntity(int childEntityId, int parentEntityId); + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体的实体编号。 + /// 用户自定义数据。 + void AttachEntity(int childEntityId, int parentEntityId, object userData); + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体。 + void AttachEntity(int childEntityId, IEntity parentEntity); + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体。 + /// 用户自定义数据。 + void AttachEntity(int childEntityId, IEntity parentEntity, object userData); + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体的实体编号。 + void AttachEntity(IEntity childEntity, int parentEntityId); + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体的实体编号。 + /// 用户自定义数据。 + void AttachEntity(IEntity childEntity, int parentEntityId, object userData); + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体。 + void AttachEntity(IEntity childEntity, IEntity parentEntity); + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体。 + /// 用户自定义数据。 + void AttachEntity(IEntity childEntity, IEntity parentEntity, object userData); + + /// + /// 解除子实体。 + /// + /// 要解除的子实体的实体编号。 + void DetachEntity(int childEntityId); + + /// + /// 解除子实体。 + /// + /// 要解除的子实体的实体编号。 + /// 用户自定义数据。 + void DetachEntity(int childEntityId, object userData); + + /// + /// 解除子实体。 + /// + /// 要解除的子实体。 + void DetachEntity(IEntity childEntity); + + /// + /// 解除子实体。 + /// + /// 要解除的子实体。 + /// 用户自定义数据。 + void DetachEntity(IEntity childEntity, object userData); + + /// + /// 解除所有子实体。 + /// + /// 被解除的父实体的实体编号。 + void DetachChildEntities(int parentEntityId); + + /// + /// 解除所有子实体。 + /// + /// 被解除的父实体的实体编号。 + /// 用户自定义数据。 + void DetachChildEntities(int parentEntityId, object userData); + + /// + /// 解除所有子实体。 + /// + /// 被解除的父实体。 + void DetachChildEntities(IEntity parentEntity); + + /// + /// 解除所有子实体。 + /// + /// 被解除的父实体。 + /// 用户自定义数据。 + void DetachChildEntities(IEntity parentEntity, object userData); + + /// + /// 实体管理器轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + void Update(float elapseSeconds, float realElapseSeconds); + + /// + /// 关闭并清理实体管理器。 + /// + void ShutDown(); + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntityManager.cs.meta b/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntityManager.cs.meta new file mode 100644 index 00000000..4b0b00f6 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/Interface/IEntityManager.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9deb38cdf5564cc9990eceff01f894d9 +timeCreated: 1662358217 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/ShowEntityInfo.cs b/Assets/TEngine/Scripts/Runtime/Entity/Core/ShowEntityInfo.cs new file mode 100644 index 00000000..e362e2b3 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/ShowEntityInfo.cs @@ -0,0 +1,40 @@ +using System; + +namespace TEngine.Runtime.Entity +{ + internal sealed class ShowEntityInfo : IMemory + { + private Type m_EntityLogicType; + private object m_UserData; + + public ShowEntityInfo() + { + m_EntityLogicType = null; + m_UserData = null; + } + + public Type EntityLogicType + { + get { return m_EntityLogicType; } + } + + public object UserData + { + get { return m_UserData; } + } + + public static ShowEntityInfo Create(Type entityLogicType, object userData) + { + ShowEntityInfo showEntityInfo = MemoryPool.Acquire(); + showEntityInfo.m_EntityLogicType = entityLogicType; + showEntityInfo.m_UserData = userData; + return showEntityInfo; + } + + public void Clear() + { + m_EntityLogicType = null; + m_UserData = null; + } + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/Core/ShowEntityInfo.cs.meta b/Assets/TEngine/Scripts/Runtime/Entity/Core/ShowEntityInfo.cs.meta new file mode 100644 index 00000000..3d2a7308 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/Core/ShowEntityInfo.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ea3881241f5746719af12b872f51d7f8 +timeCreated: 1662367905 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/DefaultEntityGroupHelper.cs b/Assets/TEngine/Scripts/Runtime/Entity/DefaultEntityGroupHelper.cs new file mode 100644 index 00000000..90f9f24c --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/DefaultEntityGroupHelper.cs @@ -0,0 +1,9 @@ +namespace TEngine.Runtime.Entity +{ + /// + /// 默认实体组辅助器。 + /// + public class DefaultEntityGroupHelper : EntityGroupHelperBase + { + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/DefaultEntityGroupHelper.cs.meta b/Assets/TEngine/Scripts/Runtime/Entity/DefaultEntityGroupHelper.cs.meta new file mode 100644 index 00000000..a0b410f7 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/DefaultEntityGroupHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 96fc5bb7ba6933342a0b5b54bd358b59 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Entity/DefaultEntityHelper.cs b/Assets/TEngine/Scripts/Runtime/Entity/DefaultEntityHelper.cs new file mode 100644 index 00000000..50e0d225 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/DefaultEntityHelper.cs @@ -0,0 +1,52 @@ +using UnityEngine; + +namespace TEngine.Runtime.Entity +{ + /// + /// 默认实体辅助器。 + /// + public class DefaultEntityHelper : EntityHelperBase + { + /// + /// 实例化实体。 + /// + /// 要实例化的实体资源。 + /// 实例化后的实体。 + public override object InstantiateEntity(object entityAsset) + { + return Instantiate((Object)entityAsset); + } + + /// + /// 创建实体。 + /// + /// 实体实例。 + /// 实体所属的实体组。 + /// 用户自定义数据。 + /// 实体。 + public override IEntity CreateEntity(object entityInstance, IEntityGroup entityGroup, object userData) + { + GameObject gameObject = entityInstance as GameObject; + if (gameObject == null) + { + Log.Error("Entity instance is invalid."); + return null; + } + + Transform transform = gameObject.transform; + transform.SetParent(((MonoBehaviour)entityGroup.Helper).transform); + + return gameObject.GetOrAddComponent(); + } + + /// + /// 释放实体。 + /// + /// 要释放的实体资源。 + /// 要释放的实体实例。 + public override void ReleaseEntity(object entityAsset, object entityInstance) + { + Destroy((Object)entityInstance); + } + } +} diff --git a/Assets/TEngine/Scripts/Runtime/Entity/DefaultEntityHelper.cs.meta b/Assets/TEngine/Scripts/Runtime/Entity/DefaultEntityHelper.cs.meta new file mode 100644 index 00000000..bd70a5b3 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/DefaultEntityHelper.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d984472e4ffc461998251d10ac639577 +timeCreated: 1662368182 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/EntityComponent.EntityGroup.cs b/Assets/TEngine/Scripts/Runtime/Entity/EntityComponent.EntityGroup.cs new file mode 100644 index 00000000..37531162 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/EntityComponent.EntityGroup.cs @@ -0,0 +1,47 @@ +using System; +using UnityEngine; + +namespace TEngine.Runtime.Entity +{ + public sealed partial class EntityComponent + { + [Serializable] + private sealed class EntityGroup + { + [SerializeField] private string m_Name = null; + + [SerializeField] private float m_InstanceAutoReleaseInterval = 60f; + + [SerializeField] private int m_InstanceCapacity = 16; + + [SerializeField] private float m_InstanceExpireTime = 60f; + + [SerializeField] private int m_InstancePriority = 0; + + public string Name + { + get { return m_Name; } + } + + public float InstanceAutoReleaseInterval + { + get { return m_InstanceAutoReleaseInterval; } + } + + public int InstanceCapacity + { + get { return m_InstanceCapacity; } + } + + public float InstanceExpireTime + { + get { return m_InstanceExpireTime; } + } + + public int InstancePriority + { + get { return m_InstancePriority; } + } + } + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/EntityComponent.EntityGroup.cs.meta b/Assets/TEngine/Scripts/Runtime/Entity/EntityComponent.EntityGroup.cs.meta new file mode 100644 index 00000000..0c79dea3 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/EntityComponent.EntityGroup.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1c0f66a106324c0ca6deff08e55f3777 +timeCreated: 1662368917 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Entity/EntityComponent.cs b/Assets/TEngine/Scripts/Runtime/Entity/EntityComponent.cs new file mode 100644 index 00000000..3b8c673a --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/EntityComponent.cs @@ -0,0 +1,1166 @@ +using System; +using System.Collections.Generic; +using TEngine.Runtime.ObjectPool; +using UnityEngine; + +namespace TEngine.Runtime.Entity +{ + /// + /// 实体组件。 + /// + [DisallowMultipleComponent] + [AddComponentMenu("TEngine/EntityManager")] + public sealed partial class EntityComponent : UnitySingleton + { + private const int DefaultPriority = 0; + + private IEntityManager m_EntityManager = null; + + private readonly List m_InternalEntityResults = new List(); + + [SerializeField] + private bool m_EnableShowEntityUpdateEvent = false; + + [SerializeField] + private bool m_EnableShowEntityDependencyAssetEvent = false; + + [SerializeField] + private Transform m_InstanceRoot = null; + + [SerializeField] + private string m_EntityHelperTypeName = "UnityGameFramework.Runtime.DefaultEntityHelper"; + + [SerializeField] + private EntityHelperBase m_CustomEntityHelper = null; + + [SerializeField] + private string m_EntityGroupHelperTypeName = "UnityGameFramework.Runtime.DefaultEntityGroupHelper"; + + [SerializeField] + private EntityGroupHelperBase m_CustomEntityGroupHelper = null; + + [SerializeField] + private EntityGroup[] m_EntityGroups = null; + + /// + /// 获取实体数量。 + /// + public int EntityCount + { + get + { + return m_EntityManager.EntityCount; + } + } + + /// + /// 获取实体组数量。 + /// + public int EntityGroupCount + { + get + { + return m_EntityManager.EntityGroupCount; + } + } + + /// + /// 游戏框架组件初始化。 + /// + public override void Awake() + { + base.Awake(); + + m_EntityManager = new EntityManager(); + if (m_EntityManager == null) + { + Log.Fatal("Entity manager is invalid."); + return; + } + + m_EntityManager.ShowEntitySuccess += OnShowEntitySuccess; + m_EntityManager.ShowEntityFailure += OnShowEntityFailure; + + if (m_EnableShowEntityUpdateEvent) + { + m_EntityManager.ShowEntityUpdate += OnShowEntityUpdate; + } + + if (m_EnableShowEntityDependencyAssetEvent) + { + m_EntityManager.ShowEntityDependencyAsset += OnShowEntityDependencyAsset; + } + + m_EntityManager.HideEntityComplete += OnHideEntityComplete; + } + + private void Start() + { + m_EntityManager.SetObjectPoolManager(ObjectPoolComponent.Instance.PoolManager); + + EntityHelperBase entityHelper = Helper.CreateHelper(m_EntityHelperTypeName, m_CustomEntityHelper); + if (entityHelper == null) + { + Log.Error("Can not create entity helper."); + return; + } + + entityHelper.name = "Entity Helper"; + Transform transform = entityHelper.transform; + transform.SetParent(this.transform); + transform.localScale = Vector3.one; + + m_EntityManager.SetEntityHelper(entityHelper); + + if (m_InstanceRoot == null) + { + m_InstanceRoot = new GameObject("Entity Instances").transform; + m_InstanceRoot.SetParent(gameObject.transform); + m_InstanceRoot.localScale = Vector3.one; + } + + for (int i = 0; i < m_EntityGroups.Length; i++) + { + if (!AddEntityGroup(m_EntityGroups[i].Name, m_EntityGroups[i].InstanceAutoReleaseInterval, m_EntityGroups[i].InstanceCapacity, m_EntityGroups[i].InstanceExpireTime, m_EntityGroups[i].InstancePriority)) + { + Log.Warning("Add entity group '{0}' failure.", m_EntityGroups[i].Name); + continue; + } + } + } + + /// + /// 是否存在实体组。 + /// + /// 实体组名称。 + /// 是否存在实体组。 + public bool HasEntityGroup(string entityGroupName) + { + return m_EntityManager.HasEntityGroup(entityGroupName); + } + + /// + /// 获取实体组。 + /// + /// 实体组名称。 + /// 要获取的实体组。 + public IEntityGroup GetEntityGroup(string entityGroupName) + { + return m_EntityManager.GetEntityGroup(entityGroupName); + } + + /// + /// 获取所有实体组。 + /// + /// 所有实体组。 + public IEntityGroup[] GetAllEntityGroups() + { + return m_EntityManager.GetAllEntityGroups(); + } + + /// + /// 获取所有实体组。 + /// + /// 所有实体组。 + public void GetAllEntityGroups(List results) + { + m_EntityManager.GetAllEntityGroups(results); + } + + /// + /// 增加实体组。 + /// + /// 实体组名称。 + /// 实体实例对象池自动释放可释放对象的间隔秒数。 + /// 实体实例对象池容量。 + /// 实体实例对象池对象过期秒数。 + /// 实体实例对象池的优先级。 + /// 是否增加实体组成功。 + public bool AddEntityGroup(string entityGroupName, float instanceAutoReleaseInterval, int instanceCapacity, float instanceExpireTime, int instancePriority) + { + if (m_EntityManager.HasEntityGroup(entityGroupName)) + { + return false; + } + + EntityGroupHelperBase entityGroupHelper = Helper.CreateHelper(m_EntityGroupHelperTypeName, m_CustomEntityGroupHelper, EntityGroupCount); + if (entityGroupHelper == null) + { + Log.Error("Can not create entity group helper."); + return false; + } + + entityGroupHelper.name = Utility.Text.Format("Entity Group - {0}", entityGroupName); + Transform transform = entityGroupHelper.transform; + transform.SetParent(m_InstanceRoot); + transform.localScale = Vector3.one; + + return m_EntityManager.AddEntityGroup(entityGroupName, instanceAutoReleaseInterval, instanceCapacity, instanceExpireTime, instancePriority, entityGroupHelper); + } + + /// + /// 是否存在实体。 + /// + /// 实体编号。 + /// 是否存在实体。 + public bool HasEntity(int entityId) + { + return m_EntityManager.HasEntity(entityId); + } + + /// + /// 是否存在实体。 + /// + /// 实体资源名称。 + /// 是否存在实体。 + public bool HasEntity(string entityAssetName) + { + return m_EntityManager.HasEntity(entityAssetName); + } + + /// + /// 获取实体。 + /// + /// 实体编号。 + /// 实体。 + public Entity GetEntity(int entityId) + { + return (Entity)m_EntityManager.GetEntity(entityId); + } + + /// + /// 获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + public Entity GetEntity(string entityAssetName) + { + return (Entity)m_EntityManager.GetEntity(entityAssetName); + } + + /// + /// 获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + public Entity[] GetEntities(string entityAssetName) + { + IEntity[] entities = m_EntityManager.GetEntities(entityAssetName); + Entity[] entityImpls = new Entity[entities.Length]; + for (int i = 0; i < entities.Length; i++) + { + entityImpls[i] = (Entity)entities[i]; + } + + return entityImpls; + } + + /// + /// 获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + public void GetEntities(string entityAssetName, List results) + { + if (results == null) + { + Log.Error("Results is invalid."); + return; + } + + results.Clear(); + m_EntityManager.GetEntities(entityAssetName, m_InternalEntityResults); + foreach (IEntity entity in m_InternalEntityResults) + { + results.Add((Entity)entity); + } + } + + /// + /// 获取所有已加载的实体。 + /// + /// 所有已加载的实体。 + public Entity[] GetAllLoadedEntities() + { + IEntity[] entities = m_EntityManager.GetAllLoadedEntities(); + Entity[] entityImpls = new Entity[entities.Length]; + for (int i = 0; i < entities.Length; i++) + { + entityImpls[i] = (Entity)entities[i]; + } + + return entityImpls; + } + + /// + /// 获取所有已加载的实体。 + /// + /// 所有已加载的实体。 + public void GetAllLoadedEntities(List results) + { + if (results == null) + { + Log.Error("Results is invalid."); + return; + } + + results.Clear(); + m_EntityManager.GetAllLoadedEntities(m_InternalEntityResults); + foreach (IEntity entity in m_InternalEntityResults) + { + results.Add((Entity)entity); + } + } + + /// + /// 获取所有正在加载实体的编号。 + /// + /// 所有正在加载实体的编号。 + public int[] GetAllLoadingEntityIds() + { + return m_EntityManager.GetAllLoadingEntityIds(); + } + + /// + /// 获取所有正在加载实体的编号。 + /// + /// 所有正在加载实体的编号。 + public void GetAllLoadingEntityIds(List results) + { + m_EntityManager.GetAllLoadingEntityIds(results); + } + + /// + /// 是否正在加载实体。 + /// + /// 实体编号。 + /// 是否正在加载实体。 + public bool IsLoadingEntity(int entityId) + { + return m_EntityManager.IsLoadingEntity(entityId); + } + + /// + /// 是否是合法的实体。 + /// + /// 实体。 + /// 实体是否合法。 + public bool IsValidEntity(Entity entity) + { + return m_EntityManager.IsValidEntity(entity); + } + + /// + /// 显示实体。 + /// + /// 实体逻辑类型。 + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + public void ShowEntity(int entityId, string entityAssetName, string entityGroupName) where T : EntityLogic + { + ShowEntity(entityId, typeof(T), entityAssetName, entityGroupName, DefaultPriority, null); + } + + /// + /// 显示实体。 + /// + /// 实体编号。 + /// 实体逻辑类型。 + /// 实体资源名称。 + /// 实体组名称。 + public void ShowEntity(int entityId, Type entityLogicType, string entityAssetName, string entityGroupName) + { + ShowEntity(entityId, entityLogicType, entityAssetName, entityGroupName, DefaultPriority, null); + } + + /// + /// 显示实体。 + /// + /// 实体逻辑类型。 + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + /// 加载实体资源的优先级。 + public void ShowEntity(int entityId, string entityAssetName, string entityGroupName, int priority) where T : EntityLogic + { + ShowEntity(entityId, typeof(T), entityAssetName, entityGroupName, priority, null); + } + + /// + /// 显示实体。 + /// + /// 实体编号。 + /// 实体逻辑类型。 + /// 实体资源名称。 + /// 实体组名称。 + /// 加载实体资源的优先级。 + public void ShowEntity(int entityId, Type entityLogicType, string entityAssetName, string entityGroupName, int priority) + { + ShowEntity(entityId, entityLogicType, entityAssetName, entityGroupName, priority, null); + } + + /// + /// 显示实体。 + /// + /// 实体逻辑类型。 + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + /// 用户自定义数据。 + public void ShowEntity(int entityId, string entityAssetName, string entityGroupName, object userData) where T : EntityLogic + { + ShowEntity(entityId, typeof(T), entityAssetName, entityGroupName, DefaultPriority, userData); + } + + /// + /// 显示实体。 + /// + /// 实体编号。 + /// 实体逻辑类型。 + /// 实体资源名称。 + /// 实体组名称。 + /// 用户自定义数据。 + public void ShowEntity(int entityId, Type entityLogicType, string entityAssetName, string entityGroupName, object userData) + { + ShowEntity(entityId, entityLogicType, entityAssetName, entityGroupName, DefaultPriority, userData); + } + + /// + /// 显示实体。 + /// + /// 实体逻辑类型。 + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + /// 加载实体资源的优先级。 + /// 用户自定义数据。 + public void ShowEntity(int entityId, string entityAssetName, string entityGroupName, int priority, object userData) where T : EntityLogic + { + ShowEntity(entityId, typeof(T), entityAssetName, entityGroupName, priority, userData); + } + + /// + /// 显示实体。 + /// + /// 实体编号。 + /// 实体逻辑类型。 + /// 实体资源名称。 + /// 实体组名称。 + /// 加载实体资源的优先级。 + /// 用户自定义数据。 + public void ShowEntity(int entityId, Type entityLogicType, string entityAssetName, string entityGroupName, int priority, object userData) + { + if (entityLogicType == null) + { + Log.Error("Entity type is invalid."); + return; + } + + m_EntityManager.ShowEntity(entityId, entityAssetName, entityGroupName, priority, ShowEntityInfo.Create(entityLogicType, userData)); + } + + /// + /// 隐藏实体。 + /// + /// 实体编号。 + public void HideEntity(int entityId) + { + m_EntityManager.HideEntity(entityId); + } + + /// + /// 隐藏实体。 + /// + /// 实体编号。 + /// 用户自定义数据。 + public void HideEntity(int entityId, object userData) + { + m_EntityManager.HideEntity(entityId, userData); + } + + /// + /// 隐藏实体。 + /// + /// 实体。 + public void HideEntity(Entity entity) + { + m_EntityManager.HideEntity(entity); + } + + /// + /// 隐藏实体。 + /// + /// 实体。 + /// 用户自定义数据。 + public void HideEntity(Entity entity, object userData) + { + m_EntityManager.HideEntity(entity, userData); + } + + /// + /// 隐藏所有已加载的实体。 + /// + public void HideAllLoadedEntities() + { + m_EntityManager.HideAllLoadedEntities(); + } + + /// + /// 隐藏所有已加载的实体。 + /// + /// 用户自定义数据。 + public void HideAllLoadedEntities(object userData) + { + m_EntityManager.HideAllLoadedEntities(userData); + } + + /// + /// 隐藏所有正在加载的实体。 + /// + public void HideAllLoadingEntities() + { + m_EntityManager.HideAllLoadingEntities(); + } + + /// + /// 获取父实体。 + /// + /// 要获取父实体的子实体的实体编号。 + /// 子实体的父实体。 + public Entity GetParentEntity(int childEntityId) + { + return (Entity)m_EntityManager.GetParentEntity(childEntityId); + } + + /// + /// 获取父实体。 + /// + /// 要获取父实体的子实体。 + /// 子实体的父实体。 + public Entity GetParentEntity(Entity childEntity) + { + return (Entity)m_EntityManager.GetParentEntity(childEntity); + } + + /// + /// 获取子实体数量。 + /// + /// 要获取子实体数量的父实体的实体编号。 + /// 子实体数量。 + public int GetChildEntityCount(int parentEntityId) + { + return m_EntityManager.GetChildEntityCount(parentEntityId); + } + + /// + /// 获取子实体。 + /// + /// 要获取子实体的父实体的实体编号。 + /// 子实体。 + public Entity GetChildEntity(int parentEntityId) + { + return (Entity)m_EntityManager.GetChildEntity(parentEntityId); + } + + /// + /// 获取子实体。 + /// + /// 要获取子实体的父实体。 + /// 子实体。 + public Entity GetChildEntity(IEntity parentEntity) + { + return (Entity)m_EntityManager.GetChildEntity(parentEntity); + } + + /// + /// 获取所有子实体。 + /// + /// 要获取所有子实体的父实体的实体编号。 + /// 所有子实体。 + public Entity[] GetChildEntities(int parentEntityId) + { + IEntity[] entities = m_EntityManager.GetChildEntities(parentEntityId); + Entity[] entityImpls = new Entity[entities.Length]; + for (int i = 0; i < entities.Length; i++) + { + entityImpls[i] = (Entity)entities[i]; + } + + return entityImpls; + } + + /// + /// 获取所有子实体。 + /// + /// 要获取所有子实体的父实体的实体编号。 + /// 所有子实体。 + public void GetChildEntities(int parentEntityId, List results) + { + if (results == null) + { + Log.Error("Results is invalid."); + return; + } + + results.Clear(); + m_EntityManager.GetChildEntities(parentEntityId, m_InternalEntityResults); + foreach (IEntity entity in m_InternalEntityResults) + { + results.Add((Entity)entity); + } + } + + /// + /// 获取所有子实体。 + /// + /// 要获取所有子实体的父实体。 + /// 所有子实体。 + public Entity[] GetChildEntities(Entity parentEntity) + { + IEntity[] entities = m_EntityManager.GetChildEntities(parentEntity); + Entity[] entityImpls = new Entity[entities.Length]; + for (int i = 0; i < entities.Length; i++) + { + entityImpls[i] = (Entity)entities[i]; + } + + return entityImpls; + } + + /// + /// 获取所有子实体。 + /// + /// 要获取所有子实体的父实体。 + /// 所有子实体。 + public void GetChildEntities(IEntity parentEntity, List results) + { + if (results == null) + { + Log.Error("Results is invalid."); + return; + } + + results.Clear(); + m_EntityManager.GetChildEntities(parentEntity, m_InternalEntityResults); + foreach (IEntity entity in m_InternalEntityResults) + { + results.Add((Entity)entity); + } + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体的实体编号。 + public void AttachEntity(int childEntityId, int parentEntityId) + { + AttachEntity(GetEntity(childEntityId), GetEntity(parentEntityId), string.Empty, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体。 + public void AttachEntity(int childEntityId, Entity parentEntity) + { + AttachEntity(GetEntity(childEntityId), parentEntity, string.Empty, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体的实体编号。 + public void AttachEntity(Entity childEntity, int parentEntityId) + { + AttachEntity(childEntity, GetEntity(parentEntityId), string.Empty, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体。 + public void AttachEntity(Entity childEntity, Entity parentEntity) + { + AttachEntity(childEntity, parentEntity, string.Empty, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体的实体编号。 + /// 相对于被附加父实体的位置。 + public void AttachEntity(int childEntityId, int parentEntityId, string parentTransformPath) + { + AttachEntity(GetEntity(childEntityId), GetEntity(parentEntityId), parentTransformPath, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体。 + /// 相对于被附加父实体的位置。 + public void AttachEntity(int childEntityId, Entity parentEntity, string parentTransformPath) + { + AttachEntity(GetEntity(childEntityId), parentEntity, parentTransformPath, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体的实体编号。 + /// 相对于被附加父实体的位置。 + public void AttachEntity(Entity childEntity, int parentEntityId, string parentTransformPath) + { + AttachEntity(childEntity, GetEntity(parentEntityId), parentTransformPath, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体。 + /// 相对于被附加父实体的位置。 + public void AttachEntity(Entity childEntity, Entity parentEntity, string parentTransformPath) + { + AttachEntity(childEntity, parentEntity, parentTransformPath, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体的实体编号。 + /// 相对于被附加父实体的位置。 + public void AttachEntity(int childEntityId, int parentEntityId, Transform parentTransform) + { + AttachEntity(GetEntity(childEntityId), GetEntity(parentEntityId), parentTransform, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体。 + /// 相对于被附加父实体的位置。 + public void AttachEntity(int childEntityId, Entity parentEntity, Transform parentTransform) + { + AttachEntity(GetEntity(childEntityId), parentEntity, parentTransform, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体的实体编号。 + /// 相对于被附加父实体的位置。 + public void AttachEntity(Entity childEntity, int parentEntityId, Transform parentTransform) + { + AttachEntity(childEntity, GetEntity(parentEntityId), parentTransform, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体。 + /// 相对于被附加父实体的位置。 + public void AttachEntity(Entity childEntity, Entity parentEntity, Transform parentTransform) + { + AttachEntity(childEntity, parentEntity, parentTransform, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体的实体编号。 + /// 用户自定义数据。 + public void AttachEntity(int childEntityId, int parentEntityId, object userData) + { + AttachEntity(GetEntity(childEntityId), GetEntity(parentEntityId), string.Empty, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体。 + /// 用户自定义数据。 + public void AttachEntity(int childEntityId, Entity parentEntity, object userData) + { + AttachEntity(GetEntity(childEntityId), parentEntity, string.Empty, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体的实体编号。 + /// 用户自定义数据。 + public void AttachEntity(Entity childEntity, int parentEntityId, object userData) + { + AttachEntity(childEntity, GetEntity(parentEntityId), string.Empty, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体。 + /// 用户自定义数据。 + public void AttachEntity(Entity childEntity, Entity parentEntity, object userData) + { + AttachEntity(childEntity, parentEntity, string.Empty, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体的实体编号。 + /// 相对于被附加父实体的位置。 + /// 用户自定义数据。 + public void AttachEntity(int childEntityId, int parentEntityId, string parentTransformPath, object userData) + { + AttachEntity(GetEntity(childEntityId), GetEntity(parentEntityId), parentTransformPath, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体。 + /// 相对于被附加父实体的位置。 + /// 用户自定义数据。 + public void AttachEntity(int childEntityId, Entity parentEntity, string parentTransformPath, object userData) + { + AttachEntity(GetEntity(childEntityId), parentEntity, parentTransformPath, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体的实体编号。 + /// 相对于被附加父实体的位置。 + /// 用户自定义数据。 + public void AttachEntity(Entity childEntity, int parentEntityId, string parentTransformPath, object userData) + { + AttachEntity(childEntity, GetEntity(parentEntityId), parentTransformPath, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体。 + /// 相对于被附加父实体的位置。 + /// 用户自定义数据。 + public void AttachEntity(Entity childEntity, Entity parentEntity, string parentTransformPath, object userData) + { + if (childEntity == null) + { + Log.Warning("Child entity is invalid."); + return; + } + + if (parentEntity == null) + { + Log.Warning("Parent entity is invalid."); + return; + } + + Transform parentTransform = null; + if (string.IsNullOrEmpty(parentTransformPath)) + { + parentTransform = parentEntity.Logic.CachedTransform; + } + else + { + parentTransform = parentEntity.Logic.CachedTransform.Find(parentTransformPath); + if (parentTransform == null) + { + Log.Warning("Can not find transform path '{0}' from parent entity '{1}'.", parentTransformPath, parentEntity.Logic.Name); + parentTransform = parentEntity.Logic.CachedTransform; + } + } + + AttachEntity(childEntity, parentEntity, parentTransform, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体的实体编号。 + /// 相对于被附加父实体的位置。 + /// 用户自定义数据。 + public void AttachEntity(int childEntityId, int parentEntityId, Transform parentTransform, object userData) + { + AttachEntity(GetEntity(childEntityId), GetEntity(parentEntityId), parentTransform, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体。 + /// 相对于被附加父实体的位置。 + /// 用户自定义数据。 + public void AttachEntity(int childEntityId, Entity parentEntity, Transform parentTransform, object userData) + { + AttachEntity(GetEntity(childEntityId), parentEntity, parentTransform, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体的实体编号。 + /// 相对于被附加父实体的位置。 + /// 用户自定义数据。 + public void AttachEntity(Entity childEntity, int parentEntityId, Transform parentTransform, object userData) + { + AttachEntity(childEntity, GetEntity(parentEntityId), parentTransform, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体。 + /// 相对于被附加父实体的位置。 + /// 用户自定义数据。 + public void AttachEntity(Entity childEntity, Entity parentEntity, Transform parentTransform, object userData) + { + if (childEntity == null) + { + Log.Warning("Child entity is invalid."); + return; + } + + if (parentEntity == null) + { + Log.Warning("Parent entity is invalid."); + return; + } + + if (parentTransform == null) + { + parentTransform = parentEntity.Logic.CachedTransform; + } + + m_EntityManager.AttachEntity(childEntity, parentEntity, AttachEntityInfo.Create(parentTransform, userData)); + } + + /// + /// 解除子实体。 + /// + /// 要解除的子实体的实体编号。 + public void DetachEntity(int childEntityId) + { + m_EntityManager.DetachEntity(childEntityId); + } + + /// + /// 解除子实体。 + /// + /// 要解除的子实体的实体编号。 + /// 用户自定义数据。 + public void DetachEntity(int childEntityId, object userData) + { + m_EntityManager.DetachEntity(childEntityId, userData); + } + + /// + /// 解除子实体。 + /// + /// 要解除的子实体。 + public void DetachEntity(Entity childEntity) + { + m_EntityManager.DetachEntity(childEntity); + } + + /// + /// 解除子实体。 + /// + /// 要解除的子实体。 + /// 用户自定义数据。 + public void DetachEntity(Entity childEntity, object userData) + { + m_EntityManager.DetachEntity(childEntity, userData); + } + + /// + /// 解除所有子实体。 + /// + /// 被解除的父实体的实体编号。 + public void DetachChildEntities(int parentEntityId) + { + m_EntityManager.DetachChildEntities(parentEntityId); + } + + /// + /// 解除所有子实体。 + /// + /// 被解除的父实体的实体编号。 + /// 用户自定义数据。 + public void DetachChildEntities(int parentEntityId, object userData) + { + m_EntityManager.DetachChildEntities(parentEntityId, userData); + } + + /// + /// 解除所有子实体。 + /// + /// 被解除的父实体。 + public void DetachChildEntities(Entity parentEntity) + { + m_EntityManager.DetachChildEntities(parentEntity); + } + + /// + /// 解除所有子实体。 + /// + /// 被解除的父实体。 + /// 用户自定义数据。 + public void DetachChildEntities(Entity parentEntity, object userData) + { + m_EntityManager.DetachChildEntities(parentEntity, userData); + } + + /// + /// 设置实体是否被加锁。 + /// + /// 实体。 + /// 实体是否被加锁。 + public void SetEntityInstanceLocked(Entity entity, bool locked) + { + if (entity == null) + { + Log.Warning("Entity is invalid."); + return; + } + + IEntityGroup entityGroup = entity.EntityGroup; + if (entityGroup == null) + { + Log.Warning("Entity group is invalid."); + return; + } + + entityGroup.SetEntityInstanceLocked(entity.gameObject, locked); + } + + /// + /// 设置实体的优先级。 + /// + /// 实体。 + /// 实体优先级。 + public void SetInstancePriority(Entity entity, int priority) + { + if (entity == null) + { + Log.Warning("Entity is invalid."); + return; + } + + IEntityGroup entityGroup = entity.EntityGroup; + if (entityGroup == null) + { + Log.Warning("Entity group is invalid."); + return; + } + + entityGroup.SetEntityInstancePriority(entity.gameObject, priority); + } + + /// + /// 创建显示实体成功事件。 + /// + /// 加载成功的实体。 + /// 加载持续时间。 + /// 用户自定义数据。 + private void OnShowEntitySuccess(IEntity entity, float duration, object userData) + { + GameEventMgr.Instance.Send(EntityEvent.ShowEntitySuccess,entity,duration,userData); + } + + /// + /// 创建显示实体失败事件。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + /// 错误信息。 + /// 用户自定义数据。 + private void OnShowEntityFailure(int entityId, string entityAssetName, string entityGroupName, string errorMessage, object userData) + { + Log.Warning("Show entity failure, entity id '{0}', asset name '{1}', entity group name '{2}', error message '{3}'.", + entityId, + entityAssetName, + entityGroupName, + errorMessage); + GameEventMgr.Instance.Send(EntityEvent.ShowEntityFailure,entityId,entityAssetName,entityGroupName,errorMessage,userData); + } + + /// + /// 创建显示实体更新事件。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + /// 显示实体进度。 + /// 用户自定义数据。 + private void OnShowEntityUpdate(int entityId, string entityAssetName, string entityGroupName, float progress, object userData) + { + GameEventMgr.Instance.Send(EntityEvent.ShowEntityUpdate,entityId,entityAssetName,entityGroupName,progress,userData); + } + + /// + /// 创建显示实体时加载依赖资源事件。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + /// 被加载的依赖资源名称。 + /// 当前已加载依赖资源数量。 + /// 总共加载依赖资源数量。 + /// 用户自定义数据。 + private void OnShowEntityDependencyAsset(int entityId, string entityAssetName, string entityGroupName, string dependencyAssetName, int loadedCount, int totalCount, object userData) + { + GameEventMgr.Instance.Send(EntityEvent.ShowEntityDependency,entityId,entityAssetName,entityGroupName,userData); + } + + /// + /// 创建隐藏实体完成事件。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体所属的实体组。 + /// 用户自定义数据。 + private void OnHideEntityComplete(int entityId, string entityAssetName, IEntityGroup entityGroup, object userData) + { + GameEventMgr.Instance.Send(EntityEvent.HideEntityComplete,entityId,entityAssetName,entityGroup,userData); + } + + public override void OnUpdate(float elapseSeconds, float realElapseSeconds) + { + m_EntityManager?.Update(elapseSeconds, realElapseSeconds); + } + + public override void OnDestroy() + { + m_EntityManager?.ShutDown(); + base.OnDestroy(); + } + } +} diff --git a/Assets/TEngine/Scripts/Runtime/Entity/EntityComponent.cs.meta b/Assets/TEngine/Scripts/Runtime/Entity/EntityComponent.cs.meta new file mode 100644 index 00000000..7e2eab87 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/EntityComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fc62b60a444ff0c4a952566cb2ecd2fa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Entity/EntityEvent.cs b/Assets/TEngine/Scripts/Runtime/Entity/EntityEvent.cs new file mode 100644 index 00000000..eab8b462 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/EntityEvent.cs @@ -0,0 +1,12 @@ +namespace TEngine.Runtime.Entity +{ + public class EntityEvent + { + public static int ShowEntitySuccess = StringId.StringToHash("EntityEvent.ShowEntitySuccess"); + public static int ShowEntityFailure = StringId.StringToHash("EntityEvent.ShowEntityFailure"); + public static int ShowEntityUpdate = StringId.StringToHash("EntityEvent.ShowEntityUpdate"); + public static int ShowEntityDependency = StringId.StringToHash("EntityEvent.ShowEntityDependency"); + public static int HideEntityComplete = StringId.StringToHash("EntityEvent.HideEntityComplete"); + } +} + diff --git a/Assets/TEngine/Scripts/Runtime/Entity/EntityEvent.cs.meta b/Assets/TEngine/Scripts/Runtime/Entity/EntityEvent.cs.meta new file mode 100644 index 00000000..71646847 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Entity/EntityEvent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d3339c75ba3df974385330e4bbcf25af +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/ObjectPool/Core/ObjectPoolComponent.cs b/Assets/TEngine/Scripts/Runtime/ObjectPool/Core/ObjectPoolComponent.cs index 30808db8..d1919f03 100644 --- a/Assets/TEngine/Scripts/Runtime/ObjectPool/Core/ObjectPoolComponent.cs +++ b/Assets/TEngine/Scripts/Runtime/ObjectPool/Core/ObjectPoolComponent.cs @@ -11,6 +11,8 @@ namespace TEngine.Runtime.ObjectPool [AddComponentMenu("TEngine/Object Pool")] public sealed class ObjectPoolComponent : UnitySingleton { + public IObjectPoolManager PoolManager => m_ObjectPoolManager; + private IObjectPoolManager m_ObjectPoolManager = null; /// @@ -1025,11 +1027,11 @@ namespace TEngine.Runtime.ObjectPool { return m_ObjectPoolManager.DestroyObjectPool(objectPool); } - + /// /// 释放对象池中的可释放对象。 /// - public void Release() + public void ReleaseObject() { Log.Info("Object pool release..."); m_ObjectPoolManager.Release();