/// <summary>
        /// Pull values from the edge (in case of a custom convertion method)
        /// This method can only be called on input ports
        /// </summary>
        public void PullData()
        {
            if (customPortIOMethod != null)
            {
                customPortIOMethod(owner, edges, this);
                return;
            }

            // check if this port have connection to ports that have custom output functions
            if (edgeWithRemoteCustomIO.Count == 0)
            {
                return;
            }

            // Only one input connection is handled by this code, if you want to
            // take multiple inputs, you must create a custom input function see CustomPortsNode.cs
            if (edges.Count > 0)
            {
                var passThroughObject = edges.First().passThroughBuffer;

                // We do an extra convertion step in case the buffer output is not compatible with the input port
                if (passThroughObject != null)
                {
                    if (TypeAdapter.AreAssignable(fieldInfo.FieldType, passThroughObject.GetType()))
                    {
                        passThroughObject = TypeAdapter.Convert(passThroughObject, fieldInfo.FieldType);
                    }
                }

                fieldInfo.SetValue(fieldOwner, passThroughObject);
            }
        }
Пример #2
0
        PushDataDelegate CreatePushDataDelegateForEdge(SerializableEdge edge)
        {
            try
            {
                //Creation of the delegate to move the data from the input node to the output node:
                FieldInfo inputField  = edge.inputNode.GetType().GetField(edge.inputFieldName, BindingFlags.Public | BindingFlags.Instance);
                FieldInfo outputField = edge.outputNode.GetType().GetField(edge.outputFieldName, BindingFlags.Public | BindingFlags.Instance);

// We keep slow checks inside the editor
#if UNITY_EDITOR
                if (!BaseGraph.TypesAreConnectable(inputField.FieldType, outputField.FieldType))
                {
                    Debug.LogError("Can't convert from " + inputField.FieldType + " to " + outputField.FieldType + ", you must specify a custom port function (i.e CustomPortInput or CustomPortOutput) for non-implicit convertions");
                }
#endif

                Expression inputParamField  = Expression.Field(Expression.Constant(edge.inputNode), inputField);
                Expression outputParamField = Expression.Field(Expression.Constant(edge.outputNode), outputField);

                var inType  = edge.inputPort.portData.displayType ?? inputField.FieldType;
                var outType = edge.outputPort.portData.displayType ?? outputField.FieldType;

                // If there is a user defined convertion function, then we call it
                if (TypeAdapter.AreAssignable(outType, inType))
                {
                    // We add a cast in case there we're calling the conversion method with a base class parameter (like object)
                    var convertedParam = Expression.Convert(outputParamField, outType);
                    outputParamField = Expression.Call(TypeAdapter.GetConvertionMethod(outType, inType), convertedParam);
                    // In case there is a custom port behavior in the output, then we need to re-cast to the base type because
                    // the convertion method return type is not always assignable directly:
                    outputParamField = Expression.Convert(outputParamField, inputField.FieldType);
                }
                else                 // otherwise we cast
                {
                    outputParamField = Expression.Convert(outputParamField, inputField.FieldType);
                }

                BinaryExpression assign = Expression.Assign(inputParamField, outputParamField);
                return(Expression.Lambda <PushDataDelegate>(assign).Compile());
            } catch (Exception e) {
                Debug.LogError(e);
                return(null);
            }
        }
Пример #3
0
        PushDataDelegate CreatePushDataDelegateForEdge(SerializableEdge edge)
        {
            try
            {
                //Creation of the delegate to move the data from the input node to the output node:
                FieldInfo inputField  = edge.inputNode.GetType().GetField(edge.inputFieldName, BindingFlags.Public | BindingFlags.Instance);
                FieldInfo outputField = edge.outputNode.GetType().GetField(edge.outputFieldName, BindingFlags.Public | BindingFlags.Instance);

// We keep slow checks inside the editor
#if UNITY_EDITOR
                if (!BaseGraph.TypesAreConnectable(inputField.FieldType, outputField.FieldType))
                {
                    Debug.LogError("Can't convert from " + inputField.FieldType + " to " + outputField.FieldType + ", you must specify a custom port function (i.e CustomPortInput or CustomPortOutput) for non-implicit convertions");
                }
#endif

                // TODO: TypeAdapter convertion method here

                Expression inputParamField  = Expression.Field(Expression.Constant(edge.inputNode), inputField);
                Expression outputParamField = Expression.Field(Expression.Constant(edge.outputNode), outputField);

                // If there is a user defined convertion function, then we call it
                if (TypeAdapter.AreAssignable(outputField.FieldType, inputField.FieldType))
                {
                    outputParamField = Expression.Call(TypeAdapter.GetConvertionMethod(outputField.FieldType, inputField.FieldType), outputParamField);
                }
                else                 // otherwise we cast
                {
                    outputParamField = Expression.Convert(outputParamField, inputField.FieldType);
                }

                BinaryExpression assign = Expression.Assign(inputParamField, outputParamField);
                return(Expression.Lambda <PushDataDelegate>(assign).Compile());
            } catch (Exception e) {
                Debug.LogError(e);
                return(null);
            }
        }
Пример #4
0
        PushDataDelegate CreatePushDataDelegateForEdge(SerializableEdge edge)
        {
            try
            {
                //Creation of the delegate to move the data from the input node to the output node:
                FieldInfo inputField = edge.inputNode.GetType().GetField(edge.inputFieldName, BindingFlags.Public | BindingFlags.Instance);
                FieldInfo outputField = edge.outputNode.GetType().GetField(edge.outputFieldName, BindingFlags.Public | BindingFlags.Instance);
                Type      inType, outType;

#if DEBUG_LAMBDA
                return(new PushDataDelegate(() => {
                    var outValue = outputField.GetValue(edge.outputNode);
                    inType = edge.inputPort.portData.displayType ?? inputField.FieldType;
                    outType = edge.outputPort.portData.displayType ?? outputField.FieldType;
                    Debug.Log($"Push: {inType}({outValue}) -> {outType} | {owner.name}");

                    object convertedValue = outValue;
                    if (TypeAdapter.AreAssignable(outType, inType))
                    {
                        var convertionMethod = TypeAdapter.GetConvertionMethod(outType, inType);
                        Debug.Log("Convertion method: " + convertionMethod.Name);
                        convertedValue = convertionMethod.Invoke(null, new object[] { outValue });
                    }

                    inputField.SetValue(edge.inputNode, convertedValue);
                }));
#endif

// We keep slow checks inside the editor
#if UNITY_EDITOR
                if (!BaseGraph.TypesAreConnectable(inputField.FieldType, outputField.FieldType))
                {
                    return(null);
                }
#endif

                Expression inputParamField  = Expression.Field(Expression.Constant(edge.inputNode), inputField);
                Expression outputParamField = Expression.Field(Expression.Constant(edge.outputNode), outputField);

                inType  = edge.inputPort.portData.displayType ?? inputField.FieldType;
                outType = edge.outputPort.portData.displayType ?? outputField.FieldType;

                // If there is a user defined convertion function, then we call it
                if (TypeAdapter.AreAssignable(outType, inType))
                {
                    // We add a cast in case there we're calling the conversion method with a base class parameter (like object)
                    var convertedParam = Expression.Convert(outputParamField, outType);
                    outputParamField = Expression.Call(TypeAdapter.GetConvertionMethod(outType, inType), convertedParam);
                    // In case there is a custom port behavior in the output, then we need to re-cast to the base type because
                    // the convertion method return type is not always assignable directly:
                    outputParamField = Expression.Convert(outputParamField, inputField.FieldType);
                }
                else                 // otherwise we cast
                {
                    outputParamField = Expression.Convert(outputParamField, inputField.FieldType);
                }

                BinaryExpression assign = Expression.Assign(inputParamField, outputParamField);
                return(Expression.Lambda <PushDataDelegate>(assign).Compile());
            }
            catch (Exception e)
            {
                Debug.LogError(e);
                return(null);
            }
        }