暫無描述
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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