Example #1
0
        public void OnEventTest([Values] CodeGenMode mode)
        {
            SetupTestGraphMultipleFrames(mode, g =>
            {
                ComponentQueryDeclarationModel query = GraphModel.CreateComponentQuery("g1");
                TypeHandle positionType = typeof(Translation).GenerateTypeHandle(Stencil);
                query.AddComponent(Stencil, positionType, ComponentDefinitionFlags.None);
                IVariableModel queryInstance = GraphModel.CreateVariableNode(query, Vector2.zero);

                TypeHandle eventTypeHandle = typeof(UnitTestEvent).GenerateTypeHandle(Stencil);

                OnEventNodeModel onUpdateModel = GraphModel.CreateNode <OnEventNodeModel>("update", Vector2.zero, SpawnFlags.Default, n => n.EventTypeHandle = eventTypeHandle);

                GraphModel.CreateEdge(onUpdateModel.InstancePort, queryInstance.OutputPort);

                SetPropertyGroupNodeModel set = onUpdateModel.CreateStackedNode <SetPropertyGroupNodeModel>("set", 0);
                var member = new TypeMember(TypeHandle.Float, new List <string> {
                    nameof(Translation.Value), nameof(Translation.Value.x)
                });
                set.AddMember(member);

                IVariableModel posComponent = GraphModel.CreateVariableNode(onUpdateModel.FunctionParameterModels.Single(p => p.DataType == positionType), Vector2.zero);
                GraphModel.CreateEdge(set.InstancePort, posComponent.OutputPort);

                ((FloatConstantModel)set.InputConstantsById[member.GetId()]).value = 2f;
            },

                                         // Add translation to even entities
                                         EachEntity((manager, i, e) =>
            {
                if (e.Index % 2 == 0)
                {
                    manager.AddComponent(e, typeof(Translation));
                }
            }),

                                         // Send event on these
                                         EachEntity(del: (manager, i, e) =>
            {
                if (e.Index % 2 == 0)
                {
                    Assert.That(manager.GetComponentData <Translation>(e).Value.x, Is.EqualTo(0f));
                }
                else
                {
                    Assert.IsFalse(manager.HasComponent <Translation>(e));
                }

                // Add event on all entities
                manager.AddBuffer <UnitTestEvent>(e).Add(new UnitTestEvent());
            }),

                                         // Event handler should set t.x to 2
                                         EachEntity((manager, i, e) =>
            {
                if (e.Index % 2 == 0)
                {
                    Assert.That(manager.GetComponentData <Translation>(e).Value.x, Is.EqualTo(2f));
                }
            }),

                                         // Reset translation
                                         EachEntity((manager, i, e) =>
            {
                if (e.Index % 2 == 0)
                {
                    var t     = manager.GetComponentData <Translation>(e);
                    t.Value.x = 0;
                    manager.SetComponentData(e, t);
                }
            }),

                                         // As we send events manually, the event system is not running and won't cleanup events.
                                         // Event handler should set t.x to 2 again
                                         EachEntity((manager, i, e) =>
            {
                if (e.Index % 2 == 0)
                {
                    Assert.That(manager.GetComponentData <Translation>(e).Value.x, Is.EqualTo(2f));
                }
            })
                                         );
        }
Example #2
0
        BaseTypeSyntax MakeJobBaseType(RoslynEcsTranslator.IterationContext iterationContext, List <ParameterSyntax> functionParameters, out Type eventType)
        {
            var genericArguments = new List <TypeSyntax>();

            eventType = null;
            int componentCount = 0;
            int bufferCount    = 0;

            if (iterationContext.UpdateMode != UpdateMode.OnEnd)
            {
                if (iterationContext.UpdateMode == UpdateMode.OnEvent) // add DynamicBuffer<eventType>
                {
                    eventType = ((OnEventNodeModel)iterationContext.Query).EventTypeHandle.Resolve(iterationContext.Stencil);
                    var eventTypeSyntax = TypeSystem.BuildTypeSyntax(eventType);
                    var bufferType      = GenericName("DynamicBuffer")
                                          .WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(eventTypeSyntax)));
                    var parameterSyntax = Parameter(
                        Identifier(OnEventNodeModel.GetBufferName(eventType)))
                                          .WithType(bufferType);
                    AddReadOnlyAttribute(ref parameterSyntax);

                    bufferCount = 1;

                    functionParameters.Add(parameterSyntax);
                    genericArguments.Add(eventTypeSyntax);
                }


                foreach (ComponentDefinition definition in iterationContext.FlattenedComponentDefinitions().Where(def => !def.Subtract))
                {
                    if (!RoslynEcsTranslatorExtensions.ShouldGenerateComponentAccess(definition.TypeHandle, true, out Type resolvedType, iterationContext.Stencil, out bool isShared, out bool isGameObjectComponent) ||
                        isGameObjectComponent)
                    {
                        continue;
                    }

                    if (isShared)
                    {
                        throw new RoslynEcsTranslator.JobSystemNotCompatibleException("Shared Components are not supported in jobs yet");
                    }

                    genericArguments.Add(TypeSystem.BuildTypeSyntax(resolvedType));
                    var parameterSyntax = Parameter(
                        Identifier(GetComponentVariableName(iterationContext.Query, definition.TypeHandle)))
                                          .WithModifiers(TokenList(Token(SyntaxKind.RefKeyword)))
                                          .WithType(TypeSystem.BuildTypeSyntax(resolvedType));
                    if (!m_WrittenComponents.Contains(definition.TypeHandle))
                    {
                        AddReadOnlyAttribute(ref parameterSyntax);
                    }
                    functionParameters.Add(
                        parameterSyntax);
                    componentCount++;
                }

                if (genericArguments.Count == 0)
                {
                    return(null);
                }
            }

            string CleanGenericName(string s)
            {
                var index = s.IndexOf('`');

                return(index == -1 ? s : s.Substring(0, index));
            }

            // IJobForEachWitEntity_EBBCCC
            string suffix = componentCount > 0 || bufferCount > 0
                ? $"_E{new String('B', bufferCount)}{new String('C', componentCount)}"
                : "";

            return(SimpleBaseType(
                       GenericName(
                           Identifier(CleanGenericName(typeof(IJobForEachWithEntity <>).Name) + suffix))
                       .WithTypeArgumentList(
                           TypeArgumentList(
                               SeparatedList(
                                   genericArguments)))));

            ParameterSyntax AddReadOnlyAttribute(ref ParameterSyntax parameterSyntax)
            {
                return(parameterSyntax = parameterSyntax.WithAttributeLists(
                           SingletonList(
                               AttributeList(
                                   SingletonSeparatedList(
                                       Attribute(
                                           IdentifierName(nameof(ReadOnlyAttribute))))))));
            }
        }
Example #3
0
        MemberDeclarationSyntax MakeJobUpdateOverride(List <ParameterSyntax> functionParameters, List <StatementSyntax> updateStatements, string trackingComponentName, Type eventType)
        {
            var blockSyntax = Block(updateStatements);

            switch (IterationContext.UpdateMode)
            {
            case UpdateMode.OnStart:
                blockSyntax = blockSyntax.AddStatements(GetEntityManipulationTranslator().AddComponent(
                                                            this, IdentifierName(EntityName),
                                                            DefaultExpression(IdentifierName(trackingComponentName)),
                                                            IdentifierName(trackingComponentName),
                                                            false).ToArray());
                break;

            case UpdateMode.OnEvent:
                Assert.IsNotNull(eventType);
                const string eventIndexName   = "event_idx";
                string       eventBufferName  = OnEventNodeModel.GetBufferName(eventType);
                var          eventDeclaration = RoslynBuilder.DeclareLocalVariable(eventType, "ev" /* TODO hardcoded event name*/,
                                                                                   ElementAccessExpression(
                                                                                       IdentifierName(eventBufferName))
                                                                                   .WithArgumentList(
                                                                                       BracketedArgumentList(
                                                                                           SingletonSeparatedList(
                                                                                               Argument(
                                                                                                   IdentifierName(eventIndexName))))));
                blockSyntax = Block(ForStatement(Block(blockSyntax.Statements.Insert(0, eventDeclaration)))
                                    .WithDeclaration(
                                        VariableDeclaration(
                                            PredefinedType(
                                                Token(SyntaxKind.IntKeyword)))
                                        .WithVariables(
                                            SingletonSeparatedList(
                                                VariableDeclarator(
                                                    Identifier(eventIndexName))
                                                .WithInitializer(
                                                    EqualsValueClause(
                                                        LiteralExpression(
                                                            SyntaxKind.NumericLiteralExpression,
                                                            Literal(0)))))))
                                    .WithCondition(
                                        BinaryExpression(
                                            SyntaxKind.LessThanExpression,
                                            IdentifierName(eventIndexName),
                                            MemberAccessExpression(
                                                SyntaxKind.SimpleMemberAccessExpression,
                                                IdentifierName(eventBufferName),
                                                IdentifierName("Length"))))
                                    .WithIncrementors(
                                        SingletonSeparatedList <ExpressionSyntax>(
                                            PostfixUnaryExpression(
                                                SyntaxKind.PostIncrementExpression,
                                                IdentifierName(eventIndexName)))));

                break;
            }

            var executeMethod = MethodDeclaration(
                PredefinedType(
                    Token(SyntaxKind.VoidKeyword)),
                Identifier("Execute"))
                                .WithModifiers(
                TokenList(
                    Token(SyntaxKind.PublicKeyword)))
                                .WithParameterList(
                ParameterList(
                    SeparatedList(functionParameters)))
                                .WithBody(blockSyntax);

            return(executeMethod);
        }
Example #4
0
        MemberDeclarationSyntax MakeJobUpdateOverride(List <ParameterSyntax> functionParameters, List <StatementSyntax> updateStatements, string trackingComponentName, Type eventType)
        {
            var blockSyntax = Block(updateStatements);

            switch (IterationContext.UpdateMode)
            {
            case UpdateMode.OnStart:
                blockSyntax = blockSyntax.AddStatements(GetEntityManipulationTranslator().AddComponent(
                                                            this, IdentifierName(EntityName),
                                                            DefaultExpression(IdentifierName(trackingComponentName)),
                                                            IdentifierName(trackingComponentName),
                                                            false).ToArray());
                break;

            case UpdateMode.OnEvent:
                Assert.IsNotNull(eventType);
                const string eventIndexName   = "event_idx";
                string       eventBufferName  = OnEventNodeModel.GetBufferName(eventType);
                var          eventDeclaration = RoslynBuilder.DeclareLocalVariable(eventType, "ev" /* TODO hardcoded event name*/,
                                                                                   ElementAccessExpression(
                                                                                       IdentifierName(eventBufferName))
                                                                                   .WithArgumentList(
                                                                                       BracketedArgumentList(
                                                                                           SingletonSeparatedList(
                                                                                               Argument(
                                                                                                   IdentifierName(eventIndexName))))));
                blockSyntax = Block(ForStatement(Block(blockSyntax.Statements.Insert(0, eventDeclaration)))
                                    .WithDeclaration(
                                        VariableDeclaration(
                                            PredefinedType(
                                                Token(SyntaxKind.IntKeyword)))
                                        .WithVariables(
                                            SingletonSeparatedList(
                                                VariableDeclarator(
                                                    Identifier(eventIndexName))
                                                .WithInitializer(
                                                    EqualsValueClause(
                                                        LiteralExpression(
                                                            SyntaxKind.NumericLiteralExpression,
                                                            Literal(0)))))))
                                    .WithCondition(
                                        BinaryExpression(
                                            SyntaxKind.LessThanExpression,
                                            IdentifierName(eventIndexName),
                                            MemberAccessExpression(
                                                SyntaxKind.SimpleMemberAccessExpression,
                                                IdentifierName(eventBufferName),
                                                IdentifierName("Length"))))
                                    .WithIncrementors(
                                        SingletonSeparatedList <ExpressionSyntax>(
                                            PostfixUnaryExpression(
                                                SyntaxKind.PostIncrementExpression,
                                                IdentifierName(eventIndexName)))));

                break;
            }

            var executeMethod = MethodDeclaration(
                PredefinedType(
                    Token(SyntaxKind.VoidKeyword)),
                Identifier("Execute"))
                                .WithModifiers(
                TokenList(
                    Token(SyntaxKind.PublicKeyword)))
                                .WithParameterList(
                ParameterList(
                    SeparatedList(functionParameters)))
                                .WithBody(blockSyntax);

            if ((TranslationOptions & RoslynEcsTranslator.TranslationOptions.Tracing) != 0)
            {
                ((SerializableGUID)IterationContext.Query.Guid).ToParts(out var guid1, out var guid2);
                StatementSyntax beginStatement = ExpressionStatement(
                    InvocationExpression(
                        MemberAccessExpression(
                            SyntaxKind.SimpleMemberAccessExpression,
                            m_RecorderJobFieldName,
                            IdentifierName(nameof(GraphStream.Writer.BeginForEachIndex))))
                    .WithArgumentList(
                        ArgumentList(
                            SeparatedList(
                                new[]
                {
                    Argument(IdentifierName(EntityName)),
                    Argument(IdentifierName(GetJobIndexParameterName())),
                    Argument(LiteralExpression(
                                 SyntaxKind.NumericLiteralExpression,
                                 Literal(guid1))),
                    Argument(LiteralExpression(
                                 SyntaxKind.NumericLiteralExpression,
                                 Literal(guid2))),
                }))))
//                    .WithAdditionalAnnotations(Annotations.MakeTracingAnnotation(IterationContext.Query))
                ;
                StatementSyntax endStatement = MakeTracingEndForEachIndexStatement();
                executeMethod = executeMethod.WithBody(executeMethod.Body.WithStatements(executeMethod.Body.Statements.Insert(0, beginStatement).Add(endStatement)));
            }

            return(executeMethod);
        }