A game about forced loneliness, made by TACStudios
1using System; 2using System.Collections.Generic; 3using System.ComponentModel; 4using System.Linq; 5using UnityEngine; 6 7namespace Unity.VisualScripting 8{ 9 [SerializationVersion("A")] 10 [DisplayName("Script Graph")] 11 public sealed class FlowGraph : Graph, IGraphWithVariables, IGraphEventListener 12 { 13 public FlowGraph() 14 { 15 units = new GraphElementCollection<IUnit>(this); 16 controlConnections = new GraphConnectionCollection<ControlConnection, ControlOutput, ControlInput>(this); 17 valueConnections = new GraphConnectionCollection<ValueConnection, ValueOutput, ValueInput>(this); 18 invalidConnections = new GraphConnectionCollection<InvalidConnection, IUnitOutputPort, IUnitInputPort>(this); 19 groups = new GraphElementCollection<GraphGroup>(this); 20 sticky = new GraphElementCollection<StickyNote>(this); 21 22 elements.Include(units); 23 elements.Include(controlConnections); 24 elements.Include(valueConnections); 25 elements.Include(invalidConnections); 26 elements.Include(groups); 27 elements.Include(sticky); 28 29 controlInputDefinitions = new UnitPortDefinitionCollection<ControlInputDefinition>(); 30 controlOutputDefinitions = new UnitPortDefinitionCollection<ControlOutputDefinition>(); 31 valueInputDefinitions = new UnitPortDefinitionCollection<ValueInputDefinition>(); 32 valueOutputDefinitions = new UnitPortDefinitionCollection<ValueOutputDefinition>(); 33 34 variables = new VariableDeclarations(); 35 } 36 37 public override IGraphData CreateData() 38 { 39 return new FlowGraphData(this); 40 } 41 42 public void StartListening(GraphStack stack) 43 { 44 stack.GetGraphData<FlowGraphData>().isListening = true; 45 46 foreach (var unit in units) 47 { 48 (unit as IGraphEventListener)?.StartListening(stack); 49 } 50 } 51 52 public void StopListening(GraphStack stack) 53 { 54 foreach (var unit in units) 55 { 56 (unit as IGraphEventListener)?.StopListening(stack); 57 } 58 59 stack.GetGraphData<FlowGraphData>().isListening = false; 60 } 61 62 public bool IsListening(GraphPointer pointer) 63 { 64 return pointer.GetGraphData<FlowGraphData>().isListening; 65 } 66 67 #region Variables 68 69 [Serialize] 70 public VariableDeclarations variables { get; private set; } 71 72 public IEnumerable<string> GetDynamicVariableNames(VariableKind kind, GraphReference reference) 73 { 74 return units.OfType<IUnifiedVariableUnit>() 75 .Where(v => v.kind == kind && Flow.CanPredict(v.name, reference)) 76 .Select(v => Flow.Predict<string>(v.name, reference)) 77 .Where(name => !StringUtility.IsNullOrWhiteSpace(name)) 78 .Distinct() 79 .OrderBy(name => name); 80 } 81 82 #endregion 83 84 85 #region Elements 86 87 [DoNotSerialize] 88 public GraphElementCollection<IUnit> units { get; private set; } 89 90 [DoNotSerialize] 91 public GraphConnectionCollection<ControlConnection, ControlOutput, ControlInput> controlConnections { get; private set; } 92 93 [DoNotSerialize] 94 public GraphConnectionCollection<ValueConnection, ValueOutput, ValueInput> valueConnections { get; private set; } 95 96 [DoNotSerialize] 97 public GraphConnectionCollection<InvalidConnection, IUnitOutputPort, IUnitInputPort> invalidConnections { get; private set; } 98 99 [DoNotSerialize] 100 public GraphElementCollection<GraphGroup> groups { get; private set; } 101 102 [DoNotSerialize] 103 public GraphElementCollection<StickyNote> sticky { get; private set; } 104 #endregion 105 106 107 #region Definition 108 109 private const string DefinitionRemoveWarningTitle = "Remove Port Definition"; 110 111 private const string DefinitionRemoveWarningMessage = "Removing this definition will break any existing connection to this port. Are you sure you want to continue?"; 112 113 [Serialize] 114 [InspectorLabel("Trigger Inputs")] 115 [InspectorWide(true)] 116 [WarnBeforeRemoving(DefinitionRemoveWarningTitle, DefinitionRemoveWarningMessage)] 117 public UnitPortDefinitionCollection<ControlInputDefinition> controlInputDefinitions { get; private set; } 118 119 [Serialize] 120 [InspectorLabel("Trigger Outputs")] 121 [InspectorWide(true)] 122 [WarnBeforeRemoving(DefinitionRemoveWarningTitle, DefinitionRemoveWarningMessage)] 123 public UnitPortDefinitionCollection<ControlOutputDefinition> controlOutputDefinitions { get; private set; } 124 125 [Serialize] 126 [InspectorLabel("Data Inputs")] 127 [InspectorWide(true)] 128 [WarnBeforeRemoving(DefinitionRemoveWarningTitle, DefinitionRemoveWarningMessage)] 129 public UnitPortDefinitionCollection<ValueInputDefinition> valueInputDefinitions { get; private set; } 130 131 [Serialize] 132 [InspectorLabel("Data Outputs")] 133 [InspectorWide(true)] 134 [WarnBeforeRemoving(DefinitionRemoveWarningTitle, DefinitionRemoveWarningMessage)] 135 public UnitPortDefinitionCollection<ValueOutputDefinition> valueOutputDefinitions { get; private set; } 136 137 public IEnumerable<IUnitPortDefinition> validPortDefinitions => 138 LinqUtility.Concat<IUnitPortDefinition>(controlInputDefinitions, 139 controlOutputDefinitions, 140 valueInputDefinitions, 141 valueOutputDefinitions) 142 .Where(upd => upd.isValid) 143 .DistinctBy(upd => upd.key); 144 145 public event Action onPortDefinitionsChanged; 146 147 public void PortDefinitionsChanged() 148 { 149 onPortDefinitionsChanged?.Invoke(); 150 } 151 152 #endregion 153 154 public static FlowGraph WithInputOutput() 155 { 156 return new FlowGraph() 157 { 158 units = 159 { 160 new GraphInput() { position = new Vector2(-250, -30) }, 161 new GraphOutput() { position = new Vector2(105, -30) } 162 } 163 }; 164 } 165 166 public static FlowGraph WithStartUpdate() 167 { 168 return new FlowGraph() 169 { 170 units = 171 { 172 new Start() { position = new Vector2(-204, -144) }, 173 new Update() { position = new Vector2(-204, 60) } 174 } 175 }; 176 } 177 } 178}