Exemple #1
0
        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));
        }