예제 #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="LoadGraphAssetCommand"/> class.
 /// </summary>
 /// <param name="assetPath">The path of the asset to load.</param>
 /// <param name="assetLocalId">The subasset file id. If 0, the first GraphAssetModel found in the file will be loaded.</param>
 /// <param name="pluginRepository">The plugin repository.</param>
 /// <param name="boundObject">The game object to which the graph should be bound.</param>
 /// <param name="loadStrategy">The type of loading and how it should affect the stack of loaded assets.</param>
 /// <param name="truncateHistoryIndex">Truncate the stack of loaded assets at this index.</param>
 public LoadGraphAssetCommand(string assetPath, long assetLocalId, PluginRepository pluginRepository, GameObject boundObject = null,
                              LoadStrategies loadStrategy = LoadStrategies.Replace, int truncateHistoryIndex = -1)
 {
     Asset                = null;
     AssetPath            = assetPath;
     BoundObject          = boundObject;
     LoadStrategy         = loadStrategy;
     FileId               = assetLocalId;
     PluginRepository     = pluginRepository;
     TruncateHistoryIndex = truncateHistoryIndex;
 }
예제 #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="AutomaticGraphProcessor" /> class.
        /// </summary>
        /// <param name="pluginRepository">The plugin repository.</param>
        public AutomaticGraphProcessor(PluginRepository pluginRepository)
            : base(new[]
        {
            nameof(GraphToolState.GraphViewState),
            nameof(GraphToolState.TracingStatusState)
        },
                   new[]
        {
            nameof(GraphToolState.GraphProcessingState)
        })
        {
            m_IdleTimer = new Stopwatch();

            m_PluginRepository = pluginRepository;
        }
        /// <summary>
        /// Processes the graph using the graph processor returned by <see cref="Stencil.CreateGraphProcessor"/>.
        /// </summary>
        /// <param name="graphModel">The graph to process.</param>
        /// <param name="pluginRepository">The plugin repository.</param>
        /// <param name="options">Graph processing options.</param>
        /// <param name="tracingEnabled">True if tracing is enabled.</param>
        /// <returns>The result of a graph processing.</returns>
        public static GraphProcessingResult ProcessGraph(this IGraphModel graphModel, PluginRepository pluginRepository, RequestGraphProcessingOptions options, bool tracingEnabled)
        {
            var stencil = (Stencil)graphModel?.Stencil;

            if (stencil == null)
            {
                return(null);
            }

            if (pluginRepository != null)
            {
                var graphProcessingOptions = GetGraphProcessingOptions(tracingEnabled);
                var plugins = stencil.GetGraphProcessingPluginHandlers(graphProcessingOptions);
                pluginRepository.RegisterPlugins(plugins);
            }

            var graphProcessor = stencil.CreateGraphProcessor();

            if (options == RequestGraphProcessingOptions.SaveGraph)
            {
                AssetDatabase.SaveAssets();
            }

            return(graphProcessor.ProcessGraph(graphModel));
        }
예제 #4
0
        protected virtual void OnEnable()
        {
            // When we open a window (including when we start the Editor), a new GUID is assigned.
            // When a window is opened and there is a domain reload, the GUID stays the same.
            if (m_GUID == default)
            {
                m_GUID = SerializableGUID.Generate();
            }

            var initialState = CreateInitialState();

            CommandDispatcher = new CommandDispatcher(initialState);

            PluginRepository = new PluginRepository(this);

            rootVisualElement.Clear();
            rootVisualElement.pickingMode = PickingMode.Ignore;

            m_GraphContainer = new VisualElement {
                name = "graphContainer"
            };
            m_GraphView    = CreateGraphView();
            m_MainToolbar  = CreateMainToolbar();
            m_ErrorToolbar = CreateErrorToolbar();
            m_BlankPage    = CreateBlankPage();
            m_BlankPage?.CreateUI();

            if (m_MainToolbar != null)
            {
                rootVisualElement.Add(m_MainToolbar);
            }
            // AddTracingTimeline();
            rootVisualElement.Add(m_GraphContainer);
            if (m_ErrorToolbar != null)
            {
                m_GraphView.Add(m_ErrorToolbar);
            }

            m_GraphContainer.Add(m_GraphView);

            rootVisualElement.name = "gtfRoot";
            rootVisualElement.AddStylesheet("GraphViewWindow.uss");

            // PF FIXME: Use EditorApplication.playModeStateChanged / AssemblyReloadEvents ? Make sure it works on all domain reloads.

            // After a domain reload, all loaded objects will get reloaded and their OnEnable() called again
            // It looks like all loaded objects are put in a deserialization/OnEnable() queue
            // the previous graph's nodes/edges/... might be queued AFTER this window's OnEnable
            // so relying on objects to be loaded/initialized is not safe
            // hence, we need to defer the loading command
            rootVisualElement.schedule.Execute(() =>
            {
                var lastGraphFilePath = CommandDispatcher.State.WindowState.LastOpenedGraph.GetGraphAssetModelPath();
                var lastGraphId       = CommandDispatcher.State.WindowState.LastOpenedGraph.AssetLocalId;
                if (!string.IsNullOrEmpty(lastGraphFilePath))
                {
                    try
                    {
                        CommandDispatcher.Dispatch(new LoadGraphAssetCommand(
                                                       lastGraphFilePath,
                                                       lastGraphId,
                                                       PluginRepository,
                                                       CommandDispatcher.State.WindowState.LastOpenedGraph.BoundObject,
                                                       LoadGraphAssetCommand.LoadStrategies.KeepHistory));
                    }
                    catch (Exception e)
                    {
                        Debug.LogError(e);
                    }
                }
            }).ExecuteLater(0);

            m_GraphProcessingPendingLabel = new Label("Graph Processing Pending")
            {
                name = "graph-processing-pending-label"
            };

            if (WithSidePanel)
            {
                m_SidePanel = CreateModelInspectorView();
            }

            if (m_SidePanel != null)
            {
                m_GraphContainer.Add(m_SidePanel);
            }

            rootVisualElement.RegisterCallback <AttachToPanelEvent>(OnEnterPanel);
            rootVisualElement.RegisterCallback <DetachFromPanelEvent>(OnLeavePanel);
            // that will be true when the window is restored during the editor startup, so OnEnterPanel won't be called later
            if (rootVisualElement.panel != null)
            {
                OnEnterPanel(null);
            }

            titleContent = new GUIContent("Graph Tool");

            m_LockTracker.lockStateChanged.AddListener(OnLockStateChanged);

            m_AutomaticGraphProcessor = new AutomaticGraphProcessor(PluginRepository);
            CommandDispatcher.RegisterObserver(m_AutomaticGraphProcessor);
            rootVisualElement.RegisterCallback <MouseMoveEvent>(ResetGraphProcessorTimer);

            m_GraphProcessingStatusObserver = new GraphProcessingStatusObserver(m_GraphProcessingPendingLabel, m_ErrorToolbar);
            CommandDispatcher.RegisterObserver(m_GraphProcessingStatusObserver);

            m_SidePanelObserver = new SidePanelObserver(this);
            CommandDispatcher.RegisterObserver(m_SidePanelObserver);
        }