Files
Studio/Assets/legacy/Scripts/HierarchyTree.cs

180 lines
4.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.PlayerLoop;
using XRLib;
namespace Studio.Hierarchy
{
public class HierarchyTree
{
public event Action<TreeItem> onAddEvent;
public event Action<TreeItem> onSelectEvent;
public event Action<TwinObject> onRemoveEvent;
public event Action<TreeItem> onDeselectEvent;
public event Action<List<TreeItem>> onDataUpdate;
HashSet<TreeItem> tempHashSet = new();
HashSet<TwinObject> rootObjects = new();
List<TreeItem> data = new List<TreeItem>();
Dictionary<TwinObject, TreeItem> twinToItem = new Dictionary<TwinObject, TreeItem>();
TreeItem CreateItem(TwinObject to)
{
TreeItem item = new TreeItem(to);
data.Add(item);
twinToItem.Add(to, item);
return item;
}
public bool isExist(TwinObject to)
{
return rootObjects.Contains(to);
}
public void Add(TwinObject to)
{
if (!rootObjects.Add(to))
return;
var item = CreateItem(to);
onAddEvent?.Invoke(item);
}
public void Remove(TwinObject to)
{
if (!rootObjects.Contains(to))
{
return;
}
GetChilds(twinToItem[to]);
foreach (var item in tempHashSet)
{
rootObjects.Remove(item.ToItem);
item.parent?.RemoveChild(item);
onRemoveEvent?.Invoke(item.ToItem);
item.DestroyTreeItem();
data.Remove(item);
twinToItem.Remove(item.ToItem);
GameObject.Destroy(item.ToItem.gameObject);
}
tempHashSet.Clear();
onDataUpdate(data);
}
void GetChilds(TreeItem go)
{
tempHashSet.Add(go);
foreach (var c in go.children)
{
GetChilds(c);
}
}
public void Attach(TreeItem p, TreeItem t)
{
if (!data.Contains(p))
{
Debug.LogError("Parent not found");
return;
}
if (!data.Contains(t))
{
Debug.LogError("Child not found");
return;
}
if (p == t)
{
return;
}
GetChilds(t);
foreach (var item in tempHashSet)
{
if (p.parent == item)
{
Debug.LogError("It is infinite");
tempHashSet.Clear();
return;
}
}
t.parent?.RemoveChild(t);
p.Add(t);
t.parent = p;
data.Remove(t);
var index = data.IndexOf(p) + 1;
if (index >= data.Count)
{
if (tempHashSet.Count > 1)
{
foreach (var item in tempHashSet)
{
data?.Remove(item);
data.Add(item);
}
}
else
{
data.Add(t);
}
}
else
{
int i = 0;
if (tempHashSet.Count > 1)
{
foreach (var item in tempHashSet)
{
data?.Remove(item);
data.Insert(index + i, item);
i++;
}
}
else
{
data.Insert(index, t);
}
}
tempHashSet.Clear();
onDataUpdate(data);
}
public void Dettach(TreeItem item)
{
if (!data.Contains(item))
{
Debug.LogError("Not found");
return;
}
item.parent?.RemoveChild(item);
item.parent = null;
GetChilds(item);
foreach (var i in tempHashSet)
{
data?.Remove(i);
data.Add(i);
}
tempHashSet.Clear();
onDataUpdate(data);
}
internal void Select(TwinObject to)
{
onSelectEvent?.Invoke(twinToItem[to]);
}
public void Select(TreeItem ti)
{
onSelectEvent?.Invoke(ti);
}
internal void Deselect(TwinObject to)
{
onDeselectEvent?.Invoke(twinToItem[to]);
}
}
}