IConstantNodeModel CreateConstantIntNode(int value) { IConstantNodeModel constNode = GraphModel.CreateConstantNode("int", typeof(int).GenerateTypeHandle(GraphModel.Stencil), Vector2.zero); ((IntConstantModel)constNode).value = value; return(constNode); }
public static Port CreateInputPort(Store store, IPortModel inputPortModel, VisualElement instanceContainer, VisualElement dataContainer, VisualElement existingIcon = null, Orientation orientation = Orientation.Horizontal) { Assert.IsTrue(inputPortModel.Direction == Direction.Input, "Expected input port model"); var port = Create(inputPortModel, store, orientation, existingIcon); if (inputPortModel.PortType == PortType.Instance) { port.AddToClassList("instance"); instanceContainer.Insert(0, port); } else { VisualElement innerContainer = new VisualElement { name = "innerContainer" }; innerContainer.style.flexDirection = FlexDirection.Row; innerContainer.Add(port); dataContainer.Add(innerContainer); IConstantNodeModel modelToShow = port.GetModelToWatch(); if (modelToShow != null) { VisualElement editor = port.CreateEditorForNodeModel(modelToShow, _ => store.Dispatch(new RefreshUIAction(UpdateFlags.RequestCompilation))); if (editor != null) { innerContainer.Add(editor); port.m_InputEditor = editor; } } } return(port); }
IConstantNodeModel CreateConstantBoolNode(bool value) { IConstantNodeModel constNode = GraphModel.CreateConstantNode("bool", typeof(bool).GenerateTypeHandle(GraphModel.Stencil), Vector2.zero); ((BooleanConstantNodeModel)constNode).value = value; return(constNode); }
public void Test_EditPropertyGroupNodeAction_AddRemove([Values] TestingMode mode) { IConstantNodeModel constant = GraphModel.CreateConstantNode("toto", typeof(Vector3).GenerateTypeHandle(Stencil), Vector2.zero); GetPropertyGroupNodeModel property = GraphModel.CreateGetPropertyGroupNode(Vector2.zero); GraphModel.CreateEdge(property.InstancePort, constant.OutputPort); Type type = typeof(GameObject); MemberInfo memberInfo = type.GetMembers()[0]; var newMember = new TypeMember { Path = new List <string> { memberInfo.Name }, Type = memberInfo.GetUnderlyingType().GenerateTypeHandle(Stencil) }; TestPrereqActionPostreq(mode, () => { Assert.That(GetNodeCount(), Is.EqualTo(2)); Assert.That(GetEdgeCount(), Is.EqualTo(1)); Assert.That(property.GetPortsForMembers().Count(), Is.EqualTo(0)); Assert.That(property.OutputsByDisplayOrder.Count(), Is.EqualTo(0)); return(new EditPropertyGroupNodeAction( EditPropertyGroupNodeAction.EditType.Add, property, newMember)); }, () => { Assert.That(GetNodeCount(), Is.EqualTo(2)); Assert.That(GetEdgeCount(), Is.EqualTo(1)); Assert.That(property.GetPortsForMembers().Count(), Is.EqualTo(1)); Assert.That(property.OutputsByDisplayOrder.Count(), Is.EqualTo(1)); }); TestPrereqActionPostreq(mode, () => { Assert.That(GetNodeCount(), Is.EqualTo(2)); Assert.That(GetEdgeCount(), Is.EqualTo(1)); Assert.That(property.GetPortsForMembers().Count(), Is.EqualTo(1)); Assert.That(property.OutputsByDisplayOrder.Count(), Is.EqualTo(1)); return(new EditPropertyGroupNodeAction( EditPropertyGroupNodeAction.EditType.Remove, property, newMember)); }, () => { Assert.That(GetNodeCount(), Is.EqualTo(2)); Assert.That(GetEdgeCount(), Is.EqualTo(1)); Assert.That(property.GetPortsForMembers().Count(), Is.EqualTo(0)); Assert.That(property.OutputsByDisplayOrder.Count(), Is.EqualTo(0)); }); }
public override void SetUp() { base.SetUp(); m_NodeModel = GraphModel.CreateNode <TestNodeModel>("OtherNode", k_NodePos); m_TokenModel = GraphModel.CreateConstantNode(TypeHandle.Float, "Constant", k_TokenPos); MarkGraphViewStateDirty(); helpers = new TestEventHelpers(Window); }
void OnAttachToPanel(AttachToPanelEvent e) { IConstantNodeModel watchedModel = GetModelToWatch(); if (watchedModel != null && m_InputEditor != null) { m_InputEditor.Bind(new SerializedObject(watchedModel.NodeAssetReference)); (m_InputEditor as PropertyField)?.RemovePropertyFieldValueLabel(); m_InputEditor.SetEnabled(!Model.Connected || Model.ConnectionPortModels.All(p => p.NodeModel.State == ModelState.Disabled)); } }
public void DeleteNodeDoesRemoveTheDependency() { var mgr = new PositionDependenciesManager(GraphView, GraphView.window.Preferences); BinaryOperatorNodeModel operatorModel = GraphModel.CreateBinaryOperatorNode(BinaryOperatorKind.Add, new Vector2(-100, -100)); IConstantNodeModel intModel = GraphModel.CreateConstantNode("int", typeof(int).GenerateTypeHandle(GraphModel.Stencil), new Vector2(-150, -100)); var edge = GraphModel.CreateEdge(operatorModel.InputPortA, intModel.OutputPort); mgr.AddPositionDependency(edge); mgr.Remove(operatorModel.Guid, intModel.Guid); Assert.That(mgr.GetDependencies(operatorModel), Is.Null); }
public IEnumerator MovingAFloatingNodeMovesConnectedToken([Values] TestingMode mode) { var operatorModel = GraphModel.CreateNode <Type0FakeNodeModel>("Node0", new Vector2(-100, -100)); IConstantNodeModel intModel = GraphModel.CreateConstantNode(typeof(int).GenerateTypeHandle(), "int", new Vector2(-150, -100)); GraphModel.CreateEdge(operatorModel.Input0, intModel.OutputPort); yield return(TestMove(mode, mouseDelta: new Vector2(20, 10), movedNodes: new INodeModel[] { operatorModel }, expectedMovedDependencies: new INodeModel[] { intModel } )); }
public IEnumerator MovingAFloatingNodeMovesConnectedToken([Values] TestingMode mode) { BinaryOperatorNodeModel operatorModel = GraphModel.CreateBinaryOperatorNode(BinaryOperatorKind.Add, new Vector2(-100, -100)); IConstantNodeModel intModel = GraphModel.CreateConstantNode("int", typeof(int).GenerateTypeHandle(GraphModel.Stencil), new Vector2(-150, -100)); GraphModel.CreateEdge(operatorModel.InputPortA, intModel.OutputPort); yield return(TestMove(mode, mouseDelta: new Vector2(20, 10), movedNodes: new INodeModel[] { operatorModel }, expectedMovedDependencies: new INodeModel[] { intModel } )); }
public IEnumerator MovingAStackMovesStackedNodeConnectedFloatingNode([Values] TestingMode mode) { var stackModel0 = GraphModel.CreateStack(string.Empty, new Vector2(-100, -100)); UnaryOperatorNodeModel unary = stackModel0.CreateStackedNode <UnaryOperatorNodeModel>("postDecr", setup: n => n.kind = UnaryOperatorKind.PostDecrement); BinaryOperatorNodeModel operatorModel = GraphModel.CreateBinaryOperatorNode(BinaryOperatorKind.Add, new Vector2(-100, -100)); IConstantNodeModel intModel = GraphModel.CreateConstantNode("int", typeof(int).GenerateTypeHandle(GraphModel.Stencil), new Vector2(-150, -100)); GraphModel.CreateEdge(unary.InputPort, operatorModel.OutputPort); GraphModel.CreateEdge(operatorModel.InputPortA, intModel.OutputPort); yield return(TestMove(mode, mouseDelta: new Vector2(20, 10), movedNodes: new INodeModel[] { stackModel0 }, expectedMovedDependencies: new INodeModel[] { operatorModel, intModel } )); }
static State CreateLogNode(State previousState, CreateLogNodeAction action) { VSGraphModel graphModel = (VSGraphModel)previousState.CurrentGraphModel; var stackModel = (StackBaseModel)action.StackModel; var functionNode = stackModel.CreateStackedNode <LogNodeModel>(LogNodeModel.NodeTitle); functionNode.LogType = action.LogType; IConstantNodeModel constantNode = graphModel.CreateConstantNode( "", typeof(string).GenerateTypeHandle(graphModel.Stencil), functionNode.Position - k_StackedTestNodesTokenOffset); ((ConstantNodeModel <string>)constantNode).value = $"{graphModel.NodeModels.Count}"; graphModel.CreateEdge(functionNode.InputPort, constantNode.OutputPort); return(previousState); }
public void Test_DisconnectSetPropertyKeepsPortType([Values] TestingMode mode) { VariableDeclarationModel trDecl = GraphModel.CreateGraphVariableDeclaration("tr", typeof(Transform).GenerateTypeHandle(Stencil), true); IVariableModel trVar = GraphModel.CreateVariableNode(trDecl, Vector2.left); FunctionModel method = GraphModel.CreateFunction("TestFunction", Vector2.zero); SetPropertyGroupNodeModel setters = method.CreateSetPropertyGroupNode(0); GraphModel.CreateEdge(setters.InstancePort, trVar.OutputPort); setters.AddMember( new TypeMember { Path = new List <string> { "position" }, Type = Stencil.GenerateTypeHandle(typeof(Vector3)) } ); IConstantNodeModel constToken = GraphModel.CreateConstantNode("v3", typeof(Vector3).GenerateTypeHandle(Stencil), Vector2.left * 200); IEdgeModel edge = GraphModel.CreateEdge(setters.GetPortsForMembers().First(), constToken.OutputPort); TestPrereqActionPostreq(mode, () => { Assert.That(GetNodeCount(), Is.EqualTo(3)); Assert.That(GetEdgeCount(), Is.EqualTo(2)); Assert.That(method.NodeModels.Count(), Is.EqualTo(1)); Assert.That(setters.GetPortsForMembers().First().DataType.Resolve(Stencil), Is.EqualTo(typeof(Vector3))); return(new DeleteElementsAction(edge)); }, () => { Assert.That(GetNodeCount(), Is.EqualTo(3)); Assert.That(GetEdgeCount(), Is.EqualTo(1)); Assert.That(method.NodeModels.Count(), Is.EqualTo(1)); Assert.That(GetStackedNode(0, 0), Is.TypeOf <SetPropertyGroupNodeModel>()); Assert.That(setters.GetPortsForMembers().First().DataType.Resolve(Stencil), Is.EqualTo(typeof(Vector3))); }); }
static State CreateLogNode(State previousState, CreateLogNodeAction action) { VSGraphModel graphModel = (VSGraphModel)previousState.CurrentGraphModel; var stackModel = (StackBaseModel)action.StackModel; var functionNode = stackModel.CreateStackedNode <LogNodeModel>(LogNodeModel.NodeTitle); functionNode.LogType = action.LogType; IConstantNodeModel constantNode = graphModel.CreateConstantNode( "", typeof(int).GenerateTypeHandle(graphModel.Stencil), stackModel.Position - k_StackedTestNodesTokenOffset); ((ConstantNodeModel <int>)constantNode).value = graphModel.NodeModels.Count; var edge = graphModel.CreateEdge(functionNode.InputPort, constantNode.OutputPort); graphModel.LastChanges.ModelsToAutoAlign.Add(edge); return(previousState); }
public IEnumerator LostEdgesAreDrawn() { var operatorModel = GraphModel.CreateNode <Type0FakeNodeModel>("Node0", new Vector2(-100, -100)); IConstantNodeModel intModel = GraphModel.CreateConstantNode(typeof(int).GenerateTypeHandle(), "int", new Vector2(-150, -100)); var edge = (EdgeModel)GraphModel.CreateEdge(operatorModel.Input0, intModel.OutputPort); // simulate a renamed port by changing the edge's port id var field = typeof(EdgeModel).GetField("m_ToPortReference", BindingFlags.Instance | BindingFlags.NonPublic); var inputPortReference = (PortReference)field.GetValue(edge); inputPortReference.UniqueId = "asd"; field.SetValue(edge, inputPortReference); edge.ResetPorts(); // get rid of cached port models MarkGraphViewStateDirty(); yield return(null); var lostPortsAdded = GraphView.Query(className: "ge-port--data-type-missing-port").Build().ToList().Count; Assert.AreEqual(1, lostPortsAdded); }
public void Test_EmbeddedConstantIsUsedWhenDisconnected([Values] TestingMode mode) { const float outerValue = 42f; const float innerValue = 347f; // make sure that we really test values that are not default Assume.That(outerValue, Is.Not.EqualTo(default(float))); Assume.That(innerValue, Is.Not.EqualTo(default(float))); var stencil = GraphModel.Stencil; FunctionModel a = GraphModel.CreateFunction("A", Vector2.zero); // Debug.Log(...) MethodInfo logMethod = typeof(Debug).GetMethod(nameof(Debug.Log), new[] { typeof(object) }); Assume.That(logMethod, Is.Not.Null); FunctionCallNodeModel log = a.CreateStackedNode <FunctionCallNodeModel>("Log", 0, SpawnFlags.Default, n => n.MethodInfo = logMethod); var logParameterPort = log.GetParameterPorts().Single(); // Math.Abs(...) MethodInfo absMethod = typeof(Mathf).GetMethod(nameof(Mathf.Abs), new[] { typeof(float) }); Assume.That(absMethod, Is.Not.Null); FunctionCallNodeModel abs = GraphModel.CreateNode <FunctionCallNodeModel>("Abs", Vector2.zero, SpawnFlags.Default, n => n.MethodInfo = absMethod); var absParameterPort = abs.GetParameterPorts().Single(); ((FloatConstantModel)abs.InputConstantsById[absParameterPort.UniqueId]).value = innerValue; GraphModel.CreateEdge(logParameterPort, abs.OutputPort); // float IConstantNodeModel outerFloat = GraphModel.CreateConstantNode("float42", typeof(float).GenerateTypeHandle(stencil), Vector2.zero); Assume.That(outerFloat, Is.Not.Null); ((FloatConstantModel)outerFloat).value = outerValue; string innerFloatString = SyntaxFactory.LiteralExpression( SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(innerValue)).ToFullString(); string outerFloatString = SyntaxFactory.LiteralExpression( SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(outerValue)).ToFullString(); TestPrereqActionPostreq(mode, () => { // outer float disconnected, check that we use the inner value SyntaxNode astRoot = CompileCurrentGraphModel(); LiteralExpressionSyntax literalInsideLogAbs = GetLiteralInsideLogAbs(astRoot); Assert.That(literalInsideLogAbs.ToFullString(), Is.EqualTo(innerFloatString)); return(new CreateEdgeAction(absParameterPort, outerFloat.OutputPort)); }, () => { // outer float connected, check that we use the outer value SyntaxNode astRoot = CompileCurrentGraphModel(); LiteralExpressionSyntax literalInsideLogAbs = GetLiteralInsideLogAbs(astRoot); Assert.That(literalInsideLogAbs.ToFullString(), Is.EqualTo(outerFloatString)); }); }
public static GraphElement CreateConstantToken(this INodeBuilder builder, Store store, IConstantNodeModel model) { GetTokenPorts(store, model, out var input, out var output); return(new Token(model, store, input, output, builder.GraphView)); }
public static VisualElement CreateEditorForNodeModel(this VisualElement element, IConstantNodeModel model, Action <IChangeEvent> onValueChanged) { VisualElement editorElement; var ext = ModelUtility.ExtensionMethodCache <IConstantEditorBuilder> .GetExtensionMethod(model.GetType(), ConstantEditorBuilder.FilterMethods, ConstantEditorBuilder.KeySelector); if (ext != null) { var constantBuilder = new ConstantEditorBuilder(onValueChanged); editorElement = (VisualElement)ext.Invoke(null, new object[] { constantBuilder, model }); } else if (model is ConstantNodeModel constantNodeModel && constantNodeModel.NodeAssetReference != null) { var serializedObject = new SerializedObject(constantNodeModel.NodeAssetReference); SerializedProperty serializedProperty = serializedObject.FindProperty("m_NodeModel.value"); var propertyField = new PropertyField(serializedProperty); editorElement = propertyField; editorElement.SetEnabled(!constantNodeModel.IsLocked); // delayed because the initial binding would cause an event otherwise, and then a compilation propertyField.schedule.Execute(() => { var onValueChangedEventCallback = new EventCallback <IChangeEvent>(onValueChanged); // HERE BE DRAGONS // there's no way atm to be notified that a PropertyField's value changed so we build a ChangeEvent<T> // callback registration using reflection, but actually provide an Action<IChangeEvent> Type type = constantNodeModel.Type; Type eventType = typeof(ChangeEvent <>).MakeGenericType(type); MethodInfo genericRegisterCallbackMethod = typeof(VisualElement).GetMethods().Single(m => { var parameterInfos = m.GetParameters(); return(m.Name == nameof(VisualElement.RegisterCallback) && parameterInfos.Length == 2 && parameterInfos[1].ParameterType == typeof(TrickleDown)); }); MethodInfo registerCallbackMethod = genericRegisterCallbackMethod.MakeGenericMethod(eventType); registerCallbackMethod.Invoke(propertyField, new object[] { onValueChangedEventCallback, TrickleDown.NoTrickleDown }); foreach (var floatField in propertyField.Query <FloatField>().ToList()) { floatField.isDelayed = true; floatField.RegisterValueChangedCallback(_ => { onValueChangedEventCallback.Invoke(null); floatField.UnregisterValueChangedCallback(onValueChangedEventCallback); }); } }).ExecuteLater(1); }
static void HandleConstants(GraphBuilder builder, out INode node, out PortMapper portToOffsetMapping, IConstantNodeModel constantNodeModel) { portToOffsetMapping = new PortMapper(); var outputPortId = constantNodeModel.OutputPort?.UniqueId ?? ""; switch (constantNodeModel) { case StringConstantModel stringConstantModel: { var index = builder.StoreStringConstant(stringConstantModel.value ?? string.Empty); var cf = new ConstantString { Value = new StringReference(index, StringReference.Storage.Managed) }; node = MapPort(portToOffsetMapping, outputPortId, Direction.Output, ref cf.ValuePort.Port, cf); return; } case BooleanConstantNodeModel booleanConstantNodeModel: { var cf = new ConstantBool { Value = booleanConstantNodeModel.value }; node = MapPort(portToOffsetMapping, outputPortId, Direction.Output, ref cf.ValuePort.Port, cf); return; } case IntConstantModel intConstantModel: { var cf = new ConstantInt { Value = intConstantModel.value }; node = MapPort(portToOffsetMapping, outputPortId, Direction.Output, ref cf.ValuePort.Port, cf); return; } case FloatConstantModel floatConstantModel: { var cf = new ConstantFloat { Value = floatConstantModel.value }; node = MapPort(portToOffsetMapping, outputPortId, Direction.Output, ref cf.ValuePort.Port, cf); return; } case Vector2ConstantModel vector2ConstantModel: { var cf = new ConstantFloat2 { Value = vector2ConstantModel.value }; node = MapPort(portToOffsetMapping, outputPortId, Direction.Output, ref cf.ValuePort.Port, cf); return; } case Vector3ConstantModel vector3ConstantModel: { var cf = new ConstantFloat3 { Value = vector3ConstantModel.value }; node = MapPort(portToOffsetMapping, outputPortId, Direction.Output, ref cf.ValuePort.Port, cf); return; } case Vector4ConstantModel vector4ConstantModel: { var cf = new ConstantFloat4 { Value = vector4ConstantModel.value }; node = MapPort(portToOffsetMapping, outputPortId, Direction.Output, ref cf.ValuePort.Port, cf); return; } case QuaternionConstantModel quaternionConstantModel: { var cf = new ConstantQuaternion { Value = quaternionConstantModel.value }; node = MapPort(portToOffsetMapping, outputPortId, Direction.Output, ref cf.ValuePort.Port, cf); return; } case ObjectConstantModel _: { throw new NotImplementedException( "Conversion and all - either a prefab (might live in a graph) or a scene object (must be injected during runtime bootstrap)"); // portToOffsetMapping = new Dictionary<IPortModel, uint>(); // var cf = new ConstantEntity {Value = objectConstantModel.value}; // MapPort(portToOffsetMapping, objectConstantModel.OutputPort, ref cf.ValuePort.Port, nodeId); // node = cf; // return; } default: throw new NotImplementedException(); } }
public static VisualElement CreateEditorForNodeModel(this VisualElement element, IConstantNodeModel model, Action <IChangeEvent> onValueChanged) { VisualElement editorElement; var ext = ExtensionMethodCache <IConstantEditorBuilder> .GetExtensionMethod(model.GetType(), ConstantEditorBuilder.FilterMethods, ConstantEditorBuilder.KeySelector); var graphAsset = model.AssetModel; if (ext != null) { Action <IChangeEvent> myValueChanged = evt => { if (evt != null) // Enum editor sends null { var p = evt.GetType().GetProperty("newValue"); var newValue = p.GetValue(evt); ((ConstantNodeModel)model).ObjectValue = newValue; onValueChanged(evt); } // TODO ugly but required to actually get the graph to be saved. Note that for some reason, the // first edit works because the graph is already dirty EditorUtility.SetDirty(graphAsset as Object); }; var constantBuilder = new ConstantEditorBuilder(myValueChanged); editorElement = (VisualElement)ext.Invoke(null, new object[] { constantBuilder, model }); } else { Debug.Log($"Could not draw Editor GUI for node of type {model.GetType()}"); editorElement = new Label("<Unknown>"); } return(editorElement); }
public static IGraphElement CreateConstantToken(this ElementBuilder elementBuilder, IStore store, IConstantNodeModel model) { var ui = new Token(); ui.Setup(model, store, elementBuilder.GraphView); return(ui); }