123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- using System;
- using System.Collections;
- using System.Linq;
- using System.Collections.Generic;
-
- using UnityEditor;
- using UnityEngine;
- using UnityEngine.UIElements;
- using UnityEditor.ShaderGraph.Drawing;
-
- using GraphDataStore = UnityEditor.ShaderGraph.DataStore<UnityEditor.ShaderGraph.GraphData>;
-
- namespace UnityEditor.ShaderGraph
- {
- class DummyChangeAction : IGraphDataAction
- {
- void OnDummyChangeAction(GraphData m_GraphData)
- {
- }
-
- public Action<GraphData> modifyGraphDataAction => OnDummyChangeAction;
- }
-
- struct SGControllerChangedEvent
- {
- public ISGControlledElement target;
- public SGController controller;
- public IGraphDataAction change;
-
- private bool m_PropagationStopped;
- void StopPropagation()
- {
- m_PropagationStopped = true;
- }
-
- public bool isPropagationStopped => m_PropagationStopped;
- }
-
- class SGControllerEvent
- {
- ISGControlledElement target = null;
-
- SGControllerEvent(ISGControlledElement controlledTarget)
- {
- target = controlledTarget;
- }
- }
-
- abstract class SGController
- {
- public bool m_DisableCalled = false;
-
- protected IGraphDataAction DummyChange = new DummyChangeAction();
-
- public virtual void OnDisable()
- {
- if (m_DisableCalled)
- Debug.LogError(GetType().Name + ".Disable called twice");
-
- m_DisableCalled = true;
- foreach (var element in allChildren)
- {
- UnityEngine.Profiling.Profiler.BeginSample(element.GetType().Name + ".OnDisable");
- element.OnDisable();
- UnityEngine.Profiling.Profiler.EndSample();
- }
- }
-
- internal void RegisterHandler(ISGControlledElement handler)
- {
- //Debug.Log("RegisterHandler of " + handler.GetType().Name + " on " + GetType().Name );
-
- if (m_EventHandlers.Contains(handler))
- Debug.LogError("Handler registered twice");
- else
- {
- m_EventHandlers.Add(handler);
-
- NotifyEventHandler(handler, DummyChange);
- }
- }
-
- internal void UnregisterHandler(ISGControlledElement handler)
- {
- m_EventHandlers.Remove(handler);
- }
-
- protected void NotifyChange(IGraphDataAction changeAction)
- {
- var eventHandlers = m_EventHandlers.ToArray(); // Some notification may trigger Register/Unregister so duplicate the collection.
-
- foreach (var eventHandler in eventHandlers)
- {
- UnityEngine.Profiling.Profiler.BeginSample("NotifyChange:" + eventHandler.GetType().Name);
- NotifyEventHandler(eventHandler, changeAction);
- UnityEngine.Profiling.Profiler.EndSample();
- }
- }
-
- void NotifyEventHandler(ISGControlledElement eventHandler, IGraphDataAction changeAction)
- {
- SGControllerChangedEvent e = new SGControllerChangedEvent();
- e.controller = this;
- e.target = eventHandler;
- e.change = changeAction;
- eventHandler.OnControllerChanged(ref e);
- if (e.isPropagationStopped)
- return;
- if (eventHandler is VisualElement)
- {
- var element = eventHandler as VisualElement;
- eventHandler = element.GetFirstOfType<ISGControlledElement>();
- while (eventHandler != null)
- {
- eventHandler.OnControllerChanged(ref e);
- if (e.isPropagationStopped)
- break;
- eventHandler = (eventHandler as VisualElement).GetFirstAncestorOfType<ISGControlledElement>();
- }
- }
- }
-
- public void SendEvent(SGControllerEvent e)
- {
- var eventHandlers = m_EventHandlers.ToArray(); // Some notification may trigger Register/Unregister so duplicate the collection.
-
- foreach (var eventHandler in eventHandlers)
- {
- eventHandler.OnControllerEvent(e);
- }
- }
-
- public abstract void ApplyChanges();
-
- public virtual IEnumerable<SGController> allChildren
- {
- get { return Enumerable.Empty<SGController>(); }
- }
-
- protected List<ISGControlledElement> m_EventHandlers = new List<ISGControlledElement>();
- }
-
- abstract class SGController<T> : SGController
- {
- GraphDataStore m_DataStore;
- protected GraphDataStore DataStore => m_DataStore;
-
- protected SGController(T model, GraphDataStore dataStore)
- {
- m_Model = model;
- m_DataStore = dataStore;
- DataStore.Subscribe += ModelChanged;
- }
-
- protected abstract void RequestModelChange(IGraphDataAction changeAction);
-
- protected abstract void ModelChanged(GraphData graphData, IGraphDataAction changeAction);
-
- T m_Model;
- public T Model => m_Model;
-
- // Cleanup delegate association before destruction
- public void Cleanup()
- {
- if (m_DataStore == null)
- return;
- DataStore.Subscribe -= ModelChanged;
- m_Model = default;
- m_DataStore = null;
- }
- }
-
- abstract class SGViewController<ModelType, ViewModelType> : SGController<ModelType>
- {
- protected SGViewController(ModelType model, ViewModelType viewModel, GraphDataStore graphDataStore) : base(model, graphDataStore)
- {
- m_ViewModel = viewModel;
- try
- {
- // Need ViewModel to be initialized before we call ModelChanged() [as view model might need to update]
- ModelChanged(DataStore.State, DummyChange);
- }
- catch (Exception e)
- {
- Debug.Log("Failed to initialize View Controller of type: " + this.GetType() + " due to exception: " + e);
- }
- }
-
- // Holds data specific to the views this controller is responsible for
- ViewModelType m_ViewModel;
- public ViewModelType ViewModel => m_ViewModel;
-
- public override void ApplyChanges()
- {
- foreach (var controller in allChildren)
- {
- controller.ApplyChanges();
- }
- }
-
- public virtual void Dispose()
- {
- m_EventHandlers.Clear();
- m_ViewModel = default;
- }
- }
- }
|