1 // 2 // Copyright (c) 2010-2023 Antmicro 3 // Copyright (c) 2011-2015 Realtime Embedded 4 // 5 // This file is licensed under the MIT License. 6 // Full license text is available in 'licenses/MIT.txt'. 7 // 8 9 using System; 10 using System.Collections.Generic; 11 using System.Collections.ObjectModel; 12 using System.Collections; 13 using System.Linq; 14 15 namespace Antmicro.Renode.Utilities.Collections 16 { 17 18 public abstract class TreeBase<TNode, TValue> : IEnumerable<TValue> where TNode : TreeBase<TNode, TValue> 19 { TreeBase(TValue value)20 protected TreeBase(TValue value) 21 { 22 this.value = value; 23 ChildrenList = new List<TNode>(); 24 ParentsList = new List<TNode>(); 25 } 26 27 public IEnumerable<TNode> Children 28 { 29 get 30 { 31 return new ReadOnlyCollection<TNode>(ChildrenList); 32 } 33 } 34 35 public IEnumerable<TNode> Parents 36 { 37 get 38 { 39 return new ReadOnlyCollection<TNode>(ParentsList); 40 } 41 } 42 43 public TValue Value 44 { 45 get 46 { 47 return value; 48 } 49 } 50 TraverseChildrenFirst(Action<TNode, List<TNode>, int> nodeHandler, int initialLevel)51 public void TraverseChildrenFirst(Action<TNode, List<TNode>, int> nodeHandler, int initialLevel) 52 { 53 foreach(var child in ChildrenList) 54 { 55 child.TraverseChildrenFirst(nodeHandler, initialLevel + 1); 56 } 57 58 nodeHandler((TNode)this, ChildrenList, initialLevel); 59 } 60 TraverseParentFirst(Action<TValue, int> nodeHandler, int initialLevel)61 public void TraverseParentFirst(Action<TValue, int> nodeHandler, int initialLevel) 62 { 63 nodeHandler(value, initialLevel); 64 foreach (var child in ChildrenList) 65 { 66 child.TraverseParentFirst(nodeHandler, initialLevel + 1); 67 } 68 } 69 TryGetNode(Func<TValue, bool> predicate)70 public TNode TryGetNode(Func<TValue, bool> predicate) 71 { 72 if(predicate(value)) 73 { 74 return (TNode)this; 75 } 76 foreach (var child in ChildrenList) 77 { 78 var node = child.TryGetNode(predicate); 79 if (node != null) 80 { 81 return node; 82 } 83 } 84 return null; 85 } 86 IEnumerable.GetEnumerator()87 IEnumerator IEnumerable.GetEnumerator() 88 { 89 return GetEnumerator(); 90 } 91 GetEnumerator()92 public IEnumerator<TValue> GetEnumerator() 93 { 94 yield return Value; 95 foreach(var child in ChildrenList) 96 { 97 foreach(var element in child) 98 { 99 yield return element; 100 } 101 } 102 } 103 AddChild(TValue value)104 public abstract TNode AddChild(TValue value); 105 TryGetNode(TValue valueToFind)106 public TNode TryGetNode(TValue valueToFind) 107 { 108 return TryGetNode(val => valueToFind.Equals(val)); 109 } 110 RemoveChild(TValue value)111 public virtual void RemoveChild(TValue value) 112 { 113 var node = ChildrenList.FirstOrDefault(x => value.Equals(x.Value)); 114 if(node == null) 115 { 116 throw new InvalidOperationException($"Could not find child '{value}'."); 117 } 118 ChildrenList.Remove(node); 119 } 120 121 protected readonly List<TNode> ParentsList; 122 protected readonly List<TNode> ChildrenList; 123 private readonly TValue value; 124 } 125 } 126