private static Task OutputSceneFiles(Dictionary <string, CodeCompileUnit> scenes, CodeDomProvider csharp, string directoryFullName) { var prependScene = CodeGeneration_Scene.SceneClassName("Global Prepend"); var appendScene = CodeGeneration_Scene.SceneClassName("Global Append"); var prepend = scenes.Any(kvp => kvp.Key.Equals(prependScene, System.StringComparison.OrdinalIgnoreCase)); var append = scenes.Any(kvp => kvp.Key.Equals(appendScene, System.StringComparison.OrdinalIgnoreCase)); return(Task.WhenAll(scenes.Select(async c => { var type = c.Value.FirstType(); if (!type.Name.Equals(prependScene, StringComparison.OrdinalIgnoreCase) && !type.Name.Equals(appendScene, StringComparison.OrdinalIgnoreCase)) { var interaction = c.Value.FirstType().MethodStatements(CodeConstants.SceneInteractionMethod); if (interaction?.OfType <CodeSnippetStatement>().Any() ?? false) { var mainCall = interaction.OfType <CodeSnippetStatement>() .First(ss => ss.Value.EndsWith(CodeConstants.ScenePrimaryMethod.ToLower() + "\":")); var mainInteract = interaction[interaction.IndexOf(mainCall) + 2]; if (prepend) { interaction.Insert(interaction.IndexOf(mainInteract), new CodeExpressionStatement(CodeGeneration_Navigation.GoToScene("global prepend"))); } if (append) { interaction.Insert(interaction.IndexOf(mainInteract) + 1, new CodeExpressionStatement(CodeGeneration_Navigation.GoToScene("global append"))); } } } using (var textWriter = new StreamWriter(File.Open(Path.Combine(directoryFullName, c.Key.Safe()) + ".cs", FileMode.Create, FileAccess.Write))) { csharp.GenerateCodeFromCompileUnit( c.Value, textWriter, new System.CodeDom.Compiler.CodeGeneratorOptions()); await textWriter.FlushAsync(); } }))); }
protected override Task Render(SceneInstruction instruction, CodeGeneratorContext context) { CodeStatementCollection statements; switch (context.CodeScope.Peek()) { case CodeMemberMethod member: statements = member.Statements; break; case CodeTypeDeclaration codeType: statements = codeType.GetMainMethod().Statements; break; case CodeConditionStatement stmt: statements = stmt.TrueStatements; break; default: return(Noop(context)); } CodeGeneration_Instructions.EnsureStateMaintenance(context); switch (instruction) { case Clear clear: statements.Clear(clear.Variable); break; case ClearAll clearAll: statements.ClearAll(); break; case Decrease decrease: statements.Decrease(decrease.Variable, decrease.Amount); break; case Flag flag: statements.SetVariable(flag.Variable, true); break; case GoTo gto: statements.Add(CodeGeneration_Navigation.GoToScene(gto.SceneName)); statements.Add(new CodeMethodReturnStatement()); break; case GoToAndReturn goToAndReturn: statements.Add(CodeGeneration_Navigation.GoToScene(goToAndReturn.SceneName)); break; case Increase increase: statements.Increase(increase.Variable, increase.Amount); break; case Set set: statements.SetVariable(set.Variable, set.Value); break; case SlotAssignment slotAssignment: context.SetSlotType(slotAssignment.SlotName, slotAssignment.SlotType); break; case Unflag unflag: statements.SetVariable(unflag.Variable, false); break; case End end: statements.Reset(); statements.Add(new CodeMethodReturnStatement()); break; case Repeat repeat: statements.Add(new CodeVariableDeclarationStatement(CodeConstants.Var, "lastSpeech", CodeGeneration_Instructions.GetVariable("scene_lastSpeech", typeof(string), false))); statements.Add(new CodeMethodInvokeExpression( new CodeTypeReferenceExpression("Output"), "AddSpeech", CodeConstants.RequestVariableRef, new CodeVariableReferenceExpression("lastSpeech"), new CodePrimitiveExpression(true))); statements.Add(new CodeMethodReturnStatement()); break; case Restart restart: statements.ClearAll("scene_"); statements.ClearAll("_scene"); CodeGeneration_Navigation.GoToScene("start"); statements.Add(new CodeMethodReturnStatement()); break; case Resume resume: statements.Add(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("await Navigation"), "Resume", CodeConstants.RequestVariableRef, new CodePrimitiveExpression(true))); statements.Add(new CodeMethodReturnStatement()); break; case Return returnCmd: statements.Add(new CodeMethodReturnStatement()); break; case Reprompt reprompt: statements.Add(new CodeVariableDeclarationStatement(CodeConstants.Var, "reprompt", CodeGeneration_Instructions.GetVariable("scene_reprompt", typeof(string), false))); statements.Add(new CodeMethodInvokeExpression( new CodeTypeReferenceExpression("Output"), "AddSpeech", CodeConstants.RequestVariableRef, new CodeVariableReferenceExpression("reprompt"), new CodePrimitiveExpression(true))); statements.Add(new CodeMethodReturnStatement()); break; case Back back: statements.Add(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("await Navigation"), "Back", CodeConstants.RequestVariableRef)); statements.Add(new CodeMethodReturnStatement()); break; case Pause pause: statements.Add(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("await Navigation"), "Pause", CodeConstants.RequestVariableRef)); statements.Add(new CodeMethodReturnStatement()); break; } return(base.Render(instruction, context)); }