public static IEnumerable <SyntaxNode> BuildLoop(this RoslynTranslator translator, LoopNodeModel statement, IPortModel portModel) { IPortModel outputPortModel = statement.OutputPort; if (outputPortModel == null) { yield break; } LoopStackModel loopStackModel = outputPortModel.ConnectionPortModels.FirstOrDefault()?.NodeModel as LoopStackModel; if (loopStackModel == null) { yield break; } foreach (var statementSyntax in translator.BuildNode(loopStackModel)) { yield return(statementSyntax); } }
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); } } } }