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}