- #if TOOLS
- using System;
- using System.Collections.Generic;
- using Godot;
- namespace Plugin;
- /// <summary>
- /// 场景监听器, 一旦当前节点内容发生改变, 则直接调用 SceneNodeChangeEvent 事件
- /// </summary>
- public class NodeMonitor
- {
- private class SceneNode : IEquatable<SceneNode>
- {
- public SceneNode(string type, string name)
- {
- Type = type;
- Name = name;
- }
- public string Type;
- public string Name;
- public List<SceneNode> Children = new List<SceneNode>();
- public bool Equals(SceneNode other)
- {
- if (other == null)
- {
- return false;
- }
- if (other.Name != Name || other.Type != Type)
- {
- return false;
- }
- if (other.Children.Count != Children.Count)
- {
- return false;
- }
- for (var i = 0; i < Children.Count; i++)
- {
- if (!Children[i].Equals(other.Children[i]))
- {
- return false;
- }
- }
- return true;
- }
- }
- /// <summary>
- /// 场景节点有变化时的回调事件
- /// </summary>
- public event Action<Node> SceneNodeChangeEvent;
- private SceneNode _sceneNode;
- private Node _targetNode;
- private double _checkTreeTimer = 0;
- /// <summary>
- /// 更新监听的节点
- /// </summary>
- public void ChangeCurrentNode(Node node)
- {
- //更新前检查旧的节点是否发生改变
- if (node != _targetNode && _targetNode != null)
- {
- try
- {
- var tempNode = ParseNodeTree(_targetNode);
- if (!_sceneNode.Equals(tempNode))
- {
- OnSceneNodeChange(_targetNode);
- }
- }
- catch (Exception e)
- {
- //检查节点存在报错, 直接跳过该节点的检查
- GD.Print(e.Message);
- }
- }
- if (node != null)
- {
- _sceneNode = ParseNodeTree(node);
- _targetNode = node;
- }
- else
- {
- _targetNode = null;
- }
- _checkTreeTimer = 0;
- }
- public void Process(float delta)
- {
- if (_targetNode == null)
- return;
- _checkTreeTimer += delta;
- if (_checkTreeTimer >= 5) //5秒检查一次
- {
- try
- {
- var tempNode = ParseNodeTree(_targetNode);
- if (!_sceneNode.Equals(tempNode))
- {
- OnSceneNodeChange(_targetNode);
- _sceneNode = tempNode;
- }
- }
- catch (Exception e)
- {
- //检查节点存在报错, 直接跳过该节点的检查
- GD.Print(e.Message);
- _targetNode = null;
- }
- _checkTreeTimer = 0;
- }
- }
- private SceneNode ParseNodeTree(Node node)
- {
- var uiNode = new SceneNode(node.GetType().FullName, node.Name);
- var count = node.GetChildCount();
- for (var i = 0; i < count; i++)
- {
- uiNode.Children.Add(ParseNodeTree(node.GetChild(i)));
- }
- return uiNode;
- }
- private void OnSceneNodeChange(Node node)
- {
- if (SceneNodeChangeEvent != null)
- {
- SceneNodeChangeEvent(node);
- }
- }
- }
- #endif