A game about forced loneliness, made by TACStudios
1using System; 2using System.Collections.Generic; 3using UnityEngine; 4 5namespace Unity.VisualScripting 6{ 7 public static class GraphInstances 8 { 9 private static readonly object @lock = new object(); 10 11 private static readonly Dictionary<IGraph, HashSet<GraphReference>> byGraph = new Dictionary<IGraph, HashSet<GraphReference>>(); 12 13 private static readonly Dictionary<IGraphParent, HashSet<GraphReference>> byParent = new Dictionary<IGraphParent, HashSet<GraphReference>>(); 14 15 public static void Instantiate(GraphReference instance) 16 { 17 lock (@lock) 18 { 19 Ensure.That(nameof(instance)).IsNotNull(instance); 20 21 instance.CreateGraphData(); 22 23 instance.graph.Instantiate(instance); 24 25 if (!byGraph.TryGetValue(instance.graph, out var instancesWithGraph)) 26 { 27 instancesWithGraph = new HashSet<GraphReference>(); 28 byGraph.Add(instance.graph, instancesWithGraph); 29 } 30 31 if (instancesWithGraph.Add(instance)) 32 { 33 // Debug.Log($"Added graph instance mapping:\n{instance.graph} => {instance}"); 34 } 35 else 36 { 37 Debug.LogWarning($"Attempting to add duplicate graph instance mapping:\n{instance.graph} => {instance}"); 38 } 39 40 if (!byParent.TryGetValue(instance.parent, out var instancesWithParent)) 41 { 42 instancesWithParent = new HashSet<GraphReference>(); 43 byParent.Add(instance.parent, instancesWithParent); 44 } 45 46 if (instancesWithParent.Add(instance)) 47 { 48 // Debug.Log($"Added parent instance mapping:\n{instance.parent.ToSafeString()} => {instance}"); 49 } 50 else 51 { 52 Debug.LogWarning($"Attempting to add duplicate parent instance mapping:\n{instance.parent.ToSafeString()} => {instance}"); 53 } 54 } 55 } 56 57 public static void Uninstantiate(GraphReference instance) 58 { 59 lock (@lock) 60 { 61 instance.graph.Uninstantiate(instance); 62 63 if (!byGraph.TryGetValue(instance.graph, out var instancesWithGraph)) 64 { 65 throw new InvalidOperationException("Graph instance not found via graph."); 66 } 67 68 if (instancesWithGraph.Remove(instance)) 69 { 70 // Debug.Log($"Removed graph instance mapping:\n{instance.graph} => {instance}"); 71 72 // Free the key references for GC collection 73 if (instancesWithGraph.Count == 0) 74 { 75 byGraph.Remove(instance.graph); 76 } 77 } 78 else 79 { 80 Debug.LogWarning($"Could not find graph instance mapping to remove:\n{instance.graph} => {instance}"); 81 } 82 83 if (!byParent.TryGetValue(instance.parent, out var instancesWithParent)) 84 { 85 throw new InvalidOperationException("Graph instance not found via parent."); 86 } 87 88 if (instancesWithParent.Remove(instance)) 89 { 90 // Debug.Log($"Removed parent instance mapping:\n{instance.parent.ToSafeString()} => {instance}"); 91 92 // Free the key references for GC collection 93 if (instancesWithParent.Count == 0) 94 { 95 byParent.Remove(instance.parent); 96 } 97 } 98 else 99 { 100 Debug.LogWarning($"Could not find parent instance mapping to remove:\n{instance.parent.ToSafeString()} => {instance}"); 101 } 102 103 // It's important to only free the graph data after 104 // dissociating the instance mapping, because the data 105 // is used as part of the equality comparison for pointers 106 instance.FreeGraphData(); 107 } 108 } 109 110 public static HashSet<GraphReference> OfPooled(IGraph graph) 111 { 112 Ensure.That(nameof(graph)).IsNotNull(graph); 113 114 lock (@lock) 115 { 116 if (byGraph.TryGetValue(graph, out var instances)) 117 { 118 // Debug.Log($"Found {instances.Count} instances of {graph}\n{instances.ToLineSeparatedString()}"); 119 120 return instances.ToHashSetPooled(); 121 } 122 else 123 { 124 // Debug.Log($"Found no instances of {graph}.\n"); 125 126 return HashSetPool<GraphReference>.New(); 127 } 128 } 129 } 130 131 public static HashSet<GraphReference> ChildrenOfPooled(IGraphParent parent) 132 { 133 Ensure.That(nameof(parent)).IsNotNull(parent); 134 135 lock (@lock) 136 { 137 if (byParent.TryGetValue(parent, out var instances)) 138 { 139 // Debug.Log($"Found {instances.Count} instances of {parent.ToSafeString()}\n{instances.ToLineSeparatedString()}"); 140 141 return instances.ToHashSetPooled(); 142 } 143 else 144 { 145 // Debug.Log($"Found no instances of {parent.ToSafeString()}.\n"); 146 147 return HashSetPool<GraphReference>.New(); 148 } 149 } 150 } 151 } 152}