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); }
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); } } } }