Example #1
0
        public static void CreateGraphAsset <TStencilType>(string graphAssetName = k_DefaultGraphAssetName, IGraphTemplate template = null)
            where TStencilType : Stencil
        {
            string uniqueFilePath = VseUtility.GetUniqueAssetPathNameInActiveFolder(graphAssetName);
            string modelName      = Path.GetFileName(uniqueFilePath);

            var endAction = CreateInstance <DoCreateVisualScriptAsset>();

            endAction.Template    = template;
            endAction.StencilType = typeof(TStencilType);
            ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, endAction, modelName, GetIcon(), null);
        }
Example #2
0
        public void DisplayCompilationErrors(State state)
        {
            VseUtility.RemoveLogEntries();
            if (ModelsToNodeMapping == null)
            {
                UpdateTopology();
            }

            var lastCompilationResult = state.CompilationResultModel.GetLastResult();

            if (lastCompilationResult?.errors == null)
            {
                return;
            }

            var graphAsset = (GraphAssetModel)m_Store.GetState().CurrentGraphModel?.AssetModel;

            foreach (var error in lastCompilationResult.errors)
            {
                if (error.sourceNode != null && !error.sourceNode.Destroyed)
                {
                    var alignment = error.sourceNode is IStackModel
                        ? SpriteAlignment.TopCenter
                        : SpriteAlignment.RightCenter;

                    ModelsToNodeMapping.TryGetValue(error.sourceNode, out var graphElement);
                    if (graphElement != null)
                    {
                        AttachErrorBadge(graphElement, error.description, alignment, m_Store, error.quickFix);
                    }
                }

                if (graphAsset)
                {
                    var graphAssetPath = graphAsset ? AssetDatabase.GetAssetPath(graphAsset) : "<unknown>";
                    VseUtility.LogSticky(error.isWarning ? LogType.Warning : LogType.Error, LogOption.None,
                                         $"{graphAssetPath}: {error.description}", $"{graphAssetPath}@{error.sourceNodeGuid}",
                                         graphAsset.GetInstanceID());
                }
            }
        }
Example #3
0
        protected virtual void OnEnable()
        {
            if (m_PreviousGraphModels == null)
            {
                m_PreviousGraphModels = new List <OpenedGraph>();
            }

            if (m_BlackboardExpandedRowStates == null)
            {
                m_BlackboardExpandedRowStates = new List <string>();
            }

            if (m_ElementModelsToSelectUponCreation == null)
            {
                m_ElementModelsToSelectUponCreation = new List <string>();
            }

            if (m_ElementModelsToExpandUponCreation == null)
            {
                m_ElementModelsToExpandUponCreation = new List <string>();
            }

            rootVisualElement.RegisterCallback <ValidateCommandEvent>(OnValidateCommand);
            rootVisualElement.RegisterCallback <ExecuteCommandEvent>(OnExecuteCommand);
            rootVisualElement.RegisterCallback <MouseMoveEvent>(_ => _compilationTimer.Restart(m_Store.GetState().EditorDataModel));

            rootVisualElement.styleSheets.Add(AssetDatabase.LoadAssetAtPath <StyleSheet>(k_StyleSheetPath + "VSEditor.uss"));

            rootVisualElement.Clear();
            rootVisualElement.style.overflow      = Overflow.Hidden;
            rootVisualElement.pickingMode         = PickingMode.Ignore;
            rootVisualElement.style.flexDirection = FlexDirection.Column;
            rootVisualElement.name = "vseRoot";

            // Create the store.
            DataModel = CreateDataModel();
            State initialState = CreateInitialState();

            m_Store = new Store(initialState, Store.Options.TrackUndoRedo);

            VseUtility.SetupLogStickyCallback();

            m_GraphContainer = new VisualElement {
                name = "graphContainer"
            };
            m_GraphView    = CreateGraphView();
            m_Menu         = CreateMenu();
            m_ErrorToolbar = CreateErrorToolbar();
            m_BlankPage    = CreateBlankPage();

            SetupWindow();

            m_CompilationPendingLabel = new Label("Compilation Pending")
            {
                name = "compilationPendingLabel"
            };

            m_SidePanel = new VisualElement()
            {
                name = "sidePanel"
            };
            m_SidePanelTitle = new Label();
            m_SidePanel.Add(m_SidePanelTitle);
            m_SidePanelPropertyElement = new Unity.Properties.UI.PropertyElement {
                name = "sidePanelInspector"
            };
            m_SidePanelPropertyElement.OnChanged += (element, path) =>
            {
                if (m_ElementShownInSidePanel is IHasGraphElementModel hasGraphElementModel && hasGraphElementModel.GraphElementModel is IPropertyVisitorNodeTarget nodeTarget2)
                {
                    nodeTarget2.Target = element.GetTarget <object>();
                }
                (m_ElementShownInSidePanel as Node)?.NodeModel.DefineNode();
                (m_ElementShownInSidePanel as Node)?.UpdateFromModel();
            };
            m_SidePanel.Add(m_SidePanelPropertyElement);
            ShowNodeInSidePanel(null, false);

            m_GraphContainer.Add(m_GraphView);
            m_GraphContainer.Add(m_SidePanel);

            Dictionary <Event, ShortcutDelegate> dictionaryShortcuts = GetShortcutDictionary();

            m_ShortcutHandler = new ShortcutHandler(GetShortcutDictionary());

            rootVisualElement.parent.AddManipulator(m_ShortcutHandler);

            m_Store.StateChanged   += StoreOnStateChanged;
            Undo.undoRedoPerformed += UndoRedoPerformed;

            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("Visual Script");

            // 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 action
            rootVisualElement.schedule.Execute(() =>
            {
                if (!String.IsNullOrEmpty(LastGraphFilePath))
                {
                    try
                    {
                        m_Store.Dispatch(new LoadGraphAssetAction(LastGraphFilePath, boundObject: m_BoundObject, loadType: LoadGraphAssetAction.Type.KeepHistory));
                    }
                    catch (Exception e)
                    {
                        Debug.LogError(e);
                    }
                }
                else             // will display the blank page. not needed otherwise as the LoadGraphAsset reducer will refresh
                {
                    m_Store.Dispatch(new RefreshUIAction(UpdateFlags.All));
                }
            }).ExecuteLater(0);


            m_LockTracker.lockStateChanged.AddListener(OnLockStateChanged);

            m_PluginRepository = new PluginRepository(m_Store, this);

            EditorApplication.playModeStateChanged += OnEditorPlayModeStateChanged;
            EditorApplication.pauseStateChanged    += OnEditorPauseStateChanged;

            if (DataModel is VSEditorDataModel vsDataModel)
            {
                vsDataModel.PluginRepository     = m_PluginRepository;
                vsDataModel.OnCompilationRequest = OnCompilationRequest;
            }
        }
Example #4
0
        void OnOptionsButton()
        {
            GenericMenu   menu         = new GenericMenu();
            VSGraphModel  vsGraphModel = (VSGraphModel)m_Store.GetState().CurrentGraphModel;
            VSPreferences pref         = m_Store.GetState().Preferences;

            void MenuItem(string title, bool value, GenericMenu.MenuFunction onToggle)
            => menu.AddItem(VseUtility.CreatTextContent(title), value, onToggle);

            void MenuToggle(string title, BoolPref k, Action callback = null)
            => MenuItem(title, pref.GetBool(k), () =>
            {
                pref.ToggleBool(k);
                callback?.Invoke();
            });

            void MenuMapToggle(string title, Func <bool> match, GenericMenu.MenuFunction onToggle)
            => MenuItem(title, match(), onToggle);

            void MenuItemDisable(string title, bool value, GenericMenu.MenuFunction onToggle, Func <bool> shouldDisable)
            {
                if (shouldDisable())
                {
                    menu.AddDisabledItem(VseUtility.CreatTextContent(title));
                }
                else
                {
                    menu.AddItem(VseUtility.CreatTextContent(title), value, onToggle);
                }
            }

            MenuItem("Build All", false, () => m_Store.Dispatch(new BuildAllEditorAction()));
            MenuItemDisable("Compile", false, () =>
            {
                m_Store.GetState().EditorDataModel.RequestCompilation(RequestCompilationOptions.SaveGraph);
            }, () => (vsGraphModel == null || !vsGraphModel.Stencil.CreateTranslator().SupportsCompilation()));

            MenuItem("Auto-itemize/Variables", pref.CurrentItemizeOptions.HasFlag(ItemizeOptions.Variables), () =>
                     pref.ToggleItemizeOption(ItemizeOptions.Variables));
            MenuItem("Auto-itemize/System Constants", pref.CurrentItemizeOptions.HasFlag(ItemizeOptions.SystemConstants), () =>
                     pref.ToggleItemizeOption(ItemizeOptions.SystemConstants));
            MenuItem("Auto-itemize/Constants", pref.CurrentItemizeOptions.HasFlag(ItemizeOptions.Constants), () =>
                     pref.ToggleItemizeOption(ItemizeOptions.Constants));
            MenuToggle("Show unused nodes", BoolPref.ShowUnusedNodes, () => m_Store.Dispatch(new RefreshUIAction(UpdateFlags.All)));
            if (Unsupported.IsDeveloperMode())
            {
                MenuItem("Log compile time stats", LogCompileTimeStats, () => LogCompileTimeStats = !LogCompileTimeStats);

                menu.AddSeparator("");

                MenuItem("Reload Graph", false, () =>
                {
                    if (m_Store.GetState()?.CurrentGraphModel != null)
                    {
                        var path = m_Store.GetState().CurrentGraphModel.GetAssetPath();
                        Selection.activeObject = null;
                        Resources.UnloadAsset((Object)m_Store.GetState().CurrentGraphModel.AssetModel);
                        m_Store.Dispatch(new LoadGraphAssetAction(path));
                    }
                });

                MenuItem("Rebuild UI", false, () =>
                {
                    m_Store.Dispatch(new RefreshUIAction(UpdateFlags.All));
                });
                MenuItem("Rebuild Blackboard", false, () =>
                {
                    m_GraphView.UIController.Blackboard?.Rebuild(Blackboard.RebuildMode.BlackboardOnly);
                });

                menu.AddSeparator("");

                MenuItem("Clear Searcher Databases", false, () =>
                {
                    var provider = m_Store.GetState().CurrentGraphModel.Stencil.GetSearcherDatabaseProvider();
                    provider.ClearTypesItemsSearcherDatabases();
                    provider.ClearTypeMembersSearcherDatabases();
                    provider.ClearGraphElementsSearcherDatabases();
                    provider.ClearGraphVariablesSearcherDatabases();
                });
                MenuItem("Integrity Check", false, () => vsGraphModel.CheckIntegrity(GraphModel.Verbosity.Verbose));
                MenuItem("Graph cleanup", false, () =>
                {
                    vsGraphModel.QuickCleanup();
                    vsGraphModel.CheckIntegrity(GraphModel.Verbosity.Verbose);
                });
                MenuItem("Fix and reimport all textures", false, OnFixAndReimportTextures);

                MenuToggle("Auto compilation when idle", BoolPref.AutoRecompile);
                MenuToggle("Auto align new dragged edges", BoolPref.AutoAlignDraggedEdges);
                if (Unsupported.IsDeveloperMode())
                {
                    MenuToggle("Bound object logging", BoolPref.BoundObjectLogging);
                    MenuToggle("Dependencies logging", BoolPref.DependenciesLogging);
                    MenuToggle("UI Performance/Always fully rebuild UI on change", BoolPref.FullUIRebuildOnChange);
                    MenuToggle("UI Performance/Warn when UI gets fully rebuilt", BoolPref.WarnOnUIFullRebuild);
                    MenuToggle("UI Performance/Log UI build time", BoolPref.LogUIBuildTime);
                    if (DebugDisplayElement.Allowed)
                    {
                        MenuItem("Show Debug", m_GraphView.ShowDebug, () => m_GraphView.ShowDebug = !m_GraphView.ShowDebug);
                    }
                    MenuToggle("Diagnostics/Log Recursive Action Dispatch", BoolPref.ErrorOnRecursiveDispatch);
                    MenuToggle("Diagnostics/Log Multiple Actions Dispatch", BoolPref.ErrorOnMultipleDispatchesPerFrame);
                    MenuToggle("Diagnostics/Log All Dispatched Actions", BoolPref.LogAllDispatchedActions);
                    MenuItem("Spawn all node types in graph", false, () =>
                    {
                        VSGraphModel graph   = (VSGraphModel)m_Store.GetState().CurrentGraphModel;
                        Stencil stencil      = graph.Stencil;
                        Vector2 nextPosition = Vector2.zero;
                        Vector2 spaceBetween = new Vector2(300, 0);
                        foreach (var node in stencil.SpawnAllNodes(graph))
                        {
                            node.Position += nextPosition;
                            nextPosition  += spaceBetween;
                        }
                    });
                }

                foreach (IPluginHandler pluginType in m_Store.GetState().EditorDataModel.PluginRepository.RegisteredPlugins)
                {
                    pluginType.OptionsMenu(menu);
                }

                var compilationResult = m_Store.GetState()?.CompilationResultModel?.GetLastResult();
            }

            menu.ShowAsContext();
        }