using System; using System.Collections.Generic; using System.Linq; namespace Reflex.Editor.DebuggingWindow { // The TreeModel is a utility class working on a list of serializable TreeElements where the order and the depth of each TreeElement define // the tree structure. Note that the TreeModel itself is not serializable (in Unity we are currently limited to serializing lists/arrays) but the // input list is. // The tree representation (parent and children references) are then build internally using TreeElementUtility.ListToTree (using depth // values of the elements). // The first element of the input list is required to have depth == -1 (the hiddenroot) and the rest to have // depth >= 0 (otherwise an exception will be thrown) public class TreeModel where T : TreeElement { private IList _data; public T Root { get; private set; } public TreeModel(IList data) { SetData(data); } public T Find(int id) { return _data.FirstOrDefault(element => element.Id == id); } private void SetData(IList data) { Init(data); } private void Init(IList data) { if (data == null) { throw new ArgumentNullException("data", "Input data is null. Ensure input is a non-null list."); } _data = data; if (_data.Count > 0) { Root = TreeElementUtility.ListToTree(data); } } public IList GetAncestors(int id) { var parents = new List(); TreeElement T = Find(id); if (T != null) { while (T.Parent != null) { parents.Add(T.Parent.Id); T = T.Parent; } } return parents; } public IList GetDescendantsThatHaveChildren(int id) { T searchFromThis = Find(id); if (searchFromThis != null) { return GetParentsBelowStackBased(searchFromThis); } return new List(); } private static IList GetParentsBelowStackBased(TreeElement searchFromThis) { Stack stack = new Stack(); stack.Push(searchFromThis); var parentsBelow = new List(); while (stack.Count > 0) { TreeElement current = stack.Pop(); if (current.HasChildren) { parentsBelow.Add(current.Id); foreach (var T in current.Children) { stack.Push(T); } } } return parentsBelow; } } }