using System; using System.Collections.Generic; using System.Threading; using Cysharp.Threading.Tasks; using YooAsset; namespace TEngine { /// /// 实体管理器。 /// internal sealed partial class EntityManager : Module, IEntityManager, IUpdateModule { private readonly Dictionary _entityInfos; private readonly Dictionary _entityGroups; private readonly Dictionary _entitiesBeingLoaded; private readonly HashSet _entitiesToReleaseOnLoad; private readonly Queue _recycleQueue; private IObjectPoolModule _objectPoolModule; private IResourceModule _resourceModule; private IEntityHelper _entityHelper; private int _serial; private bool _isShutdown; private Action _showEntitySuccessEventHandler; private Action _showEntityFailureEventHandler; private Action _hideEntityCompleteEventHandler; /// /// 初始化实体管理器的新实例。 /// public EntityManager() { _entityInfos = new Dictionary(); _entityGroups = new Dictionary(StringComparer.Ordinal); _entitiesBeingLoaded = new Dictionary(); _entitiesToReleaseOnLoad = new HashSet(); _recycleQueue = new Queue(); _objectPoolModule = null; _resourceModule = null; _entityHelper = null; _serial = 0; _isShutdown = false; _showEntitySuccessEventHandler = null; _showEntityFailureEventHandler = null; _hideEntityCompleteEventHandler = null; } /// /// 获取实体数量。 /// public int EntityCount => _entityInfos.Count; /// /// 获取实体组数量。 /// public int EntityGroupCount => _entityGroups.Count; /// /// 显示实体成功事件。 /// public event Action ShowEntitySuccess { add => _showEntitySuccessEventHandler += value; remove => _showEntitySuccessEventHandler -= value; } /// /// 显示实体失败事件。 /// public event Action ShowEntityFailure { add => _showEntityFailureEventHandler += value; remove => _showEntityFailureEventHandler -= value; } /// /// 隐藏实体完成事件。 /// public event Action HideEntityComplete { add => _hideEntityCompleteEventHandler += value; remove => _hideEntityCompleteEventHandler -= value; } /// /// 实体管理器轮询。 /// /// 逻辑流逝时间,以秒为单位。 /// 真实流逝时间,以秒为单位。 public void Update(float elapseSeconds, float realElapseSeconds) { while (_recycleQueue.Count > 0) { EntityInfo entityInfo = _recycleQueue.Dequeue(); IEntity entity = entityInfo.Entity; EntityGroup entityGroup = (EntityGroup)entity.EntityGroup; if (entityGroup == null) { throw new GameFrameworkException("Entity group is invalid."); } entityInfo.Status = EntityStatus.WillRecycle; entity.OnRecycle(); entityInfo.Status = EntityStatus.Recycled; entityGroup.UnspawnEntity(entity); MemoryPool.Release(entityInfo); } foreach (KeyValuePair entityGroup in _entityGroups) { entityGroup.Value.Update(elapseSeconds, realElapseSeconds); } } public override void OnInit() { } /// /// 关闭并清理实体管理器。 /// public override void Shutdown() { _isShutdown = true; HideAllLoadedEntities(); _entityGroups.Clear(); _entitiesBeingLoaded.Clear(); _entitiesToReleaseOnLoad.Clear(); _recycleQueue.Clear(); } /// /// 设置对象池管理器。 /// /// 对象池管理器。 public void SetObjectPoolManager(IObjectPoolModule objectPoolManager) { _objectPoolModule = objectPoolManager ?? throw new GameFrameworkException("Object pool manager is invalid."); } /// /// 设置资源管理器。 /// /// 资源管理器。 public void SetResourceManager(IResourceModule resourceManager) { _resourceModule = resourceManager ?? throw new GameFrameworkException("Resource manager is invalid."); } /// /// 设置实体辅助器。 /// /// 实体辅助器。 public void SetEntityHelper(IEntityHelper entityHelper) { _entityHelper = entityHelper ?? throw new GameFrameworkException("Entity helper is invalid."); } /// /// 是否存在实体组。 /// /// 实体组名称。 /// 是否存在实体组。 public bool HasEntityGroup(string entityGroupName) { if (string.IsNullOrEmpty(entityGroupName)) { throw new GameFrameworkException("Entity group name is invalid."); } return _entityGroups.ContainsKey(entityGroupName); } /// /// 获取实体组。 /// /// 实体组名称。 /// 要获取的实体组。 public IEntityGroup GetEntityGroup(string entityGroupName) { if (string.IsNullOrEmpty(entityGroupName)) { throw new GameFrameworkException("Entity group name is invalid."); } if (_entityGroups.TryGetValue(entityGroupName, out var entityGroup)) { return entityGroup; } return null; } /// /// 获取所有实体组。 /// /// 所有实体组。 public IEntityGroup[] GetAllEntityGroups() { int index = 0; IEntityGroup[] results = new IEntityGroup[_entityGroups.Count]; foreach (KeyValuePair entityGroup in _entityGroups) { results[index++] = entityGroup.Value; } return results; } /// /// 获取所有实体组。 /// /// 所有实体组。 public void GetAllEntityGroups(List results) { if (results == null) { throw new GameFrameworkException("Results is invalid."); } results.Clear(); foreach (KeyValuePair entityGroup in _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 GameFrameworkException("Entity group name is invalid."); } if (entityGroupHelper == null) { throw new GameFrameworkException("Entity group helper is invalid."); } if (_objectPoolModule == null) { throw new GameFrameworkException("You must set object pool manager first."); } if (HasEntityGroup(entityGroupName)) { return false; } _entityGroups.Add(entityGroupName, new EntityGroup(entityGroupName, instanceAutoReleaseInterval, instanceCapacity, instanceExpireTime, instancePriority, entityGroupHelper, _objectPoolModule)); return true; } /// /// 是否存在实体。 /// /// 实体编号。 /// 是否存在实体。 public bool HasEntity(int entityId) { return _entityInfos.ContainsKey(entityId); } /// /// 是否存在实体。 /// /// 实体资源名称。 /// 是否存在实体。 public bool HasEntity(string entityAssetName) { if (string.IsNullOrEmpty(entityAssetName)) { throw new GameFrameworkException("Entity asset name is invalid."); } foreach (KeyValuePair entityInfo in _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 GameFrameworkException("Entity asset name is invalid."); } foreach (KeyValuePair entityInfo in _entityInfos) { if (entityInfo.Value.Entity.EntityAssetName == entityAssetName) { return entityInfo.Value.Entity; } } return null; } /// /// 获取实体。 /// /// 实体资源名称。 /// 要获取的实体。 public IEntity[] GetEntities(string entityAssetName) { if (string.IsNullOrEmpty(entityAssetName)) { throw new GameFrameworkException("Entity asset name is invalid."); } List results = new List(); foreach (KeyValuePair entityInfo in _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 GameFrameworkException("Entity asset name is invalid."); } if (results == null) { throw new GameFrameworkException("Results is invalid."); } results.Clear(); foreach (KeyValuePair entityInfo in _entityInfos) { if (entityInfo.Value.Entity.EntityAssetName == entityAssetName) { results.Add(entityInfo.Value.Entity); } } } /// /// 获取所有已加载的实体。 /// /// 所有已加载的实体。 public IEntity[] GetAllLoadedEntities() { int index = 0; IEntity[] results = new IEntity[_entityInfos.Count]; foreach (KeyValuePair entityInfo in _entityInfos) { results[index++] = entityInfo.Value.Entity; } return results; } /// /// 获取所有已加载的实体。 /// /// 所有已加载的实体。 public void GetAllLoadedEntities(List results) { if (results == null) { throw new GameFrameworkException("Results is invalid."); } results.Clear(); foreach (KeyValuePair entityInfo in _entityInfos) { results.Add(entityInfo.Value.Entity); } } /// /// 获取所有正在加载实体的编号。 /// /// 所有正在加载实体的编号。 public int[] GetAllLoadingEntityIds() { int index = 0; int[] results = new int[_entitiesBeingLoaded.Count]; foreach (KeyValuePair entityBeingLoaded in _entitiesBeingLoaded) { results[index++] = entityBeingLoaded.Key; } return results; } /// /// 获取所有正在加载实体的编号。 /// /// 所有正在加载实体的编号。 public void GetAllLoadingEntityIds(List results) { if (results == null) { throw new GameFrameworkException("Results is invalid."); } results.Clear(); foreach (KeyValuePair entityBeingLoaded in _entitiesBeingLoaded) { results.Add(entityBeingLoaded.Key); } } /// /// 是否正在加载实体。 /// /// 实体编号。 /// 是否正在加载实体。 public bool IsLoadingEntity(int entityId) { return _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, EntityModule.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, EntityModule.DefaultPriority, userData); } /// /// 同步显示实体。 /// /// 实体编号。 /// 实体资源名称。 /// 实体组名称。 /// 加载实体资源的优先级。 /// 用户自定义数据。 public T ShowEntitySync(int entityId, string entityAssetName, string entityGroupName, int priority = 0, object userData = null) where T : class { if (_resourceModule == null) { throw new GameFrameworkException("You must set resource manager first."); } if (_entityHelper == null) { throw new GameFrameworkException("You must set entity helper first."); } if (string.IsNullOrEmpty(entityAssetName)) { throw new GameFrameworkException("Entity asset name is invalid."); } if (string.IsNullOrEmpty(entityGroupName)) { throw new GameFrameworkException("Entity group name is invalid."); } if (HasEntity(entityId)) { throw new GameFrameworkException(Utility.Text.Format("Entity id '{0}' is already exist.", entityId)); } if (IsLoadingEntity(entityId)) { throw new GameFrameworkException(Utility.Text.Format("Entity '{0}' is already being loaded.", entityId)); } EntityGroup entityGroup = (EntityGroup)GetEntityGroup(entityGroupName); if (entityGroup == null) { throw new GameFrameworkException(Utility.Text.Format("Entity group '{0}' is not exist.", entityGroupName)); } EntityInstanceObject entityInstanceObject = entityGroup.SpawnEntityInstanceObject(entityAssetName); if (entityInstanceObject == null) { int serialId = ++_serial; _entitiesBeingLoaded.Add(entityId, serialId); var assetInfo = _resourceModule.GetAssetInfo(entityAssetName); if (!string.IsNullOrEmpty(assetInfo.Error)) { LoadAssetFailureCallback(entityAssetName,assetInfo.Error,null); return default; } float duration = GameTime.time; UnityEngine.GameObject gameObject = _resourceModule.LoadAsset(assetInfo.Address); duration = GameTime.time - duration; Entity entity = (Entity)LoadAssetSuccessCallback(entityAssetName, gameObject, duration, ShowEntityInfo.Create(serialId, entityId, entityGroup, userData)); return entity.Logic as T; } return InternalShowEntity(entityId, entityAssetName, entityGroup, entityInstanceObject.Target, false, 0f, userData) as T; } /// /// 异步显示实体。 /// /// 实体编号。 /// 实体资源名称。 /// 实体组名称。 /// 加载实体资源的优先级。 /// 用户自定义数据。 public async UniTask ShowEntityAsync(int entityId, string entityAssetName, string entityGroupName, int priority = 0, object userData = null) where T : class { if (_resourceModule == null) { throw new GameFrameworkException("You must set resource manager first."); } if (_entityHelper == null) { throw new GameFrameworkException("You must set entity helper first."); } if (string.IsNullOrEmpty(entityAssetName)) { throw new GameFrameworkException("Entity asset name is invalid."); } if (string.IsNullOrEmpty(entityGroupName)) { throw new GameFrameworkException("Entity group name is invalid."); } if (HasEntity(entityId)) { throw new GameFrameworkException(Utility.Text.Format("Entity id '{0}' is already exist.", entityId)); } if (IsLoadingEntity(entityId)) { throw new GameFrameworkException(Utility.Text.Format("Entity '{0}' is already being loaded.", entityId)); } EntityGroup entityGroup = (EntityGroup)GetEntityGroup(entityGroupName); if (entityGroup == null) { throw new GameFrameworkException(Utility.Text.Format("Entity group '{0}' is not exist.", entityGroupName)); } EntityInstanceObject entityInstanceObject = entityGroup.SpawnEntityInstanceObject(entityAssetName); if (entityInstanceObject == null) { int serialId = ++_serial; _entitiesBeingLoaded.Add(entityId, serialId); var assetInfo = _resourceModule.GetAssetInfo(entityAssetName); if (!string.IsNullOrEmpty(assetInfo.Error)) { LoadAssetFailureCallback(entityAssetName,assetInfo.Error,null); return default; } float duration = GameTime.time; UnityEngine.GameObject gameObject = await _resourceModule.LoadAssetAsync(assetInfo.Address,CancellationToken.None); duration = GameTime.time - duration; Entity entity = (Entity)LoadAssetSuccessCallback(entityAssetName, gameObject, duration, ShowEntityInfo.Create(serialId, entityId, entityGroup, userData)); return entity.Logic as T; } return InternalShowEntity(entityId, entityAssetName, entityGroup, entityInstanceObject.Target, false, 0f, userData) as T; } /// /// 显示实体。 /// /// 实体编号。 /// 实体资源名称。 /// 实体组名称。 /// 加载实体资源的优先级。 /// 用户自定义数据。 public void ShowEntity(int entityId, string entityAssetName, string entityGroupName, int priority, object userData) { if (_resourceModule == null) { throw new GameFrameworkException("You must set resource manager first."); } if (_entityHelper == null) { throw new GameFrameworkException("You must set entity helper first."); } if (string.IsNullOrEmpty(entityAssetName)) { throw new GameFrameworkException("Entity asset name is invalid."); } if (string.IsNullOrEmpty(entityGroupName)) { throw new GameFrameworkException("Entity group name is invalid."); } if (HasEntity(entityId)) { throw new GameFrameworkException(Utility.Text.Format("Entity id '{0}' is already exist.", entityId)); } if (IsLoadingEntity(entityId)) { throw new GameFrameworkException(Utility.Text.Format("Entity '{0}' is already being loaded.", entityId)); } EntityGroup entityGroup = (EntityGroup)GetEntityGroup(entityGroupName); if (entityGroup == null) { throw new GameFrameworkException(Utility.Text.Format("Entity group '{0}' is not exist.", entityGroupName)); } EntityInstanceObject entityInstanceObject = entityGroup.SpawnEntityInstanceObject(entityAssetName); if (entityInstanceObject == null) { int serialId = ++_serial; _entitiesBeingLoaded.Add(entityId, serialId); var assetInfo = _resourceModule.GetAssetInfo(entityAssetName); if (!string.IsNullOrEmpty(assetInfo.Error)) { LoadAssetFailureCallback(entityAssetName,assetInfo.Error,null); return; } float duration = GameTime.time; _resourceModule.LoadAsset(assetInfo.Address, gameObject => { duration = GameTime.time - duration; LoadAssetSuccessCallback(entityAssetName, gameObject, duration, ShowEntityInfo.Create(serialId, entityId, entityGroup, userData)); }).Forget(); 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)) { _entitiesToReleaseOnLoad.Add(_entitiesBeingLoaded[entityId]); _entitiesBeingLoaded.Remove(entityId); return; } EntityInfo entityInfo = GetEntityInfo(entityId); if (entityInfo == null) { throw new GameFrameworkException(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 GameFrameworkException("Entity is invalid."); } HideEntity(entity.Id, userData); } /// /// 隐藏所有已加载的实体。 /// public void HideAllLoadedEntities() { HideAllLoadedEntities(null); } /// /// 隐藏所有已加载的实体。 /// /// 用户自定义数据。 public void HideAllLoadedEntities(object userData) { while (_entityInfos.Count > 0) { foreach (KeyValuePair entityInfo in _entityInfos) { InternalHideEntity(entityInfo.Value, userData); break; } } } /// /// 隐藏所有正在加载的实体。 /// public void HideAllLoadingEntities() { foreach (KeyValuePair entityBeingLoaded in _entitiesBeingLoaded) { _entitiesToReleaseOnLoad.Add(entityBeingLoaded.Value); } _entitiesBeingLoaded.Clear(); } /// /// 获取父实体。 /// /// 要获取父实体的子实体的实体编号。 /// 子实体的父实体。 public IEntity GetParentEntity(int childEntityId) { EntityInfo childEntityInfo = GetEntityInfo(childEntityId); if (childEntityInfo == null) { throw new GameFrameworkException(Utility.Text.Format("Can not find child entity '{0}'.", childEntityId)); } return childEntityInfo.ParentEntity; } /// /// 获取父实体。 /// /// 要获取父实体的子实体。 /// 子实体的父实体。 public IEntity GetParentEntity(IEntity childEntity) { if (childEntity == null) { throw new GameFrameworkException("Child entity is invalid."); } return GetParentEntity(childEntity.Id); } /// /// 获取子实体数量。 /// /// 要获取子实体数量的父实体的实体编号。 /// 子实体数量。 public int GetChildEntityCount(int parentEntityId) { EntityInfo parentEntityInfo = GetEntityInfo(parentEntityId); if (parentEntityInfo == null) { throw new GameFrameworkException(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 GameFrameworkException(Utility.Text.Format("Can not find parent entity '{0}'.", parentEntityId)); } return parentEntityInfo.GetChildEntity(); } /// /// 获取子实体。 /// /// 要获取子实体的父实体。 /// 子实体。 public IEntity GetChildEntity(IEntity parentEntity) { if (parentEntity == null) { throw new GameFrameworkException("Parent entity is invalid."); } return GetChildEntity(parentEntity.Id); } /// /// 获取所有子实体。 /// /// 要获取所有子实体的父实体的实体编号。 /// 所有子实体。 public IEntity[] GetChildEntities(int parentEntityId) { EntityInfo parentEntityInfo = GetEntityInfo(parentEntityId); if (parentEntityInfo == null) { throw new GameFrameworkException(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 GameFrameworkException(Utility.Text.Format("Can not find parent entity '{0}'.", parentEntityId)); } parentEntityInfo.GetChildEntities(results); } /// /// 获取所有子实体。 /// /// 要获取所有子实体的父实体。 /// 所有子实体。 public IEntity[] GetChildEntities(IEntity parentEntity) { if (parentEntity == null) { throw new GameFrameworkException("Parent entity is invalid."); } return GetChildEntities(parentEntity.Id); } /// /// 获取所有子实体。 /// /// 要获取所有子实体的父实体。 /// 所有子实体。 public void GetChildEntities(IEntity parentEntity, List results) { if (parentEntity == null) { throw new GameFrameworkException("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 GameFrameworkException(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 GameFrameworkException(Utility.Text.Format("Can not find child entity '{0}'.", childEntityId)); } if (childEntityInfo.Status >= EntityStatus.WillHide) { throw new GameFrameworkException(Utility.Text.Format("Can not attach entity when child entity status is '{0}'.", childEntityInfo.Status)); } EntityInfo parentEntityInfo = GetEntityInfo(parentEntityId); if (parentEntityInfo == null) { throw new GameFrameworkException(Utility.Text.Format("Can not find parent entity '{0}'.", parentEntityId)); } if (parentEntityInfo.Status >= EntityStatus.WillHide) { throw new GameFrameworkException(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 GameFrameworkException("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 GameFrameworkException("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 GameFrameworkException("Child entity is invalid."); } if (parentEntity == null) { throw new GameFrameworkException("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 GameFrameworkException(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 GameFrameworkException(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 GameFrameworkException("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 GameFrameworkException(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 GameFrameworkException("Parent entity is invalid."); } DetachChildEntities(parentEntity.Id, userData); } /// /// 获取实体信息。 /// /// 实体编号。 /// 实体信息。 private EntityInfo GetEntityInfo(int entityId) { if (_entityInfos.TryGetValue(entityId, out var entityInfo)) { return entityInfo; } return null; } private IEntity InternalShowEntity(int entityId, string entityAssetName, EntityGroup entityGroup, object entityInstance, bool isNewInstance, float duration, object userData) { try { IEntity entity = _entityHelper.CreateEntity(entityInstance, entityGroup, userData); if (entity == null) { throw new GameFrameworkException("Can not create entity in entity helper."); } EntityInfo entityInfo = EntityInfo.Create(entity); _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 (_showEntitySuccessEventHandler != null) { TEngine.ShowEntityInfo showEntityInfo = (TEngine.ShowEntityInfo)userData; Type entityLogicType = showEntityInfo.EntityLogicType; _showEntitySuccessEventHandler.Invoke(entityLogicType, entity, duration, userData); } return entity; } catch (Exception exception) { if (_showEntityFailureEventHandler != null) { TEngine.ShowEntityInfo showEntityInfo = (TEngine.ShowEntityInfo)userData; Type entityLogicType = showEntityInfo.EntityLogicType; _showEntityFailureEventHandler.Invoke(entityId,entityLogicType,entityAssetName, entityGroup.Name, exception.ToString(), userData); return null; } 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(_isShutdown, userData); entityInfo.Status = EntityStatus.Hidden; EntityGroup entityGroup = (EntityGroup)entity.EntityGroup; if (entityGroup == null) { throw new GameFrameworkException("Entity group is invalid."); } entityGroup.RemoveEntity(entity); if (!_entityInfos.Remove(entity.Id)) { throw new GameFrameworkException("Entity info is unmanaged."); } if (_hideEntityCompleteEventHandler != null) { _hideEntityCompleteEventHandler.Invoke(entity.Id, entity.EntityAssetName, entityGroup.Name, userData); } _recycleQueue.Enqueue(entityInfo); } private IEntity LoadAssetSuccessCallback(string entityAssetName, object entityAsset, float duration, object userData) { ShowEntityInfo showEntityInfo = (ShowEntityInfo)userData; if (showEntityInfo == null) { throw new GameFrameworkException("Show entity info is invalid."); } if (_entitiesToReleaseOnLoad.Contains(showEntityInfo.SerialId)) { _entitiesToReleaseOnLoad.Remove(showEntityInfo.SerialId); MemoryPool.Release(showEntityInfo); _entityHelper.ReleaseEntity(entityAsset, null); return null; } _entitiesBeingLoaded.Remove(showEntityInfo.EntityId); EntityInstanceObject entityInstanceObject = EntityInstanceObject.Create(entityAssetName, entityAsset, _entityHelper.InstantiateEntity(entityAsset), _entityHelper); showEntityInfo.EntityGroup.RegisterEntityInstanceObject(entityInstanceObject, true); IEntity entity = InternalShowEntity(showEntityInfo.EntityId, entityAssetName, showEntityInfo.EntityGroup, entityInstanceObject.Target, true, duration, showEntityInfo.UserData); MemoryPool.Release(showEntityInfo); return entity; } private void LoadAssetFailureCallback(string entityAssetName, string errorMessage, object userData) { ShowEntityInfo showEntityInfo = (ShowEntityInfo)userData; if (showEntityInfo == null) { throw new GameFrameworkException("Show entity info is invalid."); } if (_entitiesToReleaseOnLoad.Contains(showEntityInfo.SerialId)) { _entitiesToReleaseOnLoad.Remove(showEntityInfo.SerialId); return; } _entitiesBeingLoaded.Remove(showEntityInfo.EntityId); string appendErrorMessage = Utility.Text.Format("Load entity failure, asset name '{0}', error message '{1}'.", entityAssetName, errorMessage); if (_showEntityFailureEventHandler != null) { TEngine.ShowEntityInfo info = (TEngine.ShowEntityInfo)showEntityInfo.UserData; Type entityLogicType = info.EntityLogicType; _showEntityFailureEventHandler.Invoke(showEntityInfo.EntityId, entityLogicType, entityAssetName, showEntityInfo.EntityGroup.Name, appendErrorMessage, showEntityInfo.UserData); return; } throw new GameFrameworkException(appendErrorMessage); } } }