using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
///
/// 在多 SceneView 窗口下安全地添加/移除临时回调。
/// 原理:Templist 存放需在下一帧执行的回调,OnSceneGUI 将会把 Templist 转移到 list 来执行。
///
public class UXCustomSceneView
{
static private List> list = new List>();
static private List> Templist = new List>();
[InitializeOnLoadMethod]
static void Init()
{
list.Clear();
Templist.Clear();
SceneView.duringSceneGui -= OnSceneGUI;
SceneView.duringSceneGui += OnSceneGUI;
}
static public void AddDelegate(Action method)
{
if (method == null) return;
// 去重
if (!Templist.Contains(method))
Templist.Add(method);
}
static public void RemoveDelegate(Action method)
{
if (method == null) return;
var idx = Templist.FindIndex(i => i == method);
if (idx >= 0) Templist.RemoveAt(idx);
}
static public void OnSceneGUI(SceneView sceneView)
{
// 执行上一帧注册的 list
foreach (Action method in list)
{
try
{
method.Invoke(sceneView);
}
catch (Exception e)
{
Debug.LogException(e);
}
}
list.Clear();
// 将 Templist 拷贝到 list,并在下一帧执行,这样可以避免在枚举时修改集合的问题
foreach (Action method in Templist)
{
if (!list.Contains(method))
list.Add(method);
}
}
static public void ClearDelegate()
{
Templist.Clear();
}
}