Ejemplo n.º 1
0
        public ScriptCSharpGenerator(ScenarioTag scnr, MemberNameRepository nameRepo, string[] refrences = null, AttributeSyntax[] classAttributes = null)
        {
            this.scenario = scnr;
            this.nameRepo = nameRepo;

            var scenarioParts = scnr.Name.Split('\\', StringSplitOptions.RemoveEmptyEntries);

            var ns = "OpenH2.Scripts.Generated" + string.Join(".", scenarioParts.Take(2));

            this.nsDecl = NamespaceDeclaration(ParseName(ns));

            var classModifiers = SyntaxTokenList.Create(Token(SyntaxKind.PublicKeyword))
                                 .Add(Token(SyntaxKind.PartialKeyword));

            this.classDecl = ClassDeclaration("scnr_" + scenarioParts.Last())
                             .WithModifiers(classModifiers);

            if (classAttributes != null && classAttributes.Any())
            {
                var classAttrs = List <AttributeListSyntax>()
                                 .Add(AttributeList(SeparatedList(classAttributes)));

                this.classDecl = this.classDecl.WithAttributeLists(classAttrs);
            }
        }
Ejemplo n.º 2
0
        public void Load(ScenarioTag scnr)
        {
            var scenarioParts = scnr.Name.Split('\\', StringSplitOptions.RemoveEmptyEntries)
                                .Select(p => p.Trim())
                                .ToArray();

            var repo = new MemberNameRepository();

            // Reserve class field and method names

            for (var i = 0; i < scnr.ScriptVariables.Length; i++)
            {
                var variable     = scnr.ScriptVariables[i];
                var returnedName = repo.RegisterName(variable.Description, variable.DataType.ToString(), i);
            }

            for (var i = 0; i < scnr.ScriptMethods.Length; i++)
            {
                var method       = scnr.ScriptMethods[i];
                var returnedName = repo.RegisterName(method.Description, ScriptDataType.ScriptReference.ToString(), i);
            }

            var baseFields = typeof(ScenarioScriptBase).GetFields();

            foreach (var field in baseFields)
            {
                var found = SyntaxUtil.TryGetScriptTypeFromType(field.FieldType, out var t);

                Debug.Assert(found);

                repo.RegisterName(field.Name, t.ToString());
            }

            // Generate data properties

            var dataGen = new ScriptCSharpGenerator(scnr, repo);

            dataGen.AddProperties(scnr);

            dataGen.CreateDataInitializer(scnr);

            var originAttr = SyntaxFactory.Attribute(
                SyntaxFactory.ParseName("OriginScenario"),
                SyntaxFactory.AttributeArgumentList(SyntaxFactory.SeparatedList(new[] {
                SyntaxFactory.AttributeArgument(
                    SyntaxFactory.LiteralExpression(
                        SyntaxKind.StringLiteralExpression,
                        SyntaxFactory.Literal(scnr.Name)))
            })));

            var classGen = new ScriptCSharpGenerator(scnr, repo, classAttributes: new[] { originAttr });

            foreach (var variable in scnr.ScriptVariables)
            {
                classGen.AddGlobalVariable(variable);
            }

            for (int i = 0; i < scnr.ScriptMethods.Length; i++)
            {
                classGen.AddMethod(i, scnr.ScriptMethods[i]);
            }

            this.AddCode($"{scenarioParts.Last()}.cs", classGen.Generate());
            this.AddCode($"{scenarioParts.Last()}.Data.cs", dataGen.Generate());
        }
Ejemplo n.º 3
0
        // Make squads into nested classes
        public void CreateNestedSquadClasses(ScenarioTag tag)
        {
            for (var i = 0; i < tag.AiSquadDefinitions.Length; i++)
            {
                var squad = tag.AiSquadDefinitions[i];

                var squadPropName = nameRepo.RegisterName(squad.Description, ScriptDataType.AI.ToString(), i);

                var dataClassProps = new List <PropertyDeclarationSyntax>();
                dataClassProps.Add(SyntaxUtil.CreateProperty(ParseTypeName(nameof(ScenarioTag)), nameof(ScenarioTag)));

                var nestedRepo = new MemberNameRepository();

                var m = 0;
                foreach (var ai in squad.StartingLocations)
                {
                    var propName = nestedRepo.RegisterName(ai.Description, ScriptDataType.AI.ToString(), m);

                    ExpressionSyntax startingLocationAccess = ElementAccessExpression(
                        MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                               ElementAccessExpression(
                                                   MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                                          IdentifierName(nameof(ScenarioTag)),
                                                                          IdentifierName(nameof(tag.AiSquadDefinitions))))
                                               .AddArgumentListArguments(Argument(SyntaxUtil.LiteralExpression(i))),
                                               IdentifierName(nameof(squad.StartingLocations))))
                                                              .AddArgumentListArguments(Argument(SyntaxUtil.LiteralExpression(m)));

                    dataClassProps.Add(PropertyDeclaration(SyntaxUtil.ScriptTypeSyntax(ScriptDataType.AI), propName)
                                       .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword)))
                                       .WithExpressionBody(ArrowExpressionClause(startingLocationAccess))
                                       .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));

                    m++;
                }

                ExpressionSyntax squadAccess = ElementAccessExpression(
                    MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                           IdentifierName(nameof(ScenarioTag)),
                                           IdentifierName(nameof(tag.AiSquadDefinitions))))
                                               .AddArgumentListArguments(Argument(SyntaxUtil.LiteralExpression(i)));

                // This is so the script can reference the squad itself, need special init handling
                dataClassProps.Add(PropertyDeclaration(SyntaxUtil.ScriptTypeSyntax(ScriptDataType.AI), "Squad")
                                   .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword)))
                                   .WithExpressionBody(ArrowExpressionClause(squadAccess))
                                   .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));

                var squadTypeName = "Squad_" + squadPropName;

                var cls = ClassDeclaration(squadTypeName)
                          .AddModifiers(Token(SyntaxKind.PublicKeyword))
                          .WithMembers(new SyntaxList <MemberDeclarationSyntax>(dataClassProps))
                          .AddMembers(ConstructorDeclaration(squadTypeName)
                                      .AddModifiers(Token(SyntaxKind.PublicKeyword))
                                      .AddParameterListParameters(
                                          Parameter(Identifier(nameof(ScenarioTag)))
                                          .WithType(ParseTypeName(nameof(ScenarioTag))))
                                      .WithBody(Block(new List <StatementSyntax>()
                {
                    ExpressionStatement(AssignmentExpression(SyntaxKind.SimpleAssignmentExpression,
                                                             MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                                                    ThisExpression(),
                                                                                    IdentifierName(nameof(ScenarioTag))),
                                                             IdentifierName(nameof(ScenarioTag))))
                })));

                nestedDataClasses.Add(cls);
                nameRepo.NestedRepos.Add(squadPropName, nestedRepo);

                properties.Add(PropertyDeclaration(ParseTypeName(squadTypeName), squadPropName)
                               .AddModifiers(Token(SyntaxKind.PublicKeyword))
                               .WithAccessorList(SyntaxUtil.AutoPropertyAccessorList()));
            }
        }