public void ClearSelectionWorks() { var node1 = new NodeModel(); var node2 = new NodeModel(); var viewGuid1 = SerializableGUID.Generate(); var state = new GraphToolState(viewGuid1, null); using (var selectionUpdater = state.SelectionState.UpdateScope) { selectionUpdater.ClearSelection(state.WindowState.GraphModel); selectionUpdater.SelectElements(new[] { node1, node2 }, true); } Assert.IsTrue(state.SelectionState.IsSelected(node1)); Assert.IsTrue(state.SelectionState.IsSelected(node2)); using (var selectionUpdater = state.SelectionState.UpdateScope) { selectionUpdater.ClearSelection(state.WindowState.GraphModel); } Assert.IsFalse(state.SelectionState.IsSelected(node1)); Assert.IsFalse(state.SelectionState.IsSelected(node2)); }
/// <summary> /// Initializes a new GraphNodeCreationData. /// </summary> /// <param name="graphModel">The interface to the graph where we want the node to be created in.</param> /// <param name="position">The position at which the node should be created.</param> /// <param name="spawnFlags">The flags specifying how the node is to be spawned.</param> /// <param name="guid">The SerializableGUID to assign to the newly created item.</param> public GraphNodeCreationData(IGraphModel graphModel, Vector2 position, SpawnFlags spawnFlags = SpawnFlags.Default, SerializableGUID guid = default) { GraphModel = graphModel; Position = position; SpawnFlags = spawnFlags; Guid = guid; }
static void SetupLogStickyCallback() { ConsoleWindowBridge.SetEntryDoubleClickedDelegate((file, entryInstanceId) => { // FIXME: will not work with files that contains multiple GraphAssetModel. var pathAndGuid = file.Split('@'); bool assetOpened = false; var asset = AssetDatabase.LoadAssetAtPath <GraphAssetModel>(pathAndGuid[0]); if (asset != null) { assetOpened = AssetDatabase.OpenAsset(asset); } if (assetOpened) { var guid = new SerializableGUID(pathAndGuid[1]); var window = focusedWindow as GraphViewEditorWindow; if (window != null && window.GraphView.GraphModel.TryGetModelFromGuid(guid, out var nodeModel)) { var graphElement = nodeModel.GetUI <GraphElement>(window.GraphView); if (graphElement != null) { window.GraphView.DispatchFrameAndSelectElementsCommand(true, graphElement); } } } }); }
protected override INodeModel InstantiateNode(Type nodeTypeToCreate, string nodeName, Vector2 position, SerializableGUID guid = default, Action <INodeModel> initializationCallback = null) { if (nodeTypeToCreate == null) { throw new ArgumentNullException(nameof(nodeTypeToCreate)); } BasicModel.NodeModel nodeModel; if (typeof(IConstant).IsAssignableFrom(nodeTypeToCreate)) { nodeModel = new ConstantNodeModel { Value = (IConstant)Activator.CreateInstance(nodeTypeToCreate) } } ; else if (typeof(BasicModel.NodeModel).IsAssignableFrom(nodeTypeToCreate)) { nodeModel = (BasicModel.NodeModel)Activator.CreateInstance(nodeTypeToCreate); } else { throw new ArgumentOutOfRangeException(nameof(nodeTypeToCreate)); } nodeModel.Position = position; nodeModel.Guid = guid.Valid ? guid : SerializableGUID.Generate(); nodeModel.Title = nodeName; (nodeModel as ITestNodeModel).SetGraphModel(this); initializationCallback?.Invoke(nodeModel); nodeModel.OnCreateNode(); return(nodeModel); }
/// <summary> /// Initializes a new CreateNodeFromSearcherCommand. /// </summary> /// <param name="position">The position where to create the node.</param> /// <param name="selectedItem">The searcher item representing the node to create.</param> /// <param name="guid">The SerializableGUID to assign to the newly created item. If none is provided, a new /// SerializableGUID will be generated for it.</param> public CreateNodeFromSearcherCommand(Vector2 position, GraphNodeModelSearcherItem selectedItem, SerializableGUID guid = default) : this() { Position = position; SelectedItem = selectedItem; Guid = guid.Valid ? guid : SerializableGUID.Generate(); }
/// <summary> /// Initializes a new CreateNodeFromSearcherCommand. /// </summary> /// <param name="edgeModel">The edge model on which to insert the newly created node.</param> /// <param name="position">The position where to create the node.</param> /// <param name="selectedItem">The searcher item representing the node to create.</param> /// <param name="guid">The SerializableGUID to assign to the newly created item. If none is provided, a new /// SerializableGUID will be generated for it.</param> public CreateNodeOnEdgeCommand(IEdgeModel edgeModel, Vector2 position, GraphNodeModelSearcherItem selectedItem, SerializableGUID guid = default) : this() { EdgeModel = edgeModel; Position = position; SelectedItem = selectedItem; Guid = guid.Valid ? guid : SerializableGUID.Generate(); }
/// <summary> /// Creates a new variable declaration in the graph. /// </summary> /// <param name="self">The graph to add a variable declaration to.</param> /// <param name="variableDataType">The type of data the new variable declaration to create represents.</param> /// <param name="variableName">The name of the new variable declaration to create.</param> /// <param name="modifierFlags">The modifier flags of the new variable declaration to create.</param> /// <param name="isExposed">Whether the variable is exposed externally or not.</param> /// <param name="initializationModel">The initialization model of the new variable declaration to create. Can be <code>null</code>.</param> /// <param name="guid">The SerializableGUID to assign to the newly created item.</param> /// <param name="initializationCallback">An initialization method to be called right after the variable declaration is created.</param> /// <param name="spawnFlags">The flags specifying how the variable declaration is to be spawned.</param> /// <typeparam name="TDeclType">The type of variable declaration to create.</typeparam> /// <returns>The newly created variable declaration.</returns> public static TDeclType CreateGraphVariableDeclaration <TDeclType>(this IGraphModel self, TypeHandle variableDataType, string variableName, ModifierFlags modifierFlags, bool isExposed, IConstant initializationModel = null, SerializableGUID guid = default, Action <TDeclType, IConstant> initializationCallback = null, SpawnFlags spawnFlags = SpawnFlags.Default) where TDeclType : class, IVariableDeclarationModel { return((TDeclType)self.CreateGraphVariableDeclaration(typeof(TDeclType), variableDataType, variableName, modifierFlags, isExposed, initializationModel, guid, (d, c) => initializationCallback?.Invoke((TDeclType)d, c), spawnFlags)); }
/// <summary> /// Initializes a new CreateGraphVariableDeclarationCommand. /// </summary> /// <remarks>This constructor will create the graph's default variable declaration.</remarks> /// <param name="name">The name of the variable to create.</param> /// <param name="isExposed">Whether or not the variable is exposed.</param> /// <param name="typeHandle">The type of data the new variable declaration to create represents.</param> /// <param name="modifierFlags">The modifiers to apply to the newly created variable.</param> /// <param name="guid">The SerializableGUID to assign to the newly created item. If none is provided, a new /// SerializableGUID will be generated for it.</param> public CreateGraphVariableDeclarationCommand(string name, bool isExposed, TypeHandle typeHandle, ModifierFlags modifierFlags = ModifierFlags.None, SerializableGUID guid = default) : this() { VariableName = name; IsExposed = isExposed; TypeHandle = typeHandle; Guid = guid.Valid ? guid : SerializableGUID.Generate(); ModifierFlags = modifierFlags; }
void FrameAndSelectElement(SerializableGUID errorModelGuid) { if (m_GraphView.GraphModel.TryGetModelFromGuid(errorModelGuid, out var errorModel)) { var ui = errorModel.GetUI <GraphElement>(m_GraphView); if (ui != null) { m_GraphView.DispatchFrameAndSelectElementsCommand(true, ui); } } }
/// <summary> /// Creates a new node in a graph. /// </summary> /// <param name="self">The graph to add a node to.</param> /// <param name="nodeName">The name of the node to create.</param> /// <param name="position">The position of the node to create.</param> /// <param name="guid">The SerializableGUID to assign to the newly created item.</param> /// <param name="initializationCallback">An initialization method to be called right after the node is created.</param> /// <param name="spawnFlags">The flags specifying how the node is to be spawned.</param> /// <typeparam name="TNodeType">The type of the new node to create.</typeparam> /// <returns>The newly created node.</returns> public static TNodeType CreateNode <TNodeType>(this IGraphModel self, string nodeName = "", Vector2 position = default, SerializableGUID guid = default, Action <TNodeType> initializationCallback = null, SpawnFlags spawnFlags = SpawnFlags.Default) where TNodeType : class, INodeModel { Action <INodeModel> setupWrapper = null; if (initializationCallback != null) { setupWrapper = n => initializationCallback.Invoke(n as TNodeType); } return((TNodeType)self.CreateNode(typeof(TNodeType), nodeName, position, guid, setupWrapper, spawnFlags)); }
public void EmptyChangeSetsDoNotDirtyAsset() { var viewGuid1 = SerializableGUID.Generate(); var state = new GraphToolState(viewGuid1, null); var initialDirtyCount = EditorUtility.GetDirtyCount(m_Asset1 as Object); using (var graphUpdater = state.GraphViewState.UpdateScope) { graphUpdater.MarkNew(Enumerable.Empty <IGraphElementModel>()); graphUpdater.MarkChanged(Enumerable.Empty <IGraphElementModel>()); graphUpdater.MarkDeleted(Enumerable.Empty <IGraphElementModel>()); } Assert.AreEqual(initialDirtyCount, EditorUtility.GetDirtyCount(m_Asset1 as Object)); }
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 root = rootVisualElement; this.SetAntiAliasing(4); m_Toolbar = new UIElements.Toolbar(); // Register panel choice refresh on the toolbar so the event // is received before the ToolbarPopup clickable handle it. m_Toolbar.RegisterCallback <MouseDownEvent>(e => { if (e.target == m_SelectorMenu) { RefreshPanelChoices(); } }, TrickleDown.TrickleDown); m_GraphViewChoices = new List <GraphViewChoice>(); m_SelectorMenu = new ToolbarMenu { name = "panelSelectPopup", text = "Select a panel" }; var menu = m_SelectorMenu.menu; menu.AppendAction("None", OnSelectGraphView, a => m_SelectedGraphView == null ? DropdownMenuAction.Status.Checked : DropdownMenuAction.Status.Normal); m_Toolbar.Add(m_SelectorMenu); m_Toolbar.style.flexGrow = 1; m_Toolbar.style.overflow = Overflow.Hidden; m_ToolbarContainer = new VisualElement(); m_ToolbarContainer.style.flexDirection = FlexDirection.Row; m_ToolbarContainer.Add(m_Toolbar); root.Add(m_ToolbarContainer); m_FirstUpdate = true; titleContent.text = ToolName; }
public void AllStateComponentsReturnsAllStateComponents() { var viewGuid1 = SerializableGUID.Generate(); var state = new GraphToolState(viewGuid1, null); var sc = new HashSet <IStateComponent>(state.AllStateComponents); var foundComponents = new HashSet <IStateComponent>(); foreach (var fieldInfo in typeof(GraphToolState) .GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) .Where(fi => typeof(IStateComponent).IsAssignableFrom(fi.FieldType)) ) { foundComponents.Add(fieldInfo.GetValue(state) as IStateComponent); Assert.IsTrue(sc.Contains(fieldInfo.GetValue(state) as IStateComponent), fieldInfo.Name + " is not included in AllStateComponents"); } Assert.AreEqual(sc, foundComponents); }
public void SettingAStateComponentAndGettingItWorks() { var persistedState = new PersistedState(); persistedState.SetAssetKey("42424242"); var viewGuid1 = SerializableGUID.Generate(); // View State Components { var firstState = persistedState.GetOrCreateViewStateComponent <WindowStateComponent>(viewGuid1, ""); var newStateComponent = new WindowStateComponent(); persistedState.SetViewStateComponent(viewGuid1, newStateComponent); var secondState = persistedState.GetOrCreateViewStateComponent <WindowStateComponent>(viewGuid1, ""); Assert.IsNotNull(firstState); Assert.IsNotNull(secondState); Assert.AreSame(newStateComponent, secondState); } // Asset State Components { var firstState = persistedState.GetOrCreateAssetStateComponent <BlackboardViewStateComponent>(""); var newStateComponent = new BlackboardViewStateComponent(); persistedState.SetAssetStateComponent(newStateComponent); var secondState = persistedState.GetOrCreateAssetStateComponent <BlackboardViewStateComponent>(""); Assert.IsNotNull(firstState); Assert.IsNotNull(secondState); Assert.AreSame(newStateComponent, secondState); } // Asset View State Components { var firstState = persistedState.GetOrCreateAssetViewStateComponent <SelectionStateComponent>(viewGuid1, ""); var newStateComponent = new SelectionStateComponent(); persistedState.SetAssetViewStateComponent(viewGuid1, newStateComponent); var secondState = persistedState.GetOrCreateAssetViewStateComponent <SelectionStateComponent>(viewGuid1, ""); Assert.IsNotNull(firstState); Assert.IsNotNull(secondState); Assert.AreSame(newStateComponent, secondState); } PersistedState.RemoveViewState(viewGuid1); }
public void SelectionStateIsTiedToAssetAndView() { var node = new NodeModel(); var viewGuid1 = SerializableGUID.Generate(); var state = new GraphToolState(viewGuid1, null); state.LoadGraphAsset(m_Asset1, null); Assert.IsNotNull(state.SelectionState); using (var selectionUpdater = state.SelectionState.UpdateScope) { selectionUpdater.SelectElements(new[] { node }, true); } Assert.IsTrue(state.SelectionState.IsSelected(node)); // Load another asset in the same view: node is not selected anymore. var state2 = new GraphToolState(viewGuid1, null); state2.LoadGraphAsset(m_Asset2, null); var selectionState2 = state2.SelectionState; Assert.IsNotNull(selectionState2); Assert.IsFalse(selectionState2.IsSelected(node)); // Load the same asset in the another view: node is not selected anymore. var viewGuid2 = SerializableGUID.Generate(); state2 = new GraphToolState(viewGuid2, null); state2.LoadGraphAsset(m_Asset1, null); selectionState2 = state2.SelectionState; Assert.IsNotNull(selectionState2); Assert.IsFalse(selectionState2.IsSelected(node)); // Reload the same asset in the original view: node is still selected. state2 = new GraphToolState(viewGuid1, null); state2.LoadGraphAsset(m_Asset1, null); selectionState2 = state2.SelectionState; Assert.IsNotNull(selectionState2); Assert.IsTrue(selectionState2.IsSelected(node)); }
public void Remove(SerializableGUID a, SerializableGUID b) { SerializableGUID parent; SerializableGUID child; if (m_DependenciesByNode.TryGetValue(a, out var link) && link.TryGetValue(b, out var dependency)) { parent = a; child = b; } else if (m_DependenciesByNode.TryGetValue(b, out link) && link.TryGetValue(a, out dependency)) { parent = b; child = a; } else { return; } if (dependency is LinkedNodesDependency linked) { linked.Count--; if (linked.Count <= 0) { link.Remove(child); } } else { link.Remove(child); } if (link.Count == 0) { m_DependenciesByNode.Remove(parent); } }
public void MarkChangedHasNoEffectIfModelIsNew() { var viewGuid1 = SerializableGUID.Generate(); var state = new GraphToolState(viewGuid1, null); var dummyModel = new TestNodeModel(); using (var graphUpdater = state.GraphViewState.UpdateScope) { graphUpdater.MarkNew(dummyModel); } var changes = state.GraphViewState.GetAggregatedChangeset(0); Assert.IsTrue(changes.NewModels.Contains(dummyModel)); using (var graphUpdater = state.GraphViewState.UpdateScope) { graphUpdater.MarkChanged(dummyModel); } changes = state.GraphViewState.GetAggregatedChangeset(0); Assert.IsFalse(changes.ChangedModels.Contains(dummyModel)); }
public void MarkDeletedRemovesModelFromTheChangedList() { var viewGuid1 = SerializableGUID.Generate(); var state = new GraphToolState(viewGuid1, null); var dummyModel = new TestNodeModel(); using (var graphUpdater = state.GraphViewState.UpdateScope) { graphUpdater.MarkChanged(dummyModel); } var changes = state.GraphViewState.GetAggregatedChangeset(0); Assert.IsTrue(changes.ChangedModels.Contains(dummyModel)); using (var graphUpdater = state.GraphViewState.UpdateScope) { graphUpdater.MarkDeleted(dummyModel); } changes = state.GraphViewState.GetAggregatedChangeset(0); Assert.IsFalse(changes.ChangedModels.Contains(dummyModel)); Assert.IsTrue(changes.DeletedModels.Contains(dummyModel)); }
protected override IEdgeModel InstantiateEdge(IPortModel toPort, IPortModel fromPort, SerializableGUID guid = default) { var edgeModel = base.InstantiateEdge(toPort, fromPort, guid); if (edgeModel is EdgeModel testEdgeModel) { testEdgeModel.SetGraphModel(this); } return(edgeModel); }
public override IVariableNodeModel CreateVariableNode(IVariableDeclarationModel declarationModel, Vector2 position, SerializableGUID guid = default, SpawnFlags spawnFlags = SpawnFlags.Default) { return(this.CreateNode <VariableNodeModel>(declarationModel.DisplayTitle, position, guid, v => v.DeclarationModel = declarationModel, spawnFlags)); }
/// <summary> /// Converts a <see cref="SerializableGUID"/> to a <see cref="GUID"/>. /// </summary> /// <param name="guid">The SerializableGUID to convert.</param> /// <returns>The resulting GUID.</returns> public static unsafe GUID ToGUID(this SerializableGUID guid) { return(*(GUID *)&guid); }
public GraphToolState(SerializableGUID graphViewEditorWindowGUID, IGraphModel graphModel) : base(graphViewEditorWindowGUID, CreatePreferences()) { m_GraphModel = graphModel; }
public TestGraphToolState(SerializableGUID graphViewEditorWindowGUID, Preferences preferences) : base(graphViewEditorWindowGUID, preferences) { }
static string UnexpectedValueMessage(string fieldName, SerializableGUID guid) { return(UnexpectedValueMessage(fieldName, NiceGuid(guid))); }
static string NiceGuid(SerializableGUID guid) { var(a, b) = guid.ToParts(); return($"GUID {{m_Value0: {a} m_Value1: {b}}}"); }
protected override IVariableDeclarationModel InstantiateVariableDeclaration(Type variableTypeToCreate, TypeHandle variableDataType, string variableName, ModifierFlags modifierFlags, bool isExposed, IConstant initializationModel, SerializableGUID guid, Action <IVariableDeclarationModel, IConstant> initializationCallback = null) { var vdm = base.InstantiateVariableDeclaration(variableTypeToCreate, variableDataType, variableName, modifierFlags, isExposed, initializationModel, guid, initializationCallback); if (vdm is VariableDeclarationModel testVdm) { testVdm.SetGraphModel(this); } return(vdm); }
/// <summary> /// Initializes a new CreateGraphVariableDeclarationCommand. /// </summary> /// <param name="name">The name of the variable to create.</param> /// <param name="isExposed">Whether or not the variable is exposed.</param> /// <param name="typeHandle">The type of data the new variable declaration to create represents.</param> /// <param name="variableType">The type of variable declaration to create.</param> /// <param name="modifierFlags">The modifiers to apply to the newly created variable.</param> /// <param name="guid">The SerializableGUID to assign to the newly created item. If none is provided, a new /// SerializableGUID will be generated for it.</param> public CreateGraphVariableDeclarationCommand(string name, bool isExposed, TypeHandle typeHandle, Type variableType, ModifierFlags modifierFlags = ModifierFlags.None, SerializableGUID guid = default) : this(name, isExposed, typeHandle, modifierFlags, guid) { VariableType = variableType; }
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); }