public SyntaxNode SendEvent(TranslationContext translatorContext, ExpressionSyntax entity, Type eventType, ExpressionSyntax newEventSyntax)
        {
            if (m_Concurrent)
            {
                //throw new RoslynEcsTranslator.JobSystemNotCompatibleException("Sending event in job isn't implemented yet");
            }


            ExpressionSyntax bufferName = translatorContext.GetEventBufferWriter(translatorContext.IterationContext, entity, eventType, out var bufferInitialization);

            if (bufferInitialization != null)
            {
                translatorContext.AddStatement(bufferInitialization);
            }
            // EntityManager.GetBuffer<TestEvent2>(e).Add(<new event syntax>))
            return(InvocationExpression(
                       MemberAccessExpression(
                           SyntaxKind.SimpleMemberAccessExpression,
                           bufferName,
                           IdentifierName("Add")))
                   .WithArgumentList(
                       ArgumentList(
                           SingletonSeparatedList(
                               Argument(
                                   newEventSyntax))))
                   .NormalizeWhitespace());
        }
Пример #2
0
        Microsoft.CodeAnalysis.SyntaxTree GenerateSyntaxTree(VSGraphModel graphModel, CompilationOptions compilationOptions, bool useJobSystem)
        {
            var ecsStencil = (EcsStencil)graphModel.Stencil;

            ecsStencil.ClearComponentDefinitions();

            //TODO fix graph name, do not use the asset name
            var className = graphModel.TypeName;

            TranslationOptions options = TranslationOptions.None;

            if (useJobSystem)
            {
                options |= TranslationOptions.UseJobs;
            }
            if (!compilationOptions.HasFlag(CompilationOptions.LiveEditing))
            {
                options |= TranslationOptions.BurstCompile;
            }

            var rootContext = new RootContext(ecsStencil, className, options);

            context = rootContext;

            List <IFunctionModel> entryPoints = GetEntryPointStacks(graphModel).ToList();

            BuildSpecificStack <PreUpdate>(entryPoints, rootContext);

            foreach (FunctionModel stack in entryPoints.Cast <FunctionModel>().OrderBy(x => x is IOrderedStack orderedStack ? orderedStack.Order : -1))
            {
                if (stack is PreUpdate || stack is PostUpdate)
                {
                    continue;
                }

                IEnumerable <SyntaxNode> entrySyntaxNode = BuildNode(stack);
                foreach (var node in entrySyntaxNode)
                {
                    switch (node)
                    {
                    case null:
                        continue;

                    case StatementSyntax statement:
                        context.AddStatement(statement);
                        break;

                    case MemberDeclarationSyntax member:
                        rootContext.AddMember(member);
                        break;

                    default:
                        Debug.LogError($"Cannot process syntax node type {node.GetType().Name}");
                        break;
                    }
                }
            }

            // TODO: events (see KeyDownEvent)
            // foreach (var statementSyntax in m_EventRegistrations) rootContext.AddStatement(statementSyntax);

            BuildSpecificStack <PostUpdate>(entryPoints, rootContext);

            var referencedNamespaces = new List <string>
            {
                "System",
                "Unity.Burst",
                "Unity.Entities",
                "Unity.Jobs",
                "Unity.Mathematics",
                "Unity.Transforms",
                "Unity.Collections",
                "Microsoft.CSharp",
                "UnityEngine",
            };

            referencedNamespaces = referencedNamespaces.Distinct().ToList();

            var usingList = new List <UsingDirectiveSyntax>();

            foreach (var ns in referencedNamespaces)
            {
                string[] identifiers = ns.Split(".".ToCharArray());

                if (identifiers.Length == 1)
                {
                    usingList.Add(UsingDirective(IdentifierName(identifiers[0])));
                }
                else if (identifiers.Length == 2)
                {
                    usingList.Add(UsingDirective(QualifiedName(IdentifierName(identifiers[0]), IdentifierName(identifiers[1]))));
                }
                else if (identifiers.Length == 3)
                {
                    usingList.Add(UsingDirective(QualifiedName(
                                                     QualifiedName(IdentifierName(identifiers[0]), IdentifierName(identifiers[1])),
                                                     IdentifierName(identifiers[2]))));
                }
            }

            CompilationUnitSyntax compilationUnit = CompilationUnit()
                                                    .WithUsings(
                List(usingList.ToArray()))
                                                    .WithMembers(
                SingletonList <MemberDeclarationSyntax>(rootContext.Build(this, graphModel))).NormalizeWhitespace();

            return(compilationUnit.SyntaxTree);
        }
Пример #3
0
        internal static void BuildCriteria(this IEntityManipulationTranslator self, RoslynEcsTranslator translator,
                                           TranslationContext context, ExpressionSyntax entity, IEnumerable <CriteriaModel> criteriaModels,
                                           StatementSyntax conditionBreak)
        {
            var criteriaList = criteriaModels.ToList();

            if (!criteriaList.Any())
            {
                return;
            }

            ExpressionSyntax ifExpressionSyntax = null;

            foreach (var model in criteriaList)
            {
                ExpressionSyntax finalExpression = null;
                foreach (var criterion in model.Criteria)
                {
                    if (!(criterion is Criterion componentCriterion))
                    {
                        continue;
                    }

                    var rightValue = componentCriterion.Value is ConstantNodeModel constantNodeModel
                        ? translator.Constant(constantNodeModel.ObjectValue, translator.Stencil, constantNodeModel.Type)
                        : IdentifierName(componentCriterion.Value.DeclarationModel.VariableName);

                    var expression = BinaryExpression(
                        componentCriterion.Operator.ToSyntaxKind(),
                        GetLeftValueFromCriterion(self, context, translator.Stencil, entity, componentCriterion),
                        rightValue) as ExpressionSyntax;

                    // TODO : Temporary. Once Unity.Mathematics have IComparable interface, remove this
                    // and use IComparable and IEquatable methods instead of operators
                    var rightValueType = GetRightValueType(componentCriterion, translator.Stencil);
                    if (rightValueType.Namespace != null && rightValueType.Namespace.StartsWith("Unity.Mathematics"))
                    {
                        expression = RoslynBuilder.MethodInvocation(
                            nameof(math.all),
                            typeof(math).ToTypeSyntax(),
                            new[] { Argument(expression) },
                            Enumerable.Empty <TypeSyntax>());
                    }

                    finalExpression = finalExpression == null
                        ? expression
                        : BinaryExpression(SyntaxKind.LogicalAndExpression, finalExpression, expression);
                }

                if (finalExpression == null)
                {
                    continue;
                }
                context.AddStatement(RoslynBuilder.DeclareLocalVariable(
                                         typeof(bool),
                                         model.Name,
                                         finalExpression,
                                         RoslynBuilder.VariableDeclarationType.InferredType));

                var unaryExpression = PrefixUnaryExpression(SyntaxKind.LogicalNotExpression, IdentifierName(model.Name));
                if (model != criteriaList.First())
                {
                    ifExpressionSyntax = BinaryExpression(
                        SyntaxKind.LogicalAndExpression,
                        ifExpressionSyntax,
                        unaryExpression);
                }
                else
                {
                    ifExpressionSyntax = unaryExpression;
                }
            }

            if (ifExpressionSyntax != null)
            {
                BlockSyntax statementSyntax;
                if ((translator.Options & CompilationOptions.Tracing) != 0 && context is JobContext jobContext)
                {
                    statementSyntax = Block(List <SyntaxNode>()
                                            .Add(jobContext.MakeTracingEndForEachIndexStatement())
                                            .Add(conditionBreak));
                }
                else
                {
                    statementSyntax = Block(SingletonList(conditionBreak));
                }
                context.AddStatement(IfStatement(ifExpressionSyntax, statementSyntax));
            }
        }