public static void AddHearMarker(CodeGeneratorContext context, CodeStatementCollection statements) { while (context.CodeScope.Peek().GetType() != typeof(CodeTypeDeclaration)) { context.CodeScope.Pop(); } var type = context.CodeScope.Peek() as CodeTypeDeclaration; var count = NumberAsWord(type.Members.OfType <CodeMemberMethod>().Count(m => m.Name.StartsWith("Hear"))); var newMethod = new CodeMemberMethod { Name = "Hear_" + count, Attributes = MemberAttributes.Public | MemberAttributes.Static, ReturnType = CodeConstants.AsyncTask }; newMethod.AddFlowParams(); type.Members.Add(newMethod); context.CodeScope.Push(newMethod); var interactions = type.MethodStatements(CodeConstants.SceneInteractionMethod); var invoke = new CodeMethodInvokeExpression( new CodeTypeReferenceExpression("await " + type.Name), newMethod.Name); invoke.AddFlowParameters(); statements.Add(CodeGeneration_Navigation.EnableCandidate(context.Marker)); interactions.AddInteraction(type.Name, context.Marker, invoke, true); }
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 Begin(Scene scene, CodeGeneratorContext context) { var code = CodeGeneration_Scene.Generate(scene, context); var sceneClass = code.FirstType(); context.SceneFiles.Add(CodeGeneration_Scene.SceneClassName(scene.Name), code); context.CodeScope.Push(sceneClass); context.CodeScope.Push(sceneClass.GetMainMethod()); CodeGeneration_Navigation.RegisterScene(context, scene.Name, new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(sceneClass.Name), CodeConstants.SceneInteractionMethod)); if (scene.Name.Equals(SpecialScenes.Start, StringComparison.OrdinalIgnoreCase)) { context.CreateLaunchRequestHandler(); } return(base.Begin(scene, context)); }
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)); }