No Description
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.

SGController.cs 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. using System;
  2. using System.Collections;
  3. using System.Linq;
  4. using System.Collections.Generic;
  5. using UnityEditor;
  6. using UnityEngine;
  7. using UnityEngine.UIElements;
  8. using UnityEditor.ShaderGraph.Drawing;
  9. using GraphDataStore = UnityEditor.ShaderGraph.DataStore<UnityEditor.ShaderGraph.GraphData>;
  10. namespace UnityEditor.ShaderGraph
  11. {
  12. class DummyChangeAction : IGraphDataAction
  13. {
  14. void OnDummyChangeAction(GraphData m_GraphData)
  15. {
  16. }
  17. public Action<GraphData> modifyGraphDataAction => OnDummyChangeAction;
  18. }
  19. struct SGControllerChangedEvent
  20. {
  21. public ISGControlledElement target;
  22. public SGController controller;
  23. public IGraphDataAction change;
  24. private bool m_PropagationStopped;
  25. void StopPropagation()
  26. {
  27. m_PropagationStopped = true;
  28. }
  29. public bool isPropagationStopped => m_PropagationStopped;
  30. }
  31. class SGControllerEvent
  32. {
  33. ISGControlledElement target = null;
  34. SGControllerEvent(ISGControlledElement controlledTarget)
  35. {
  36. target = controlledTarget;
  37. }
  38. }
  39. abstract class SGController
  40. {
  41. public bool m_DisableCalled = false;
  42. protected IGraphDataAction DummyChange = new DummyChangeAction();
  43. public virtual void OnDisable()
  44. {
  45. if (m_DisableCalled)
  46. Debug.LogError(GetType().Name + ".Disable called twice");
  47. m_DisableCalled = true;
  48. foreach (var element in allChildren)
  49. {
  50. UnityEngine.Profiling.Profiler.BeginSample(element.GetType().Name + ".OnDisable");
  51. element.OnDisable();
  52. UnityEngine.Profiling.Profiler.EndSample();
  53. }
  54. }
  55. internal void RegisterHandler(ISGControlledElement handler)
  56. {
  57. //Debug.Log("RegisterHandler of " + handler.GetType().Name + " on " + GetType().Name );
  58. if (m_EventHandlers.Contains(handler))
  59. Debug.LogError("Handler registered twice");
  60. else
  61. {
  62. m_EventHandlers.Add(handler);
  63. NotifyEventHandler(handler, DummyChange);
  64. }
  65. }
  66. internal void UnregisterHandler(ISGControlledElement handler)
  67. {
  68. m_EventHandlers.Remove(handler);
  69. }
  70. protected void NotifyChange(IGraphDataAction changeAction)
  71. {
  72. var eventHandlers = m_EventHandlers.ToArray(); // Some notification may trigger Register/Unregister so duplicate the collection.
  73. foreach (var eventHandler in eventHandlers)
  74. {
  75. UnityEngine.Profiling.Profiler.BeginSample("NotifyChange:" + eventHandler.GetType().Name);
  76. NotifyEventHandler(eventHandler, changeAction);
  77. UnityEngine.Profiling.Profiler.EndSample();
  78. }
  79. }
  80. void NotifyEventHandler(ISGControlledElement eventHandler, IGraphDataAction changeAction)
  81. {
  82. SGControllerChangedEvent e = new SGControllerChangedEvent();
  83. e.controller = this;
  84. e.target = eventHandler;
  85. e.change = changeAction;
  86. eventHandler.OnControllerChanged(ref e);
  87. if (e.isPropagationStopped)
  88. return;
  89. if (eventHandler is VisualElement)
  90. {
  91. var element = eventHandler as VisualElement;
  92. eventHandler = element.GetFirstOfType<ISGControlledElement>();
  93. while (eventHandler != null)
  94. {
  95. eventHandler.OnControllerChanged(ref e);
  96. if (e.isPropagationStopped)
  97. break;
  98. eventHandler = (eventHandler as VisualElement).GetFirstAncestorOfType<ISGControlledElement>();
  99. }
  100. }
  101. }
  102. public void SendEvent(SGControllerEvent e)
  103. {
  104. var eventHandlers = m_EventHandlers.ToArray(); // Some notification may trigger Register/Unregister so duplicate the collection.
  105. foreach (var eventHandler in eventHandlers)
  106. {
  107. eventHandler.OnControllerEvent(e);
  108. }
  109. }
  110. public abstract void ApplyChanges();
  111. public virtual IEnumerable<SGController> allChildren
  112. {
  113. get { return Enumerable.Empty<SGController>(); }
  114. }
  115. protected List<ISGControlledElement> m_EventHandlers = new List<ISGControlledElement>();
  116. }
  117. abstract class SGController<T> : SGController
  118. {
  119. GraphDataStore m_DataStore;
  120. protected GraphDataStore DataStore => m_DataStore;
  121. protected SGController(T model, GraphDataStore dataStore)
  122. {
  123. m_Model = model;
  124. m_DataStore = dataStore;
  125. DataStore.Subscribe += ModelChanged;
  126. }
  127. protected abstract void RequestModelChange(IGraphDataAction changeAction);
  128. protected abstract void ModelChanged(GraphData graphData, IGraphDataAction changeAction);
  129. T m_Model;
  130. public T Model => m_Model;
  131. // Cleanup delegate association before destruction
  132. public void Cleanup()
  133. {
  134. if (m_DataStore == null)
  135. return;
  136. DataStore.Subscribe -= ModelChanged;
  137. m_Model = default;
  138. m_DataStore = null;
  139. }
  140. }
  141. abstract class SGViewController<ModelType, ViewModelType> : SGController<ModelType>
  142. {
  143. protected SGViewController(ModelType model, ViewModelType viewModel, GraphDataStore graphDataStore) : base(model, graphDataStore)
  144. {
  145. m_ViewModel = viewModel;
  146. try
  147. {
  148. // Need ViewModel to be initialized before we call ModelChanged() [as view model might need to update]
  149. ModelChanged(DataStore.State, DummyChange);
  150. }
  151. catch (Exception e)
  152. {
  153. Debug.Log("Failed to initialize View Controller of type: " + this.GetType() + " due to exception: " + e);
  154. }
  155. }
  156. // Holds data specific to the views this controller is responsible for
  157. ViewModelType m_ViewModel;
  158. public ViewModelType ViewModel => m_ViewModel;
  159. public override void ApplyChanges()
  160. {
  161. foreach (var controller in allChildren)
  162. {
  163. controller.ApplyChanges();
  164. }
  165. }
  166. public virtual void Dispose()
  167. {
  168. m_EventHandlers.Clear();
  169. m_ViewModel = default;
  170. }
  171. }
  172. }