public static IEnumerable <SyntaxNode> BuildMacroRefNode(this RoslynTranslator translator,
                                                                 MacroRefNodeModel model, IPortModel portModel)
        {
            if (model.Macro == null)
            {
                translator.AddError(
                    model,
                    $"The asset of macro node {model.Title} is missing.");
                return(Enumerable.Empty <SyntaxNode>());
            }

            var variableDeclarations = portModel.Direction == Direction.Input
                ? model.DefinedInputVariables
                : model.DefinedOutputVariables;
            var declaration = variableDeclarations.Single(v => v.VariableName == portModel.UniqueId);

            translator.InMacro.Push(model);
            var variableNodeModel = ((VSGraphModel)declaration.GraphModel)
                                    .FindUsages((VariableDeclarationModel)declaration)
                                    .Single();
            var returnValue = translator.BuildPort(variableNodeModel.OutputPort);

            translator.InMacro.Pop();
            return(returnValue);
        }
Beispiel #2
0
        static void BuildStack(RoslynTranslator translator, IStackModel stack,
                               ref Dictionary <string, FieldDeclarationSyntax> variables, ref List <SwitchSectionSyntax> states,
                               ref int stateIndex)
        {
            translator.RegisterBuiltStack(stack);

            foreach (var node in stack.NodeModels)
            {
                switch (node)
                {
                case IfConditionNodeModel _:
                    translator.AddError(node, "Coroutine (e.g. Wait) and Condition nodes can't coexist within the same stack for now. This feature is coming in a further release");
                    continue;

                case ReturnNodeModel _:
                    translator.AddError(node, "Coroutine (e.g. Wait) and Return nodes can't coexist within the same stack for now. This feature is coming in a further release");
                    continue;
                }

                var blocks = translator.BuildNode(node);
                if (node is CoroutineNodeModel coroutineNode)
                {
                    foreach (var variable in coroutineNode.Fields)
                    {
                        if (variables.ContainsKey(variable.Key))
                        {
                            continue;
                        }

                        variables.Add(variable.Key, variable.Value);
                    }

                    foreach (var block in blocks)
                    {
                        states.Add(SwitchSection()
                                   .WithLabels(
                                       SingletonList <SwitchLabelSyntax>(
                                           CaseSwitchLabel(
                                               LiteralExpression(
                                                   SyntaxKind.NumericLiteralExpression,
                                                   Literal(stateIndex)))))
                                   .WithStatements(
                                       SingletonList(block as StatementSyntax)));

                        stateIndex++;
                    }
                }
                else
                {
                    var statements = new List <StatementSyntax>();
                    foreach (var block in blocks)
                    {
                        switch (block)
                        {
                        case StatementSyntax statementNode:
                            statements.Add(statementNode);
                            break;

                        case ExpressionSyntax expressionNode:
                            statements.Add(
                                ExpressionStatement(expressionNode)
                                .WithAdditionalAnnotations(
                                    new SyntaxAnnotation(Annotations.AnnotationKind,
                                                         node.NodeAssetReference.GetInstanceID().ToString())));
                            break;

                        default:
                            throw new InvalidOperationException("Expected a statement or expression " +
                                                                $"node, found a {node.GetType()} when building {block}");
                        }
                    }

                    states.Add(SwitchSection()
                               .WithLabels(
                                   SingletonList <SwitchLabelSyntax>(
                                       CaseSwitchLabel(
                                           LiteralExpression(
                                               SyntaxKind.NumericLiteralExpression,
                                               Literal(stateIndex)))))
                               .WithStatements(
                                   SingletonList((StatementSyntax)Block(statements)
                                                 .AddStatements(
                                                     RoslynEcsBuilder.BuildCoroutineNextState(),
                                                     ReturnStatement(
                                                         LiteralExpression(SyntaxKind.TrueLiteralExpression))))));

                    stateIndex++;
                }
            }

            foreach (var outputPort in stack.OutputPorts)
            {
                foreach (var connectedStack in outputPort.ConnectionPortModels)
                {
                    if (connectedStack.NodeModel is IStackModel nextStack)
                    {
                        BuildStack(translator, nextStack, ref variables, ref states, ref stateIndex);
                    }
                }
            }
        }