Beispiel #1
0
 public override string GenerateCode()
 {
     if (condition != null && condition.isAssigned)
     {
         string data = CodeGenerator.ParseValue((object)condition);
         if (!string.IsNullOrEmpty(data))
         {
             if (CodeGenerator.debugScript || CodeGenerator.CanReturnState(this))
             {
                 return(CodeGenerator.GenerateIfStatement(data,
                                                          CodeGenerator.GetFinishCode(this, true, true, false, onTrue, onFinished),
                                                          CodeGenerator.GetFinishCode(this, false, true, false, onFalse, onFinished)));
             }
             if (onTrue.isAssigned)
             {
                 if (onFalse.isAssigned)
                 {
                     data = CodeGenerator.GenerateIfStatement(data, CodeGenerator.GenerateFlowCode(onTrue, this));
                     string failure = CodeGenerator.GenerateFlowCode(onFalse, this);
                     if (!string.IsNullOrEmpty(failure))
                     {
                         var flag = onFalse.targetType == MemberData.TargetType.FlowNode &&
                                    onFalse.GetTargetNode() is NodeIf &&
                                    !(onFalse.GetTargetNode() as NodeIf).onFinished.isAssigned;
                         if (flag && CodeGenerator.IsGroupedNode(this))
                         {
                             data += " else " + failure.RemoveLineAndTabOnFirst();
                         }
                         else
                         {
                             data += " else {" + failure.AddLineInFirst().AddTabAfterNewLine(1) + "\n}";
                         }
                     }
                 }
                 else
                 {
                     data = CodeGenerator.GenerateIfStatement(data, CodeGenerator.GenerateFlowCode(onTrue, this));
                 }
                 data += CodeGenerator.GetFinishCode(this, true, false, false, onFinished).AddLineInFirst();
                 return(data);
             }
             else if (onFalse.isAssigned)
             {
                 return
                     (CodeGenerator.GenerateIfStatement(
                          data.AddFirst("!(").Add(")"),
                          CodeGenerator.GenerateFlowCode(onFalse, this)) +
                      CodeGenerator.GetFinishCode(this, false, true, false, onFinished).AddLineInFirst());
             }
             return
                 (CodeGenerator.GenerateIfStatement(data, "") +
                  CodeGenerator.GetFinishCode(this, true, false, false, onFinished).AddLineInFirst());
         }
         else
         {
             throw new Exception("Condition generates empty code");
         }
     }
     throw new System.Exception("Unassigned condition");
 }
Beispiel #2
0
 public bool AddNodeTree(MemberData member, TreeViewItem parentTree, IList <TreeViewItem> rows, bool isChildren = true)
 {
     if (member.isAssigned && member.IsTargetingPinOrNode)
     {
         if (member.targetType == MemberData.TargetType.FlowNode)
         {
             Node n = member.GetTargetNode();
             if (n != null)
             {
                 AddNodes(n, parentTree, rows, isChildren);
                 return(true);
             }
         }
         else if (member.targetType == MemberData.TargetType.FlowInput)
         {
             Node n    = member.GetTargetNode();
             var  flow = member.Invoke(null) as FlowInput;
             if (n != null && flow != null)
             {
                 bool flag = false;
                 if (!flowPortsMap.TryGetValue(flow, out var flowTree))
                 {
                     flag     = true;
                     flowTree = new HierarchyPortTree(
                         n,
                         flow,
                         uNodeEditorUtility.GetUIDFromString($"{n.GetHashCode()}:FI={member.startName}"),
                         -1,
                         $"{n.GetNodeName()} ( {ObjectNames.NicifyVariableName(flow.name)} )")
                     {
                         icon = uNodeEditorUtility.GetTypeIcon(n.GetNodeIcon()) as Texture2D
                     };
                     flowPortsMap[flow] = flowTree;
                 }
                 if (isChildren)
                 {
                     parentTree.AddChild(flowTree);
                 }
                 else
                 {
                     parentTree.parent.AddChild(flowTree);
                 }
                 rows.Add(flowTree);
                 if (flag)
                 {
                     var drawer = HierarchyDrawer.FindDrawer(n.GetType());
                     drawer.manager = this;
                     drawer.AddChildNodes(n, flowTree, rows);
                 }
                 return(true);
             }
         }
     }
     return(false);
 }
Beispiel #3
0
 public bool CanAddTree(MemberData member)
 {
     if (member.isAssigned && member.IsTargetingPinOrNode)
     {
         if (member.targetType == MemberData.TargetType.FlowNode)
         {
             return(member.GetTargetNode() != null);
         }
         else if (member.targetType == MemberData.TargetType.FlowInput)
         {
             return(member.GetTargetNode() != null && member.Invoke(null) as FlowInput != null);
         }
     }
     return(false);
 }
Beispiel #4
0
 public override void RegisterPort()
 {
     base.RegisterPort();
     if (CodeGenerator.isGenerating)
     {
         //Register this node as state node, because this is coroutine node with state.
         CodeGenerator.RegisterAsStateNode(this);
         var node = targetNode.GetTargetNode();
         if (node != null)
         {
             //Register each target node as state node, because this node need to compare the target state.
             CodeGenerator.RegisterAsStateNode(node);
         }
     }
 }
Beispiel #5
0
 /// <summary>
 /// True if instance variable from node has used in flow nodes.
 /// </summary>
 /// <param name="from"></param>
 /// <param name="field"></param>
 /// <param name="index"></param>
 /// <param name="flows"></param>
 /// <returns></returns>
 public static bool NeedInstanceVariable(Node from, FieldInfo field, int index, IList <Node> flows)
 {
     if (from && flows != null && flows.Count > 0)
     {
         var allConnection = GetAllNode(from.transform.parent);
         var allFlows      = new HashSet <NodeComponent>();
         foreach (var flow in flows)
         {
             if (flow == null)
             {
                 continue;
             }
             FindAllNodeConnection(flow, ref allFlows);
         }
         bool check = false;
         Func <object, bool> validation = null;
         validation = delegate(object obj) {
             if (obj is MemberData)
             {
                 MemberData member = obj as MemberData;
                 if (member.isAssigned)
                 {
                     Node n = member.GetTargetNode();
                     if (n)
                     {
                         int tes;
                         if (member.targetType == MemberData.TargetType.NodeFieldElement && n == from &&
                             int.TryParse(member.startName.Split('#')[1], out tes) && tes == index &&
                             member.startName.Split('#')[0] == field.Name)
                         {
                             check = true;
                         }
                         else if (member.targetType == MemberData.TargetType.ValueNode)
                         {
                             AnalizerUtility.AnalizeObject(n, validation);
                         }
                     }
                 }
             }
             return(check);
         };
         foreach (Node node in allConnection)
         {
             if (node == null || !isInUngrouped && IsGroupedNode(from) /*&& allFlows.Contains(node)*/)
             {
                 continue;
             }
             AnalizerUtility.AnalizeObject(node, validation);
             if (check)
             {
                 var nodes = GetFlowConnectedTo(node);
                 if (nodes.Count > 0)
                 {
                     return(nodes.Any(n => !allFlows.Contains(n)));
                 }
             }
         }
     }
     return(false);
 }
Beispiel #6
0
 public IEnumerator OnUpdate()
 {
     while (state == StateType.Running)
     {
         if (!targetNode.isAssigned)
         {
             Debug.LogError("Unassigned target node", this);
             Finish();
             yield break;
         }
         Node n;
         if (canExecuteEvent && (RepeatForever || RepeatCount > repeatNumber))
         {
             WaitUntil w;
             if (!targetNode.ActivateFlowNode(out n, out w))
             {
                 yield return(w);
             }
             repeatNumber++;
             canExecuteEvent = false;
         }
         else
         {
             n = targetNode.GetTargetNode();
         }
         if (n.IsFinished())
         {
             JumpStatement js = n.GetJumpState();
             if (js != null)
             {
                 if (js.jumpType == JumpStatementType.Continue)
                 {
                     continue;
                 }
                 else if (js.jumpType == JumpStatementType.Break)
                 {
                     Finish();
                     yield break;
                 }
                 jumpState = js;
                 Finish();
                 yield break;
             }
             if (StopEventOnFailure && n.currentState == StateType.Failure)
             {
                 Finish();
                 yield break;
             }
             if (!RepeatForever && RepeatCount <= repeatNumber)
             {
                 Finish();
             }
             canExecuteEvent = true;
         }
         yield return(null);
     }
 }
Beispiel #7
0
 /// <summary>
 /// Return true of flow member is coroutine.
 /// </summary>
 /// <param name="member"></param>
 /// <returns></returns>
 protected bool HasCoroutineInFlow(MemberData member)
 {
     if (member != null && member.isAssigned)
     {
         var node = member.GetTargetNode();
         if (node != null)
         {
             return(node.IsCoroutine());
         }
     }
     return(false);
 }
Beispiel #8
0
 public override bool IsCoroutine()
 {
     if (kind == PortKind.FlowInput && target.isAssigned)
     {
         var node = target.GetTargetNode();
         if (node != null)
         {
             return(node.IsCoroutine());
         }
     }
     return(base.IsCoroutine());
 }
Beispiel #9
0
        /// <summary>
        /// Get flow nodes from node.
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public static HashSet <NodeComponent> GetFlowConnection(NodeComponent node)
        {
            HashSet <NodeComponent> allNodes;

            if (generatorData.flowNodeConnectionsMap.TryGetValue(node, out allNodes))
            {
                return(allNodes);
            }
            allNodes = new HashSet <NodeComponent>();
            if (node is StateNode)
            {
                StateNode         eventNode = node as StateNode;
                TransitionEvent[] TE        = eventNode.GetTransitions();
                foreach (TransitionEvent transition in TE)
                {
                    if (transition.GetTargetNode() != null && !allNodes.Contains(transition.GetTargetNode()))
                    {
                        allNodes.Add(transition.GetTargetNode());
                    }
                }
            }
            Func <object, bool> validation = delegate(object obj) {
                if (obj is MemberData)
                {
                    MemberData member = obj as MemberData;
                    if (member != null && member.isAssigned &&
                        (member.targetType == MemberData.TargetType.FlowNode ||
                         member.targetType == MemberData.TargetType.FlowInput) &&
                        !allNodes.Contains(member.GetTargetNode()))
                    {
                        allNodes.Add(member.GetTargetNode());
                    }
                }
                return(false);
            };

            AnalizerUtility.AnalizeObject(node, validation);
            generatorData.flowNodeConnectionsMap[node] = allNodes;
            return(allNodes);
        }
Beispiel #10
0
        public static HashSet <NodeComponent> GetConnections(NodeComponent node)
        {
            HashSet <NodeComponent> allNodes;

            if (generatorData.nodeConnectionsMap.TryGetValue(node, out allNodes))
            {
                return(allNodes);
            }
            allNodes = new HashSet <NodeComponent>();
            if (node is StateNode)
            {
                StateNode         eventNode = node as StateNode;
                TransitionEvent[] TE        = eventNode.GetTransitions();
                foreach (TransitionEvent transition in TE)
                {
                    var tNode = transition.GetTargetNode();
                    if (tNode != null)
                    {
                        allNodes.Add(tNode);
                    }
                }
            }
            else if (node is BaseEventNode)
            {
                BaseEventNode stateEvent = node as BaseEventNode;
                foreach (var member in stateEvent.GetFlows())
                {
                    var tNode = member.GetTargetNode();
                    if (tNode != null)
                    {
                        allNodes.Add(tNode);
                    }
                }
            }
            Func <object, bool> validation = delegate(object obj) {
                if (obj is MemberData)
                {
                    MemberData member = obj as MemberData;
                    if (member != null && member.IsTargetingPinOrNode)
                    {
                        allNodes.Add(member.GetTargetNode());
                    }
                }
                return(false);
            };

            AnalizerUtility.AnalizeObject(node, validation);
            generatorData.nodeConnectionsMap[node] = allNodes;
            return(allNodes);
        }
Beispiel #11
0
        public static void RetargetValueNode(Node source, Node destination)
        {
            List <uNodeComponent> nodes = new List <uNodeComponent>();

            foreach (Transform t in source.transform.parent)
            {
                var comp = t.GetComponent <uNodeComponent>();
                if (comp != null)
                {
                    if (comp is StateNode)
                    {
                        var state       = comp as StateNode;
                        var transitions = state.GetTransitions();
                        foreach (var tr in transitions)
                        {
                            nodes.Add(tr);
                        }
                    }
                    nodes.Add(comp);
                }
            }
            Func <object, bool> validation = delegate(object o) {
                if (o is MemberData)
                {
                    MemberData member = o as MemberData;
                    if (member.targetType == MemberData.TargetType.ValueNode)
                    {
                        Node n = member.GetTargetNode();
                        if (n != null && n == source)
                        {
                            member.RefactorUnityObject(new Object[] { source }, new Object[] { destination });
                            //return true;
                        }
                    }
                }
                return(false);
            };

            foreach (var n in nodes)
            {
                AnalizerUtility.AnalizeObject(n, validation);
            }
        }
Beispiel #12
0
 private static void ConnectNode(NodeComponent node)
 {
     if (node != null && !generatorData.connectedNode.Contains(node))
     {
         generatorData.connectedNode.Add(node);
         var nodes = GetConnections(node);
         if (nodes != null)
         {
             foreach (NodeComponent n in nodes)
             {
                 if (n)
                 {
                     ConnectNode(n);
                 }
             }
         }
         if (node is ISuperNode)
         {
             ISuperNode superNode = node as ISuperNode;
             foreach (var n in superNode.nestedFlowNodes)
             {
                 if (n != null)
                 {
                     ConnectNode(n);
                 }
             }
         }
         Func <object, bool> validation = delegate(object obj) {
             if (obj is MemberData)
             {
                 MemberData member = obj as MemberData;
                 if (member.IsTargetingPinOrNode)
                 {
                     ConnectNode(member.GetTargetNode());
                 }
             }
             return(false);
         };
         AnalizerUtility.AnalizeObject(node, validation);
     }
 }
Beispiel #13
0
        public static PortView GetOutputPort(MemberData inputValue, UGraphView graphView)
        {
            var outputNode = inputValue.GetTargetNode();

            if (outputNode != null)
            {
                if (inputValue.IsTargetingNode)
                {
                    switch (inputValue.targetType)
                    {
                    case MemberData.TargetType.FlowNode:
                        return(GetSelfPort(outputNode, Orientation.Vertical, graphView));

                    case MemberData.TargetType.ValueNode:
                        PortView port;
                        if (graphView.portValueNodeAliases.TryGetValue(outputNode, out port) && port != null)
                        {
                            return(port);
                        }
                        return(GetSelfPort(outputNode, Orientation.Horizontal, graphView));
                    }
                }
                UNodeView nodeView;
                if (graphView.nodeViewsPerNode.TryGetValue(outputNode, out nodeView))
                {
                    foreach (var p in nodeView.outputPorts)
                    {
                        if (p.portData.portID == inputValue.startName)
                        {
                            return(p);
                        }
                    }
                }
            }
            return(null);
        }
Beispiel #14
0
 public static HashSet <NodeComponent> GetFlowConnectedTo(Node target)
 {
     if (target != null)
     {
         if (generatorData.FlowConnectedTo.TryGetValue(target, out var comp))
         {
             return(comp);
         }
         comp = new HashSet <NodeComponent>();
         Node currNode = null;
         Func <object, bool> validation = delegate(object obj) {
             if (obj is MemberData)
             {
                 MemberData member     = obj as MemberData;
                 Node       targetNode = member.GetTargetNode();
                 if (targetNode == target)
                 {
                     if (member.targetType == MemberData.TargetType.FlowNode || member.targetType == MemberData.TargetType.FlowInput)
                     {
                         comp.Add(currNode);
                         return(true);
                     }
                     else if (member.targetType == MemberData.TargetType.ValueNode ||
                              member.targetType == MemberData.TargetType.NodeField ||
                              member.targetType == MemberData.TargetType.NodeFieldElement)
                     {
                         var connectedNodes = GetFlowConnectedTo(currNode);
                         if (connectedNodes != null)
                         {
                             foreach (var n in connectedNodes)
                             {
                                 comp.Add(n);
                             }
                         }
                     }
                 }
             }
             return(false);
         };
         foreach (Node node in generatorData.allNode)
         {
             if (target == node)
             {
                 continue;
             }
             if (node is StateNode)
             {
                 StateNode         eventNode = node as StateNode;
                 TransitionEvent[] TE        = eventNode.GetTransitions();
                 foreach (TransitionEvent transition in TE)
                 {
                     if (transition != null && transition.GetTargetNode() == target)
                     {
                         comp.Add(node);
                         break;
                     }
                 }
             }
             else if (node is IMacro)
             {
                 IMacro macro       = node as IMacro;
                 var    outputFlows = macro.OutputFlows;
                 foreach (var flow in outputFlows)
                 {
                     if (flow != null && flow.target.GetTargetNode() == target)
                     {
                         comp.Add(node);
                         break;
                     }
                 }
             }
             currNode = node;
             AnalizerUtility.AnalizeObject(node, validation);
         }
         foreach (EventNode method in generatorData.eventNodes)
         {
             if (method == null)
             {
                 continue;
             }
             foreach (var flow in method.GetFlows())
             {
                 if (flow.GetTargetNode() == target)
                 {
                     comp.Add(method);
                     break;
                 }
             }
         }
         generatorData.FlowConnectedTo[target] = comp;
         return(comp);
     }
     return(null);
 }
Beispiel #15
0
        /// <summary>
        /// Function for generating code for flow member.
        /// </summary>
        /// <param name="flowMember">The flow member</param>
        /// <param name="from">The node which flow member comes from</param>
        /// <param name="waitTarget">If true, will generate wait code on coroutine member.</param>
        /// <returns></returns>
        public static string GenerateFlowCode(MemberData flowMember, NodeComponent from, bool waitTarget = true)
        {
            if (flowMember == null)
            {
                return(null);
            }
            if (!flowMember.isAssigned)
            {
                return(null);
            }
            Node target = flowMember.GetTargetNode();

            if (target == null)
            {
                return(null);
            }
            if (flowMember.targetType != MemberData.TargetType.FlowNode && flowMember.targetType != MemberData.TargetType.FlowInput)
            {
                throw new System.Exception("Incorrect target type : " + flowMember.targetType.ToString() + ", TargetType must FlowNode or FlowInput");
            }
            if (flowMember.targetType != MemberData.TargetType.FlowInput && !target.IsFlowNode())
            {
                throw new System.Exception("node is not flow node.");
            }
            string debug = null;

            if (setting.debugScript)
            {
                debug = GenerateDebugCode(flowMember).AddLineInEnd();
            }
            if (flowMember.targetType == MemberData.TargetType.FlowNode)
            {
                if (!isInUngrouped && !uNodeUtility.IsInStateGraph(target) && !IsUngroupedNode(target))
                {
                    return(debug + GenerateNode(target));
                }
                if (waitTarget && (isInUngrouped || from && from.IsSelfCoroutine() || allowYieldStatement && IsUngroupedNode(target)))
                {
                    if (!generatorData.ungroupedNode.Contains(target))
                    {
                        return(debug + GenerateNode(target));
                    }
                    if (!allowYieldStatement)
                    {
                        throw new Exception("The current block doesn't allow coroutines / yield statements");
                    }
                    return(debug + "yield return " + RunEvent(target));
                }
                if (!isInUngrouped && generatorData.groupedNode.Contains(target))
                {
                    return(debug + GenerateNode(target));
                }
                if (!generatorData.ungroupedNode.Contains(target))
                {
                    if (!allowYieldStatement && target.IsSelfCoroutine())
                    {
                        throw new Exception("The current block doesn't allow coroutines / yield statements");
                    }
                    throw new uNodeException($"Forbidden to generate state code because the node: {target.GetNodeName()} is not registered as State Node.\nEnsure to register it using {nameof(CodeGenerator)}.{nameof(CodeGenerator.RegisterAsStateNode)}", target);
                }
                return(debug + RunEvent(target));
            }
            else
            {
                return(debug + GenerateFlowCode(flowMember.Invoke(null) as IFlowGenerate, target));
            }
            // return debug + GetInvokeCode(_eventCode, false, generatorData.GetEventName(target));
        }
Beispiel #16
0
 /// <summary>
 /// Return true on flow body can be simplify to lambda expression code.
 /// </summary>
 /// <param name="target"></param>
 /// <param name="returnType"></param>
 /// <param name="parameterTypes"></param>
 /// <returns></returns>
 public static bool CanSimplifyToLambda(MemberData target, Type returnType, IList <Type> parameterTypes)
 {
     if (target.IsTargetingNode)
     {
         var bodyNode = target.GetTargetNode();
         if (bodyNode is MultipurposeNode)
         {
             var node = bodyNode as MultipurposeNode;
             if (node.target.target.isAssigned && !node.onFinished.isAssigned)
             {
                 System.Type[] memberTypes = null;
                 if (node.target.target.targetType == MemberData.TargetType.Method)
                 {
                     var members = node.target.target.GetMembers(false);
                     if (members != null && members.Length > 0)
                     {
                         var lastMember = members.LastOrDefault() as System.Reflection.MethodInfo;
                         if (lastMember != null && lastMember.ReturnType == returnType)
                         {
                             memberTypes = lastMember.GetParameters().Select(i => i.ParameterType).ToArray();
                         }
                     }
                 }
                 else if (node.target.target.targetType == MemberData.TargetType.uNodeFunction)
                 {
                     uNodeFunction func = node.target.target.GetUnityObject() as uNodeFunction;
                     if (func != null && func.ReturnType() == returnType)
                     {
                         memberTypes = func.parameters.Select(i => i.Type).ToArray();
                     }
                 }
                 if (memberTypes != null)
                 {
                     if (parameterTypes.Count == memberTypes.Length && node.target.parameters.Length == memberTypes.Length)
                     {
                         bool flag = true;
                         for (int x = 0; x < parameterTypes.Count; x++)
                         {
                             if (parameterTypes[x] != memberTypes[x])
                             {
                                 flag = false;
                                 break;
                             }
                         }
                         if (flag)
                         {
                             for (int x = 0; x < parameterTypes.Count; x++)
                             {
                                 var p = node.target.parameters[x];
                                 if (p.targetType != MemberData.TargetType.NodeFieldElement || p.GetAccessIndex() != x)
                                 {
                                     flag = false;
                                     break;
                                 }
                             }
                             if (flag)
                             {
                                 return(true);
                             }
                         }
                     }
                 }
             }
         }
     }
     return(false);
 }
Beispiel #17
0
        /// <summary>
        /// Are the flow connection identifiead as coroutine?
        /// </summary>
        /// <param name="member"></param>
        /// <returns></returns>
        public static bool IsCoroutineFlow(MemberData member)
        {
            var node = member.GetTargetNode();

            return(IsCoroutineFlow(node));
        }
Beispiel #18
0
        private string GenerateEventCodes()
        {
            if (!body.isAssigned)
            {
                return(null);
            }
            Type targetType = target.type;

            if (targetType == null)
            {
                return(null);
            }
            System.Type[] parameterTypes = null;
            if (targetType.IsCastableTo(typeof(Delegate)))
            {
                parameterTypes = targetType.GetMethod("Invoke").GetParameters().Select(i => i.ParameterType).ToArray();

                if (CodeGenerator.IsGroupedNode(this) && CodeGenerator.CanSimplifyToLambda(body, targetType, parameterTypes))
                {
                    var bodyNode = body.GetTargetNode();
                    if (bodyNode as MultipurposeNode)
                    {
                        string result = bodyNode.GenerateValueCode();
                        if (result.EndsWith(")"))
                        {
                            int deep = 0;
                            for (int i = result.Length - 1; i > 0; i--)
                            {
                                var c = result[i];
                                if (c == '(')
                                {
                                    if (deep == 0)
                                    {
                                        result = result.Remove(i);
                                        break;
                                    }
                                    else
                                    {
                                        deep--;
                                    }
                                }
                                else if (c == ')' && i != result.Length - 1)
                                {
                                    deep++;
                                }
                            }
                        }
                        return(result);
                    }
                }
            }
            else if (targetType.IsCastableTo(typeof(UnityEventBase)))
            {
                var method = targetType.GetMethod("AddListener");
                var param  = method.GetParameters()[0].ParameterType;
                parameterTypes = param.GetGenericArguments();

                if (CodeGenerator.IsGroupedNode(this) && CodeGenerator.CanSimplifyToLambda(body, typeof(void), parameterTypes))
                {
                    var bodyNode = body.GetTargetNode();
                    if (bodyNode as MultipurposeNode)
                    {
                        string result = bodyNode.GenerateValueCode();
                        if (result.EndsWith(")"))
                        {
                            int deep = 0;
                            for (int i = result.Length - 1; i > 0; i--)
                            {
                                var c = result[i];
                                if (c == '(')
                                {
                                    if (deep == 0)
                                    {
                                        result = result.Remove(i);
                                        break;
                                    }
                                    else
                                    {
                                        deep--;
                                    }
                                }
                                else if (c == ')' && i != result.Length - 1)
                                {
                                    deep++;
                                }
                            }
                        }
                        return(result);
                    }
                }
            }
            else
            {
                throw new Exception("Unsupported event to hook:" + target.DisplayName(true));
            }
            //Generate lambda code
            string        contents       = null;
            List <Type>   types          = new List <Type>();
            List <string> parameterNames = new List <string>();

            for (int i = 0; i < parameterTypes.Length; i++)
            {
                var pType = parameterTypes[i];
                var field = this.GetType().GetField("parameters");
                if (pType != null)
                {
                    string varName = null;
                    if (CodeGenerator.NeedInstanceVariable(this, field, i, new Node[] { this }))
                    {
                        varName  = CodeGenerator.GenerateVariableName("tempVar", this);
                        contents = CodeGenerator.AddVariable(this, field, i, pType, true) + " = " + varName + ";" + contents.AddLineInFirst();
                    }
                    else
                    {
                        varName = CodeGenerator.GetVariableName(this, field, i);
                    }
                    types.Add(pType);
                    parameterNames.Add(varName);
                }
            }
            contents += CodeGenerator.GenerateFlowCode(body, this).AddLineInFirst();
            return(CodeGenerator.GenerateAnonymousMethod(types, parameterNames, contents));
        }
Beispiel #19
0
 public override string GenerateValueCode()
 {
     System.Type rType = null;
     if (returnType.isAssigned)
     {
         rType = returnType.Get <System.Type>();
     }
     if (rType != null && parameterTypes.All(item => item.isAssigned && item.Get <System.Type>() != null))
     {
         string        contents = null;
         System.Type[] types    = parameterTypes.Select(m => m.isAssigned ? m.startType : null).ToArray();
         if (!CodeGenerator.IsInStateGraph(this) && CodeGenerator.CanSimplifyToLambda(body, rType, types))
         {
             var bodyNode = body.GetTargetNode();
             if (bodyNode as MultipurposeNode)
             {
                 string result = bodyNode.GenerateValueCode();
                 if (result.EndsWith(")"))
                 {
                     int deep = 0;
                     for (int i = result.Length - 1; i > 0; i--)
                     {
                         var c = result[i];
                         if (c == '(')
                         {
                             if (deep == 0)
                             {
                                 result = result.Remove(i);
                                 break;
                             }
                             else
                             {
                                 deep--;
                             }
                         }
                         else if (c == ')' && i != result.Length - 1)
                         {
                             deep++;
                         }
                     }
                 }
                 return(result);
             }
         }
         List <string> parameterNames = new List <string>();
         var           field          = this.GetType().GetField("parameterValues");
         for (int i = 0; i < types.Length; i++)
         {
             string      varName = null;
             System.Type type    = types[i];
             if (type != null)
             {
                 if (CodeGenerator.NeedInstanceVariable(this, field, i, body))                         //Auto generate instance variable for parameter.
                 {
                     varName  = CodeGenerator.GenerateVariableName("tempVar", this.GetInstanceID().ToString() + i);
                     contents = CodeGenerator.AddVariable(this, field, i, type, true) + " = " + varName + ";" + contents.AddLineInFirst();
                 }
                 else
                 {
                     varName = CodeGenerator.GetVariableName(this, field, i);
                 }
                 parameterNames.Add(varName);
             }
         }
         CodeGenerator.BeginBlock(allowYield: false); //Ensure there's no yield statements
         contents += CodeGenerator.GenerateFlowCode(body, this, false).AddLineInFirst();
         CodeGenerator.EndBlock();                    //Ensure to restore to previous block
         return(CodeGenerator.GenerateAnonymousMethod(types, parameterNames, contents));
     }
     return(null);
 }