using System; using System.Collections.Generic; using XGame.Framework.Asyncs; using XGame.Framework.Interfaces; namespace XGame.Framework.Nodes { public class NodeTree : INodeTree, IUpdate, ILateUpdate, IDisposable { public INode Root { get; private set; } private NodeContext _context; private Dictionary _nodeGroupMap; private List _updates; private List _lateUpdate; public NodeTree(NodeContext context, INode root) { _context = context; Root = root; _nodeGroupMap = new Dictionary(); _updates = new List(); _lateUpdate = new List(); if (root is IUpdate update) { _updates.Add(update); } if (root is ILateUpdate lateUpdate) { _lateUpdate.Add(lateUpdate); } } #region 接口实现 void INodeTree.RemoveGroup(uint groupId, bool isDestroy) { if (_nodeGroupMap.TryGetValue(groupId, out var group)) { var removeAsync = group.RemoveAll(isDestroy); if (isDestroy) { _nodeGroupMap.Remove(groupId); removeAsync.On(_ => { Log.Debug($"NodeTree RemoveGroup Callback. GroupId:{groupId}"); (group as IDisposable)?.Dispose(); }); } } } public IAsync AddAsync(NodeKey nodeKey, object intent) { return GetGroup(nodeKey.GroupId).AddAsync(nodeKey, intent); } public bool IsActive(NodeKey nodeKey) { return GetGroup(nodeKey.GroupId).IsActive(nodeKey); } public IAsync Preload(NodeKey nodeKey) { return GetGroup(nodeKey.GroupId).Preload(nodeKey); } public void Remove(NodeKey nodeKey, bool isDestroy) { GetGroup(nodeKey.GroupId).Remove(nodeKey, isDestroy); } void IUpdate.Update(int millisecond) { foreach(var impl in _updates) { impl.Update(millisecond); } } void ILateUpdate.LateUpdate(int millisecond) { foreach (var impl in _lateUpdate) { impl.LateUpdate(millisecond); } } void IDisposable.Dispose() { foreach(var item in _nodeGroupMap) { (item.Value as IDisposable)?.Dispose(); } _nodeGroupMap.Clear(); _updates.Clear(); _lateUpdate.Clear(); Root.Disable(); (Root as IDisposable)?.Dispose(); Root = null; (_context as IDisposable)?.Dispose(); _context = null; } #endregion #region 内部方法 private INodeGroup GetGroup(uint id) { if (!_nodeGroupMap.TryGetValue(id, out var group)) { group = new NodeGroup(_context.Clone()); _nodeGroupMap.Add(id, group); _updates.Add(group); _lateUpdate.Add(group); } return group; } #endregion } }