private void ExecuteImplicitNode(CNode implicitNode) { m_inParameterBuffer.Clear(); m_outParameterBuffer.Clear(); // We first execute all implicit nodes for (int i = 0; i < implicitNode.GetInParameterCount(); i++) { CInputPin inputPin = implicitNode.InputPins[i]; if (inputPin.SourceNode != null && inputPin.SourceNode.IsImplicit) { ExecuteImplicitNode(inputPin.SourceNode); } } // Afterwards the parameters are added to the buffer for (int i = 0; i < implicitNode.GetInParameterCount(); i++) { int stackIndex = implicitNode.InputPins[i].StackIndex; if (stackIndex >= 0) { m_inParameterBuffer.Add(m_stack[stackIndex]); } else { m_inParameterBuffer.Add(null); } } // After all input parameters are resolved we execute the node and add it's output parameters to the stack implicitNode.Execute(s_nodeExecutionContext, m_inParameterBuffer, m_outParameterBuffer); AddOutParametersToStack(implicitNode.OutParameterStackIndex, implicitNode.GetOutParameterCount()); m_inParameterBuffer.Clear(); m_outParameterBuffer.Clear(); }
protected override void OnTargetFieldChanged() { if (TargetField == null) { throw new NullReferenceException("Target Field cannot be null as this would make the node invalid"); } InputPins.Clear(); OutputPins.Clear(); CInputPin targetObjectInput = new CInputPin("Target", TargetField.DeclaringType); InputPins.Add(targetObjectInput); Name = "Get " + TargetField.Name; COutputPin outputPin = new COutputPin(TargetField.Name, TargetField.FieldType); OutputPins.Add(outputPin); }
protected override void OnTargetPropertyChanged() { if (TargetProperty == null) { throw new NullReferenceException("Target Property cannot be null as this would make the node invalid"); } InputPins.Clear(); OutputPins.Clear(); Name = "Set " + TargetProperty.Name; CInputPin targetObjectInput = new CInputPin("Target", TargetProperty.DeclaringType); InputPins.Add(targetObjectInput); CInputPin setValueInput = new CInputPin("Value", TargetProperty.PropertyType); InputPins.Add(setValueInput); COutputPin newValueOutput = new COutputPin("NewValue", TargetProperty.PropertyType); OutputPins.Add(newValueOutput); }
/// <summary> /// Adds a new value input pin. This should only be called upon editor callback. /// </summary> /// <param name="context">Context which contains all editor node actions that need to be executed after this call</param> /// <param name="newPin">The new input pin that should be added</param> /// <param name="index">The index at which the input pin should be inserted</param> protected void AddInputPin(CNodeChangeContext context, CInputPin newPin, int index) { InputPins.Add(newPin); context.Actions.Add(new CAddPinChangeAction(newPin, index, true)); }
/// <summary> /// Notifies the node that the output of another pin has been connected to one of its input pins /// </summary> /// <param name="context">Context which contains all editor node actions that need to be executed after this call</param> /// <param name="pin">The pin on this node that got a new connection</param> /// <param name="otherpin">The pin this node has been connected to</param> /// <returns></returns> public virtual void OnInputConnectionChanged(CNodeChangeContext context, CInputPin pin, COutputPin otherpin) { }
// Editor functions /// <summary> /// Notifies the node that the literal value of one of its pins has been altered /// </summary> /// <param name="context">Context which contains all editor node actions that need to be executed after this call</param> /// <param name="pin">The pin whose literal value has been changed</param> /// <returns>If true the node will be redrawn in the node graph</returns> public virtual void OnInputLiteralChanged(CNodeChangeContext context, CInputPin pin) { }
private void OnTargetMethodChanged() { OutputPins.Clear(); InputPins.Clear(); CKlaxScriptRegistry registry = CKlaxScriptRegistry.Instance; registry.TryGetFunctionInfo(TargetMethod, out CKlaxScriptFunctionInfo outFunctionInfo); Name = outFunctionInfo.displayName; if (TargetMethod.ReturnType != typeof(void)) { COutputPin returnOutput = new COutputPin() { Name = "Return", Type = TargetMethod.ReturnType, }; OutputPins.Add(returnOutput); } if (!TargetMethod.IsStatic) { CInputPin targetObjectInput = new CInputPin() { Name = "Target", Type = TargetMethod.DeclaringType, Literal = null, SourceNode = null, SourceParameterIndex = -1, StackIndex = -1, }; InputPins.Add(targetObjectInput); } ParameterInfo[] methodParameters = TargetMethod.GetParameters(); for (var index = 0; index < methodParameters.Length; index++) { ParameterInfo parameter = methodParameters[index]; Type elementType = parameter.ParameterType; if (parameter.ParameterType.IsByRef) { elementType = parameter.ParameterType.GetElementType(); if (!parameter.IsIn) { m_additionalReturns.Add(index); COutputPin output = new COutputPin() { Name = parameter.Name, Type = elementType, }; OutputPins.Add(output); } } if (parameter.IsOut) { continue; } CInputPin input = new CInputPin() { Name = outFunctionInfo.inputParameterNames[index], Type = elementType, SourceNode = null, SourceParameterIndex = -1, StackIndex = -1, }; input.Literal = input.Type.IsValueType ? Activator.CreateInstance(input.Type) : null; InputPins.Add(input); m_functionProxy = new SKlaxScriptFunctionProxy(outFunctionInfo); } }
/// <summary> /// Executes the graph, returns the last node executed /// </summary> /// <param name="startNode"></param> /// <param name="firstPin"></param> /// <returns></returns> protected CNode Execute(CNode startNode, CExecutionPin firstPin) { s_nodeExecutionContext.graph = this; CExecutionPin nextExecutionPin = firstPin; CNode nextNode = startNode; while (nextNode != null) { m_inParameterBuffer.Clear(); m_outParameterBuffer.Clear(); CNode nodeToExecute = nextNode; s_nodeExecutionContext.calledPin = null; // We first execute all implicit nodes for (int i = 0; i < nodeToExecute.GetInParameterCount(); i++) { CInputPin inputPin = nodeToExecute.InputPins[i]; if (inputPin.SourceNode != null && inputPin.SourceNode.IsImplicit) { ExecuteImplicitNode(inputPin.SourceNode); } } // Afterwards the parameters are added to the buffer for (int i = 0; i < nodeToExecute.GetInParameterCount(); i++) { int stackIndex = nodeToExecute.InputPins[i].StackIndex; if (stackIndex >= 0) { m_inParameterBuffer.Add(m_stack[stackIndex]); } else { m_inParameterBuffer.Add(null); } } s_nodeExecutionContext.calledPin = nextExecutionPin != null ? nextExecutionPin.TargetPin : null; nextExecutionPin = nodeToExecute.Execute(s_nodeExecutionContext, m_inParameterBuffer, m_outParameterBuffer); if (nextExecutionPin == null || nextExecutionPin.TargetNode == null) { nextExecutionPin = null; int count = m_returnPointNodes.Count; if (count > 0) { nextNode = m_returnPointNodes[count - 1]; m_returnPointNodes.RemoveAt(count - 1); continue; } else { return(nextNode); } } nextNode = nextExecutionPin.TargetNode; AddOutParametersToStack(nodeToExecute.OutParameterStackIndex, nodeToExecute.GetOutParameterCount()); } return(null); }