// // Copyright (c) 2010-2023 Antmicro // Copyright (c) 2011-2015 Realtime Embedded // // This file is licensed under the MIT License. // Full license text is available in 'licenses/MIT.txt'. // using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections; using System.Linq; namespace Antmicro.Renode.Utilities.Collections { public abstract class TreeBase : IEnumerable where TNode : TreeBase { protected TreeBase(TValue value) { this.value = value; ChildrenList = new List(); ParentsList = new List(); } public IEnumerable Children { get { return new ReadOnlyCollection(ChildrenList); } } public IEnumerable Parents { get { return new ReadOnlyCollection(ParentsList); } } public TValue Value { get { return value; } } public void TraverseChildrenFirst(Action, int> nodeHandler, int initialLevel) { foreach(var child in ChildrenList) { child.TraverseChildrenFirst(nodeHandler, initialLevel + 1); } nodeHandler((TNode)this, ChildrenList, initialLevel); } public void TraverseParentFirst(Action nodeHandler, int initialLevel) { nodeHandler(value, initialLevel); foreach (var child in ChildrenList) { child.TraverseParentFirst(nodeHandler, initialLevel + 1); } } public TNode TryGetNode(Func predicate) { if(predicate(value)) { return (TNode)this; } foreach (var child in ChildrenList) { var node = child.TryGetNode(predicate); if (node != null) { return node; } } return null; } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public IEnumerator GetEnumerator() { yield return Value; foreach(var child in ChildrenList) { foreach(var element in child) { yield return element; } } } public abstract TNode AddChild(TValue value); public TNode TryGetNode(TValue valueToFind) { return TryGetNode(val => valueToFind.Equals(val)); } public virtual void RemoveChild(TValue value) { var node = ChildrenList.FirstOrDefault(x => value.Equals(x.Value)); if(node == null) { throw new InvalidOperationException($"Could not find child '{value}'."); } ChildrenList.Remove(node); } protected readonly List ParentsList; protected readonly List ChildrenList; private readonly TValue value; } }