public IEnumerator MovingThenStackDoesntMoveElseOrConditionStacks([Values] TestingMode mode)
        {
            var stackModel0 = GraphModel.CreateStack(string.Empty, new Vector2(-100, -100));
            IfConditionNodeModel conditionNodeModel = stackModel0.CreateStackedNode <IfConditionNodeModel>("cond");
            var thenStack = GraphModel.CreateStack(string.Empty, new Vector2(100, 100));
            var elseStack = GraphModel.CreateStack(string.Empty, new Vector2(200, 100));
            var joinStack = GraphModel.CreateStack(string.Empty, new Vector2(-100, 200));

            GraphModel.CreateEdge(thenStack.InputPorts.First(), conditionNodeModel.ThenPort);
            GraphModel.CreateEdge(joinStack.InputPorts.First(), thenStack.OutputPorts.First());
            GraphModel.CreateEdge(joinStack.InputPorts.First(), elseStack.OutputPorts.First());

            yield return(TestMove(mode,
                                  mouseDelta: new Vector2(20, 10),
                                  movedNodes: new INodeModel[] { thenStack },
                                  expectedMovedDependencies: new INodeModel[] { joinStack },
                                  expectedUnmovedDependencies: new INodeModel[] { stackModel0, elseStack }
                                  ));
        }
Exemplo n.º 2
0
        // create a function bool IsIntEven(int i)
        //      if ((i % 2) == 0) { return true; } else { return false; }
        // the goal is to have 2 different return nodes depending on a parameter
        FunctionModel CreateIsIntEvenFunction()
        {
            // define function
            FunctionModel method = GraphModel.CreateFunction("IsIntEven", Vector2.zero);

            method.ReturnType = typeof(bool).GenerateTypeHandle(GraphModel.Stencil);
            VariableDeclarationModel paramI = method.CreateAndRegisterFunctionParameterDeclaration("i", typeof(int).GenerateTypeHandle(GraphModel.Stencil));

            // add if/then/else structure
            IfConditionNodeModel if0 = CreateIfThenElseStacks(method, out var then0, out var else0);

            // if (i % 2 == 0)
            var            binOpNode = GraphModel.CreateBinaryOperatorNode(BinaryOperatorKind.Modulo, Vector2.zero);
            IVariableModel varI      = GraphModel.CreateVariableNode(paramI, Vector2.left);
            var            const2    = CreateConstantIntNode(2);

            GraphModel.CreateEdge(binOpNode.InputPortA, varI.OutputPort);
            GraphModel.CreateEdge(binOpNode.InputPortB, const2.OutputPort);
            var equalNode = GraphModel.CreateBinaryOperatorNode(BinaryOperatorKind.Equals, Vector2.zero);
            var const0    = CreateConstantIntNode(0);

            GraphModel.CreateEdge(equalNode.InputPortA, binOpNode.OutputPort);
            GraphModel.CreateEdge(equalNode.InputPortB, const0.OutputPort);
            GraphModel.CreateEdge(if0.IfPort, equalNode.OutputPort);

            // then return true
            var returnTrue = then0.CreateStackedNode <ReturnNodeModel>("return true");
            var constTrue  = CreateConstantBoolNode(true);

            GraphModel.CreateEdge(returnTrue.InputPort, constTrue.OutputPort);

            // else return false
            var returnFalse = else0.CreateStackedNode <ReturnNodeModel>("return false");
            var constFalse  = CreateConstantBoolNode(false);

            GraphModel.CreateEdge(returnFalse.InputPort, constFalse.OutputPort);
            return(method);
        }
        public static IEnumerable <SyntaxNode> BuildIfCondition(this RoslynTranslator translator, IfConditionNodeModel statement, IPortModel portModel)
        {
            // this enables more elegant code generation with no duplication
            // if() { then(); } else { else(); }
            // codeAfterIf();
            // instead of duplicating the code after the if in each branch
            // find first stack reachable from both then/else stacks

            var endStack = RoslynTranslator.FindConnectedStacksCommonDescendant(statement);

            if (endStack != null)
            {
                // building the branches will stop at the common descendant
                translator.EndStack = endStack;
                // Debug.Log($"If in stack {statement.parentStackModel} Common descendant: {endStack}");
            }

            // ie. follow outputs, find all stacks with multiple inputs, compare them until finding the common one if it exists
            // BuildStack checks the m_EndStack field, returning when recursing on it
            // the parent buildStack call will then continue on this end stack

            StatementSyntax syntax = null;

            // construct multiple if else if else ... from right to left, starting with the last else
            foreach (var conditionWithAction in statement.ConditionsWithActionsPorts.Reverse())
            {
                var         stack = RoslynTranslator.GetConnectedStack(conditionWithAction.Action);
                BlockSyntax block = SyntaxFactory.Block();
                if (endStack == null || endStack != stack) // stop before the end stack
                {
                    translator.BuildStack(stack, ref block, StackExitStrategy.Inherit);
                }
                if (conditionWithAction.Condition == null) // last else
                {
                    syntax = block;
                }
                else // if = if() { current statement } else { prev statement that might be an if }
                {
                    var condition = (ExpressionSyntax)translator.BuildPort(conditionWithAction.Condition).SingleOrDefault();
                    syntax = SyntaxFactory.IfStatement(condition, block)
                             .WithElse(SyntaxFactory.ElseClause(syntax));
                }
            }

            yield return(syntax);
        }
Exemplo n.º 4
0
        public static IEnumerable <SyntaxNode> BuildIfCondition(this RoslynEcsTranslator translator, IfConditionNodeModel statement, IPortModel portModel)
        {
            // TODO: de-duplicate code after if stacks
            var firstThenStack = RoslynTranslator.GetConnectedStack(statement, 0);
            var firstElseStack = RoslynTranslator.GetConnectedStack(statement, 1);

            // this enables more elegant code generation with no duplication
            // find first stack reachable from both then/else stacks
            var endStack = RoslynTranslator.FindCommonDescendant(firstThenStack, firstElseStack);

            if (endStack != null)
            {
//                Debug.Log($"If in stack {statement.parentStackModel} Common descendant: {endStack}");
                // building the branches will stop at the common descendant
                translator.EndStack = endStack;
            }

            // ie. follow outputs, find all stacks with multiple inputs, compare them until finding the common one if it exists
            // BuildStack should take an abort stack parameter, returning when recursing on it
            // the parent buildStack call will then continue on this end stack

            var thenBlock = Block();

            if (endStack != firstThenStack)
            {
                translator.BuildStack(firstThenStack, ref thenBlock, StackExitStrategy.Inherit);
            }

            var elseBlock = Block();

            if (endStack != firstElseStack)
            {
                translator.BuildStack(firstElseStack, ref elseBlock, StackExitStrategy.Inherit);
            }

            var ifNode = RoslynBuilder.IfStatement(
                translator.BuildPort(statement.IfPort).SingleOrDefault(),
                thenBlock,
                elseBlock);

            yield return(ifNode);
        }
 public static GraphElement CreateIfConditionNode(this INodeBuilder builder, Store store, IfConditionNodeModel model)
 {
     return(new IfConditionNode(model, store, builder.GraphView));
 }
        void BuildIfConditionNode(IfConditionNodeModel node, RoslynEcsTranslator translator, int stateIndex)
        {
            translator.BuildNode(node);

            var firstThenStack = RoslynTranslator.GetConnectedStack(node, 0);
            var firstElseStack = RoslynTranslator.GetConnectedStack(node, 1);
            var ifState        = m_States[stateIndex];
            var ifIndex        = GetCurrentStateIndex();

            var endStackIndex = 0;

            if (translator.EndStack != null)
            {
                m_StackIndexes.TryGetValue(translator.EndStack, out endStackIndex);
            }

            // Reserve then/else/complete states first
            var       thenIndex = ifIndex;
            var       thenBlock = Block().AddStatements(ReturnStatement(LiteralExpression(SyntaxKind.FalseLiteralExpression)));
            StateData thenState = null;

            if (firstThenStack != null)
            {
                if (firstThenStack == translator.EndStack && endStackIndex != 0)
                {
                    thenBlock = Block().AddStatements(BuildGoToState(endStackIndex));
                }
                else
                {
                    thenIndex += 1;
                    thenState  = RequestNewState();
                    TryAddStackIndex(firstThenStack, thenIndex);
                    thenBlock = Block().AddStatements(BuildGoToState(thenIndex));
                }
            }

            var       elseIndex = thenIndex + 1;
            var       elseBlock = Block().AddStatements(ReturnStatement(LiteralExpression(SyntaxKind.FalseLiteralExpression)));
            StateData elseState = null;

            if (firstElseStack != null)
            {
                if (firstElseStack == translator.EndStack && endStackIndex != 0)
                {
                    elseBlock = Block().AddStatements(BuildGoToState(endStackIndex));
                }
                else
                {
                    elseState = RequestNewState();
                    TryAddStackIndex(firstElseStack, elseIndex);
                    elseBlock = Block().AddStatements(BuildGoToState(elseIndex));
                }
            }

            // Then Build stacks
            ifState.Statements.Add(RoslynBuilder.IfStatement(
                                       translator.BuildPort(node.IfPort).SingleOrDefault(),
                                       thenBlock,
                                       elseBlock)
                                   .WithAdditionalAnnotations(
                                       new SyntaxAnnotation(Annotations.VSNodeMetadata, node.Guid.ToString())));
            ifState.Statements.Add(ReturnStatement(LiteralExpression(SyntaxKind.TrueLiteralExpression)));
            ifState.SkipStateBuilding = true;

            var reserveEndStackState = translator.EndStack != null &&
                                       translator.EndStack != firstElseStack &&
                                       translator.EndStack != firstThenStack &&
                                       endStackIndex == 0;

            if (reserveEndStackState)
            {
                var endState = RequestNewState();
                endState.NextStateIndex = GetNextStateIndex(translator.EndStack);
                TryAddStackIndex(translator.EndStack, GetCurrentStateIndex());
            }

            var origBuiltStacks = translator.BuiltStacks;

            translator.BuiltStacks = new HashSet <IStackModel>(origBuiltStacks);

            if (translator.EndStack != firstThenStack)
            {
                if (translator.EndStack != null && thenState != null)
                {
                    thenState.NextStateIndex = m_StackIndexes[translator.EndStack];
                }
                BuildStack(translator, firstThenStack, thenIndex, StackExitStrategy.Inherit);
            }

            var partialStacks = translator.BuiltStacks;

            translator.BuiltStacks = new HashSet <IStackModel>(origBuiltStacks);

            if (translator.EndStack != firstElseStack)
            {
                if (translator.EndStack != null && elseState != null)
                {
                    elseState.NextStateIndex = m_StackIndexes[translator.EndStack];
                }
                BuildStack(translator, firstElseStack, elseIndex, StackExitStrategy.Inherit);
            }

            translator.BuiltStacks.UnionWith(partialStacks);
        }