public IEnumerable <SyntaxNode> SetComponent(TranslationContext context, ExpressionSyntax entity,
                                                     Type componentType, ExpressionSyntax componentDeclaration)
        {
            var type         = TypeSystem.BuildTypeSyntax(componentType);
            var expressionId = typeof(ISharedComponentData).IsAssignableFrom(componentType)
                ? nameof(EntityCommandBuffer.Concurrent.SetSharedComponent)
                : nameof(EntityCommandBuffer.Concurrent.SetComponent);

            yield return(RoslynBuilder.MethodInvocation(
                             expressionId,
                             context.GetOrDeclareCommandBuffer(true),
                             m_Concurrent
                ? new[]
            {
                Argument(IdentifierName(context.GetJobIndexParameterName())),
                Argument(entity),
                Argument(componentDeclaration)
            }
                : new[]
            {
                Argument(entity),
                Argument(componentDeclaration)
            },
                             new[] { type }));
        }
        public static IEnumerable <SyntaxNode> BuildFunctionCall(this RoslynTranslator translator, FunctionCallNodeModel call, IPortModel portModel)
        {
            if (call.MethodInfo == null)
            {
                yield break;
            }

            var instance = BuildArgumentList(translator, call, out var argumentList);

            var typeArgumentList = new List <TypeSyntax>();

            if (call.MethodInfo.IsGenericMethod)
            {
                foreach (var typeArgument in call.TypeArguments)
                {
                    typeArgumentList.Add(TypeSystem.BuildTypeSyntax(typeArgument.Resolve(translator.Stencil)));
                }
            }

            TypeArgumentListSyntax typeArgList = null;

            if (typeArgumentList.Any())
            {
                typeArgList = SyntaxFactory.TypeArgumentList(SyntaxFactory.SingletonSeparatedList(typeArgumentList.First()));
            }

            SyntaxNode method = RoslynBuilder.MethodInvocation(call.Title, call.MethodInfo, instance, argumentList, typeArgList);

            yield return(method);
        }
示例#3
0
        IEnumerable <MemberDeclarationSyntax> BuildComponentMembers(RoslynTranslator translator)
        {
            var states     = new List <SwitchSectionSyntax>();
            var variables  = new Dictionary <string, FieldDeclarationSyntax>();
            var stateIndex = 0;

            // Add members (MoveNext + variables) from coroutine nodes in stack
            var stack = Parent.IterationContext.Query;

            BuildStack(translator, stack, ref variables, ref states, ref stateIndex);

            // Fields
            var members = new List <MemberDeclarationSyntax>
            {
                RoslynBuilder.DeclareField(
                    typeof(int),
                    RoslynEcsBuilder.CoroutineStateVariableName,
                    AccessibilityFlags.Private)
            };

            members.AddRange(variables.Values);

            // Parameters + Arguments
            foreach (var component in m_AccessedComponents)
            {
                var componentName = GetComponentVariableName(IterationContext.Query, component);
                var componentType = component.Resolve(IterationContext.Stencil);

                m_Parameters.Add(
                    Argument(IdentifierName(componentName))
                    .WithRefOrOutKeyword(Token(SyntaxKind.RefKeyword)),
                    Parameter(Identifier(componentName))
                    .WithModifiers(TokenList(Token(SyntaxKind.RefKeyword)))
                    .WithType(TypeSystem.BuildTypeSyntax(componentType)));
            }

            foreach (var localVariable in IterationContext.Query.FunctionVariableModels)
            {
                m_Parameters.Add(
                    Argument(IdentifierName(localVariable.Name)),
                    Parameter(Identifier(localVariable.Name))
                    .WithType(TypeSystem.BuildTypeSyntax(localVariable.DataType.Resolve(IterationContext.Stencil))));
            }

            // Create MoveNext method
            members.Add(
                RoslynBuilder.DeclareMethod(k_MoveNext, AccessibilityFlags.Public, typeof(bool))
                .WithParameterList(
                    ParameterList(SeparatedList(m_Parameters.Values)))
                .WithBody(
                    Block(
                        SwitchStatement(IdentifierName(RoslynEcsBuilder.CoroutineStateVariableName))
                        .WithOpenParenToken(Token(SyntaxKind.OpenParenToken))
                        .WithCloseParenToken(Token(SyntaxKind.CloseParenToken))
                        .WithSections(List(states)),
                        ReturnStatement(
                            LiteralExpression(SyntaxKind.FalseLiteralExpression)))));

            return(members);
        }
示例#4
0
        public override ExpressionSyntax GetCachedValue(string key, ExpressionSyntax value, TypeHandle type,
                                                        params IdentifierNameSyntax[] attributes)
        {
            var constant = base.GetCachedValue(key, value, type, attributes);

            // Use the same identifier as the parentJob. This avoid things like myCoroutine.FixedTime0 = FixedTime
            var variableName = constant is IdentifierNameSyntax ins
                ? ins.Identifier.Text
                : key.Replace(".", "_");

            var found = m_Parameters.FirstOrDefault(p => p.Value.Identifier.Text.Equals(variableName));

            if (found.Value != null)
            {
                return(IdentifierName(found.Value.Identifier));
            }

            var param = Parameter(Identifier(variableName))
                        .WithType(TypeSystem.BuildTypeSyntax(type.Resolve(IterationContext.Stencil)));

            if (attributes.Any())
            {
                param.AddAttributeLists(AttributeList(SeparatedList(attributes.Select(Attribute))));
            }

            m_Parameters.Add(Argument(constant), param);

            return(IdentifierName(param.Identifier));
        }
        public static IEnumerable <SyntaxNode> Build(
            this RoslynEcsTranslator translator,
            GetSingletonNodeModel model)
        {
            if (model.ComponentType == TypeHandle.Unknown)
            {
                yield break;
            }

            var singletonType = model.ComponentType.Resolve(translator.Stencil);
            var typeArguments = TypeArgumentList(SingletonSeparatedList(TypeSystem.BuildTypeSyntax(singletonType)));

            var bindingFlags = BindingFlags.Public | BindingFlags.Instance;
            var methodInfo   = typeof(EntityQuery).GetMethod(nameof(EntityQuery.GetSingleton), bindingFlags)
                               ?.GetGenericMethodDefinition()
                               .MakeGenericMethod(singletonType);


            var method = RoslynBuilder.MethodInvocation(
                nameof(EntityQuery.GetSingleton),
                methodInfo,
                InvocationExpression(
                    IdentifierName("GetEntityQuery"))
                .WithArgumentList(
                    ArgumentList(
                        SingletonSeparatedList(
                            Argument(TypeOfExpression(singletonType.ToTypeSyntax()))))),
                new List <ArgumentSyntax>(),
                typeArguments) as ExpressionSyntax;

            yield return(method);
        }
        public override ExpressionSyntax GetSingletonVariable(IVariableDeclarationModel variable)
        {
            var ext = Parent.GetSingletonVariable(variable);

            if (!HasParameter(RootContext.SingletonVariableName))
            {
                // If not jobContext (readOnly access) we have to pass the singleton component as reference
                if (IsJobContext)
                {
                    m_Parameters.Add(
                        Argument(ext),
                        Parameter(Identifier(((IdentifierNameSyntax)ext).Identifier.Text))
                        .WithType(TypeSystem.BuildTypeSyntax(variable.DataType.Resolve(IterationContext.Stencil))));
                }
                else
                {
                    m_Parameters.Add(
                        Argument(IdentifierName(RootContext.SingletonVariableName))
                        .WithRefOrOutKeyword(Token(SyntaxKind.RefKeyword)),
                        Parameter(Identifier(RootContext.SingletonVariableName))
                        .WithModifiers(TokenList(Token(SyntaxKind.RefKeyword)))
                        .WithType(IdentifierName(RootContext.SingletonComponentTypeName)));
                }
            }

            return(ext);
        }
        public static IEnumerable <SyntaxNode> BuildGetComponent(this RoslynEcsTranslator translator, GetOrCreateComponentNodeModel model, IPortModel portModel)
        {
            var entity = translator.BuildPort(model.EntityPort).First() as ExpressionSyntax;

            TypeSyntax componentType = TypeSystem.BuildTypeSyntax(model.ComponentType.Resolve(translator.Stencil));

            yield return(InvocationExpression(
                             MemberAccessExpression(
                                 SyntaxKind.SimpleMemberAccessExpression,
                                 IdentifierName(nameof(EntityManager)),
                                 GenericName(
                                     Identifier(model.CreateIfNeeded ? nameof(EcsHelper.GetOrCreateComponentData) : nameof(EntityManager.GetComponentData)))
                                 .WithTypeArgumentList(
                                     TypeArgumentList(
                                         SingletonSeparatedList(
                                             componentType
                                             )
                                         )
                                     )
                                 )
                             )
                         .WithArgumentList(
                             ArgumentList(
                                 SingletonSeparatedList(
                                     Argument(
                                         entity)))));
        }
示例#8
0
        public override string GetOrDeclareComponentArray(RoslynEcsTranslator.IterationContext ctx,
                                                          ComponentDefinition componentDefinition, out LocalDeclarationStatementSyntax arrayInitialization,
                                                          out StatementSyntax arrayDisposal)
        {
            var declaration = Parent.GetOrDeclareComponentArray(
                ctx,
                componentDefinition,
                out arrayInitialization,
                out arrayDisposal);
            var parameter = declaration.ToCamelCase();

            if (!(Parent is JobContext) || m_DeclaredComponentArray.Contains(componentDefinition))
            {
                return(parameter);
            }

            var componentType = componentDefinition.TypeHandle.Resolve(ctx.Stencil);
            var arrayType     = typeof(NativeArray <>).MakeGenericType(componentType);

            m_Parameters.Add(
                Argument(IdentifierName(declaration)),
                Parameter(Identifier(parameter))
                .WithType(TypeSystem.BuildTypeSyntax(arrayType)));
            m_DeclaredComponentArray.Add(componentDefinition);

            return(parameter);
        }
 public static MethodDeclarationSyntax DeclareMethod(string name, AccessibilityFlags accessibility,
                                                     Type returnValueType)
 {
     return(SyntaxFactory.MethodDeclaration(
                TypeSystem.BuildTypeSyntax(returnValueType),
                SyntaxFactory.Identifier(name))
            .WithModifiers(SyntaxFactory.TokenList(AccessibilityToSyntaxToken(accessibility).ToArray())));
 }
示例#10
0
        public override string GetJobIndexParameterName()
        {
            var declaration = Parent.GetJobIndexParameterName();
            var parameter   = declaration.ToCamelCase();

            m_Parameters.Add(
                Argument(IdentifierName(declaration)),
                Parameter(Identifier(parameter)).WithType(TypeSystem.BuildTypeSyntax(typeof(int))));

            return(parameter);
        }
 internal static StructDeclarationSyntax DeclareComponent(string componentName, Type componentType,
                                                          IEnumerable <MemberDeclarationSyntax> members = null)
 {
     return(StructDeclaration(componentName)
            .WithModifiers(
                TokenList(
                    Token(SyntaxKind.PublicKeyword)))
            .WithBaseList(
                BaseList(
                    SingletonSeparatedList <BaseTypeSyntax>(
                        SimpleBaseType(TypeSystem.BuildTypeSyntax(componentType)))))
            .WithMembers(List(members)));
 }
        public override string GetJobIndexParameterName()
        {
            var declaration = Parent.GetJobIndexParameterName();

            if (!HasParameter(declaration))
            {
                m_Parameters.Add(
                    Argument(IdentifierName(declaration)),
                    Parameter(Identifier(declaration)).WithType(TypeSystem.BuildTypeSyntax(typeof(int))));
            }

            return(declaration);
        }
        public override void RecordEntityAccess(IVariableDeclarationModel model)
        {
            Parent.RecordEntityAccess(model);

            if (HasParameter(model.Name))
            {
                return;
            }

            m_Parameters.Add(
                Argument(IdentifierName(model.Name)),
                Parameter(Identifier(model.Name))
                .WithType(TypeSystem.BuildTypeSyntax(typeof(Entity))));
        }
        protected IEnumerable <MemberDeclarationSyntax> BuildComponentMembers()
        {
            // Fields
            var members = new List <MemberDeclarationSyntax>
            {
                RoslynBuilder.DeclareField(
                    typeof(int),
                    k_CoroutineStateVariableName,
                    AccessibilityFlags.Public)
            };

            members.AddRange(m_ComponentVariables.Values);

            foreach (var component in m_AccessedComponents)
            {
                var componentName = GetComponentVariableName(IterationContext.Query, component);
                var componentType = component.Resolve(IterationContext.Stencil);

                m_Parameters.Add(
                    Argument(IdentifierName(componentName))
                    .WithRefOrOutKeyword(Token(SyntaxKind.RefKeyword)),
                    Parameter(Identifier(componentName))
                    .WithModifiers(TokenList(Token(SyntaxKind.RefKeyword)))
                    .WithType(TypeSystem.BuildTypeSyntax(componentType)));
            }

            foreach (var localVariable in IterationContext.Query.FunctionVariableModels)
            {
                m_Parameters.Add(
                    Argument(IdentifierName(localVariable.Name)),
                    Parameter(Identifier(localVariable.Name))
                    .WithType(TypeSystem.BuildTypeSyntax(localVariable.DataType.Resolve(IterationContext.Stencil))));
            }

            if ((TranslationOptions & RoslynEcsTranslator.TranslationOptions.Tracing) != 0)
            {
                m_Parameters.Add(
                    Argument(GetRecorderName())
                    .WithRefOrOutKeyword(Token(SyntaxKind.RefKeyword)),
                    Parameter(GetRecorderName().Identifier)
                    .WithModifiers(SyntaxTokenList.Create(Token(SyntaxKind.RefKeyword)))
                    .WithType((IsJobContext ? typeof(GraphStream.Writer) : typeof(DebuggerTracer.EntityFrameTrace))
                              .ToTypeSyntax()));
            }

            return(members);
        }
示例#15
0
        public override IdentifierNameSyntax GetEventBufferWriter(RoslynEcsTranslator.IterationContext iterationContext,
                                                                  ExpressionSyntax entity, Type eventType, out StatementSyntax bufferInitialization)
        {
            var declaration = Parent.GetEventBufferWriter(iterationContext, entity, eventType, out bufferInitialization);
            var parameter   = declaration.Identifier.Text.ToCamelCase();

            m_Parameters.Add(
                Argument(declaration),
                Parameter(Identifier(parameter))
                .WithType(
                    GenericName(Identifier("DynamicBuffer"))
                    .WithTypeArgumentList(
                        TypeArgumentList(
                            SingletonSeparatedList(TypeSystem.BuildTypeSyntax(eventType))))));

            return(IdentifierName(parameter));
        }
        public override IdentifierNameSyntax GetOrDeclareCommandBuffer(bool isConcurrent)
        {
            var declaration = Parent.GetOrDeclareCommandBuffer(isConcurrent);
            var name        = declaration.Identifier.Text;

            if (!HasParameter(name))
            {
                var parameter = IdentifierName(name);
                var cmdType   = declaration.Identifier.Text != nameof(ComponentSystem.PostUpdateCommands)
                    ? typeof(EntityCommandBuffer.Concurrent)
                    : typeof(EntityCommandBuffer);
                m_Parameters.Add(
                    Argument(IdentifierName(declaration.Identifier)),
                    Parameter(parameter.Identifier).WithType(TypeSystem.BuildTypeSyntax(cmdType)));
            }

            return(declaration);
        }
        public IEnumerable <SyntaxNode> SetComponent(TranslationContext context, ExpressionSyntax entity,
                                                     Type componentType, ExpressionSyntax componentDeclaration)
        {
            var type         = TypeSystem.BuildTypeSyntax(componentType);
            var expressionId = typeof(ISharedComponentData).IsAssignableFrom(componentType)
                ? nameof(EntityManager.SetSharedComponentData)
                : nameof(EntityManager.SetComponentData);

            yield return(RoslynBuilder.MethodInvocation(
                             expressionId,
                             IdentifierName(nameof(EntityManager)),
                             new[]
            {
                Argument(entity),
                Argument(componentDeclaration)
            },
                             new[] { type }));
        }
        public static List <ParameterSyntax> BuildArguments(Stencil stencil, IFunctionModel stack)
        {
            var argumentNodes = new List <ParameterSyntax>();

            foreach (var paramDecl in stack.FunctionParameterModels)
            {
                switch (paramDecl.VariableType)
                {
                case VariableType.FunctionParameter:
                    argumentNodes.Add(SyntaxFactory.Parameter(
                                          SyntaxFactory.Identifier(paramDecl.Name))
                                      .WithType(
                                          TypeSystem.BuildTypeSyntax(paramDecl.DataType.Resolve(stencil))));
                    break;
                }
            }

            return(argumentNodes);
        }
        public IEnumerable <SyntaxNode> GetComponent(TranslationContext context, ExpressionSyntax entity,
                                                     Type componentType)
        {
            var type = TypeSystem.BuildTypeSyntax(componentType);

            context.RecordComponentAccess(
                context.IterationContext,
                componentType.GenerateTypeHandle(context.IterationContext.Stencil),
                RoslynEcsTranslator.AccessMode.Read);
            var expressionId = typeof(ISharedComponentData).IsAssignableFrom(componentType)
                ? nameof(EntityManager.GetSharedComponentData)
                : nameof(EntityManager.GetComponentData);

            yield return(RoslynBuilder.MethodInvocation(
                             expressionId,
                             IdentifierName(nameof(EntityManager)),
                             new[] { Argument(entity) },
                             new[] { type }));
        }
示例#20
0
        protected override StatementSyntax GetOrDeclareEntityArray(RoslynEcsTranslator.IterationContext context,
                                                                   out StatementSyntax arrayDisposal)
        {
            if (Parent is JobContext)
            {
                m_Parameters.Add(
                    Argument(IdentifierName(context.EntitiesArrayName)),
                    Parameter(Identifier(context.EntitiesArrayName))
                    .WithType(TypeSystem.BuildTypeSyntax(typeof(NativeArray <Entity>))));
            }
            else
            {
                m_Parameters.Add(
                    Argument(IdentifierName(context.GroupName)),
                    Parameter(Identifier(context.GroupName))
                    .WithType(TypeSystem.BuildTypeSyntax(typeof(EntityQuery))));
            }

            return(base.GetOrDeclareEntityArray(context, out arrayDisposal));
        }
示例#21
0
        public override IdentifierNameSyntax GetOrDeclareCommandBuffer(bool isConcurrent)
        {
            var declaration = Parent.GetOrDeclareCommandBuffer(isConcurrent);
            var parameter   = IdentifierName(declaration.Identifier.Text.ToCamelCase());

            if (m_DeclaredCommandBuffers.Contains(parameter))
            {
                return(parameter);
            }

            var cmdType = isConcurrent && Parent is JobContext
                ? typeof(EntityCommandBuffer.Concurrent)
                : typeof(EntityCommandBuffer);

            m_Parameters.Add(
                Argument(IdentifierName(declaration.Identifier)),
                Parameter(parameter.Identifier).WithType(TypeSystem.BuildTypeSyntax(cmdType)));
            m_DeclaredCommandBuffers.Add(parameter);

            return(parameter);
        }
示例#22
0
 internal static ExpressionSyntax MakeInitComponentDataArrayExpression(
     RoslynEcsTranslator.IterationContext ctx,
     Type componentType)
 {
     return(InvocationExpression(
                MemberAccessExpression(
                    SyntaxKind.SimpleMemberAccessExpression,
                    IdentifierName(ctx.GroupName),
                    GenericName(
                        Identifier("ToComponentDataArray"))
                    .WithTypeArgumentList(
                        TypeArgumentList(
                            SingletonSeparatedList(
                                TypeSystem.BuildTypeSyntax(componentType))))))
            .WithArgumentList(
                ArgumentList(
                    SingletonSeparatedList(
                        Argument(
                            MemberAccessExpression(
                                SyntaxKind.SimpleMemberAccessExpression,
                                IdentifierName(nameof(Allocator)),
                                IdentifierName(ctx.AllocatorType.ToString()))))))
            .NormalizeWhitespace());
 }
示例#23
0
        public virtual ExpressionSyntax Constant(object value, Stencil stencil, Type generatedType = null)
        {
            switch (value)
            {
            case float f:
                return(LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(f)));

            case decimal d:
                return(LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(d)));

            case int i:
                return(LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(i)));

            case double d:
                return(LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(d)));

            case bool b:
                return(LiteralExpression(b ? SyntaxKind.TrueLiteralExpression : SyntaxKind.FalseLiteralExpression));

            case string s:
                return(LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(s)));

            case char c:
                return(LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(c)));

            case Vector2 _:
            case Vector3 _:
            case Vector4 _:
            case Quaternion _:
            case Color _:

                if (generatedType == null)
                {
                    generatedType = value.GetType();
                }
                return(RoslynBuilder.CreateConstantInitializationExpression(value, generatedType));

            case Enum _:
                return(MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                              IdentifierName(value.GetType().Name),
                                              IdentifierName(value.ToString())
                                              ));

            case EnumValueReference e:
                return(MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                              TypeSystem.BuildTypeSyntax(e.EnumType.Resolve(stencil)),
                                              IdentifierName(e.ValueAsEnum(stencil).ToString())
                                              ));

            case AnimationCurve _:
                return(DefaultExpression(TypeSyntaxFactory.ToTypeSyntax(typeof(AnimationCurve))));

            case LayerMask m:
                return(LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(m.value)));

            case InputName inputName:
                return(inputName.name == null
                        ? LiteralExpression(SyntaxKind.NullLiteralExpression)
                        : LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(inputName.name)));

            case SceneAsset asset:
                return(LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(AssetDatabase.GetAssetPath(asset))));

            default:
                return(DefaultExpression(TypeSystem.BuildTypeSyntax(value.GetType())));
            }
        }
示例#24
0
        StructDeclarationSyntax Build()
        {
            if (IterationContext.UpdateMode == UpdateMode.OnEnd)
            {
                throw new RoslynEcsTranslator.JobSystemNotCompatibleException("Exit stacks are not compatible with jobs yet");
            }

            // Todo: disabled at the moment - job scheduling needs to use the enter query which uses an excluded component
            if (IterationContext.UpdateMode == UpdateMode.OnStart)
            {
                throw new RoslynEcsTranslator.JobSystemNotCompatibleException("Enter stacks are not compatible with jobs yet");
            }

            if (m_UpdateSingletonRequested)
            {
                throw new RoslynEcsTranslator.JobSystemNotCompatibleException("Setting a blackboard variable is not compatible with jobs yet");
            }

            var stateComponentName = IterationContext.UpdateMode == UpdateMode.OnUpdate || IterationContext.UpdateMode == UpdateMode.OnEvent
                ? null
                : IncludeTrackingSystemStateComponent(IterationContext.Query.ComponentQueryDeclarationModel, IterationContext.UpdateMode == UpdateMode.OnEnd);

            var functionParameters = new List <ParameterSyntax>
            {
                Parameter(Identifier(EntityName)).WithType(TypeSystem.BuildTypeSyntax(typeof(Entity))),
                Parameter(Identifier(GetJobIndexParameterName())).WithType(PredefinedType(Token(SyntaxKind.IntKeyword)))
            };

            var baseTypeSyntax = MakeJobBaseType(IterationContext, functionParameters, out Type eventType);

            if (baseTypeSyntax == null)
            {
                return(null);
            }
            StructDeclarationSyntax structDeclaration = StructDeclaration(m_JobName);

            if (BurstCompileJobs)
            {
                structDeclaration = structDeclaration.AddAttributeLists(
                    AttributeList().AddAttributes(
                        Attribute(IdentifierName("BurstCompile"))));
            }

            structDeclaration = DeclareExcludedComponents(structDeclaration);

            var makeJobUpdateOverride = MakeJobUpdateOverride(functionParameters, m_UpdateStatements, stateComponentName, eventType);

            structDeclaration = structDeclaration
                                .AddBaseListTypes(baseTypeSyntax)
                                .WithMembers(List(m_MemberDeclarations))
                                .AddMembers(makeJobUpdateOverride);
            return(structDeclaration);

            StructDeclarationSyntax DeclareExcludedComponents(StructDeclarationSyntax declaration)
            {
                if (m_ExcludedComponents.Count == 0)
                {
                    return(declaration);
                }

                List <AttributeArgumentSyntax> componentsToExclude = new List <AttributeArgumentSyntax>();

                foreach (var excludedComponent in m_ExcludedComponents)
                {
                    var arg = AttributeArgument(TypeOfExpression(excludedComponent.ToTypeSyntax(IterationContext.Stencil)));
                    componentsToExclude.Add(arg);
                }

                var syntaxNodes = new SyntaxNodeOrToken[componentsToExclude.Count * 2 - 1];

                syntaxNodes[0] = componentsToExclude[0];
                for (var index = 1; index < componentsToExclude.Count; index++)
                {
                    syntaxNodes[index * 2 - 1] = Token(SyntaxKind.CommaToken);
                    syntaxNodes[index * 2]     = componentsToExclude[index];
                }

                declaration = declaration.AddAttributeLists(
                    AttributeList().AddAttributes(
                        Attribute(IdentifierName("ExcludeComponent"))
                        .WithArgumentList(
                            AttributeArgumentList(SeparatedList <AttributeArgumentSyntax>(syntaxNodes)))));

                return(declaration);
            }
        }
        public static SyntaxNode MethodInvocation(string name, MethodBase methodInfo, SyntaxNode instance, List <ArgumentSyntax> argumentList, TypeArgumentListSyntax typeArgumentList)
        {
            var sepList = SyntaxFactory.SeparatedList(argumentList);

            if (methodInfo == null)
            {
                return(SyntaxFactory.EmptyStatement());
            }

            var  propertyInfos = methodInfo.DeclaringType?.GetProperties();
            var  isSetAccessor = propertyInfos?.FirstOrDefault(prop => prop.GetSetMethod() == methodInfo);
            var  isGetAccessor = propertyInfos?.FirstOrDefault(prop => prop.GetGetMethod() == methodInfo);
            bool isProperty    = isSetAccessor != null || isGetAccessor != null;
            var  methodName    = methodInfo.Name;

            if (isProperty)
            {
                methodName = name.Substring(4);
            }

            bool             isGenericMethod        = methodInfo.IsGenericMethod;
            ExpressionSyntax finalExpressionSyntax  = null;
            ExpressionSyntax memberAccessExpression = instance == null?SyntaxFactory.IdentifierName(methodInfo.DeclaringType?.Name) : instance as ExpressionSyntax;

            if (!isProperty)
            {
                if (methodInfo.IsConstructor)
                {
                    finalExpressionSyntax = SyntaxFactory.ObjectCreationExpression(
                        TypeSystem.BuildTypeSyntax(methodInfo.DeclaringType))
                                            .WithArgumentList(SyntaxFactory.ArgumentList(sepList));
                }
                else
                {
                    SimpleNameSyntax genericName = isGenericMethod
                        ? (SimpleNameSyntax)SyntaxFactory.GenericName(
                        SyntaxFactory.Identifier(methodName))
                                                   .WithTypeArgumentList(typeArgumentList)
                        : SyntaxFactory.IdentifierName(methodName);

                    InvocationExpressionSyntax invocation = SyntaxFactory.InvocationExpression(
                        SyntaxFactory.MemberAccessExpression(
                            SyntaxKind.SimpleMemberAccessExpression,
                            memberAccessExpression,
                            genericName
                            )
                        );
                    finalExpressionSyntax = invocation
                                            .WithArgumentList(SyntaxFactory.ArgumentList(sepList));
                }
            }
            else
            {
                if (isGetAccessor != null)
                {
                    if (isGetAccessor.GetIndexParameters().Length > 0)
                    {
                        finalExpressionSyntax = SyntaxFactory.ElementAccessExpression(
                            memberAccessExpression,
                            SyntaxFactory.BracketedArgumentList(sepList));
                    }
                    else
                    {
                        finalExpressionSyntax = SyntaxFactory.MemberAccessExpression(
                            SyntaxKind.SimpleMemberAccessExpression,
                            memberAccessExpression,
                            SyntaxFactory.IdentifierName(methodName));
                    }
                }
                else if (isSetAccessor != null)
                {
                    ExpressionSyntax left;
                    if (isSetAccessor.GetIndexParameters().Length > 0)
                    {
                        left = SyntaxFactory.ElementAccessExpression(memberAccessExpression, SyntaxFactory.BracketedArgumentList(
                                                                         SyntaxFactory.SeparatedList(argumentList.Take(argumentList.Count - 1))
                                                                         ));
                    }
                    else
                    {
                        left = SyntaxFactory.MemberAccessExpression(
                            SyntaxKind.SimpleMemberAccessExpression,
                            memberAccessExpression,
                            SyntaxFactory.IdentifierName(methodName));
                    }

                    finalExpressionSyntax = SyntaxFactory.AssignmentExpression(
                        SyntaxKind.SimpleAssignmentExpression,
                        left,
                        argumentList.Last().Expression);
                }
            }

            return(finalExpressionSyntax);
        }
示例#26
0
        protected override StatementSyntax OnPopContext()
        {
            BlockSyntax forBody = Block();

            var loopIndexName = IterationContext.IndexVariableName;
            List <StatementSyntax> reassignComponentDataArrays = new List <StatementSyntax>();


            BlockSyntax blockSyntax = Block();

            // foreach in a job: the entity array will be declared as a job field, initialized at job creation

            StatementSyntax initEntitiesArray = GetOrDeclareEntityArray(IterationContext, out var disposeEntitiesArray);

            foreach (ComponentDefinition definition in IterationContext.FlattenedComponentDefinitions())
            {
                if (!RoslynEcsTranslatorExtensions.ShouldGenerateComponentAccess(definition.TypeHandle, true, out var componentType, IterationContext.Stencil, out bool isShared, out bool isGameObjectComponent) ||
                    isGameObjectComponent)
                {
                    continue;
                }

                if (!m_WrittenComponents.TryGetValue(definition.TypeHandle, out var mode))
                {
                    mode = RoslynEcsTranslator.AccessMode.None;
                }

                if (mode == RoslynEcsTranslator.AccessMode.None)
                {
                    continue;
                }

                ExpressionSyntax initValue;
                if (isShared)
                {
                    initValue = InvocationExpression(
                        MemberAccessExpression(
                            SyntaxKind.SimpleMemberAccessExpression,
                            IdentifierName(nameof(EntityManager)),
                            GenericName(
                                Identifier(nameof(EntityManager.GetSharedComponentData)))
                            .WithTypeArgumentList(
                                TypeArgumentList(
                                    SingletonSeparatedList(
                                        TypeSystem.BuildTypeSyntax(componentType))))))
                                .WithArgumentList(
                        ArgumentList(
                            SingletonSeparatedList(
                                Argument(
                                    IdentifierName(EntityName)))));
                }
                else
                {
                    string compArrayName = GetOrDeclareComponentArray(IterationContext, definition,
                                                                      out var componentDataArrayInitialization,
                                                                      out var componentDataArrayDisposal);
                    if (componentDataArrayInitialization != null)
                    {
                        m_InitComponentDataArrays.Add(componentDataArrayInitialization);
                    }
                    if (componentDataArrayDisposal != null)
                    {
                        m_DisposeComponentDataArrays.Add(componentDataArrayDisposal);
                    }

                    initValue = ElementAccessExpression(IdentifierName(compArrayName))
                                .WithArgumentList(
                        BracketedArgumentList(
                            SingletonSeparatedList(
                                Argument(
                                    IdentifierName(loopIndexName)))));
                }


                // per-entity component variable
                StatementSyntax componentVarDeclaration = RoslynBuilder.DeclareLocalVariable(
                    componentType,
                    IterationContext.GetComponentDataName(componentType),
                    initValue,
                    RoslynBuilder.VariableDeclarationType.InferredType);
                forBody = forBody.AddStatements(componentVarDeclaration);

                if (mode == RoslynEcsTranslator.AccessMode.Write)
                {
                    reassignComponentDataArrays.Add(ExpressionStatement(
                                                        GetEntityManipulationTranslator().SetComponent(
                                                            this,
                                                            ElementAccessExpression(IdentifierName(IterationContext.EntitiesArrayName))
                                                            .WithArgumentList(
                                                                BracketedArgumentList(
                                                                    SingletonSeparatedList(
                                                                        Argument(
                                                                            IdentifierName(IterationContext.IndexVariableName))))),
                                                            componentType,
                                                            IdentifierName(IterationContext.GetComponentDataName(componentType)))
                                                        .Cast <ExpressionSyntax>()
                                                        .Single())
                                                    );
                }
            }

            forBody = forBody.AddStatements(m_UpdateStatements.ToArray());
            forBody = forBody.AddStatements(reassignComponentDataArrays.ToArray());

            if (forBody.Statements.Count != 0) // strip the iteration loop if empty
            {
                forBody = forBody.WithStatements(forBody.Statements.Insert(0, m_EntityDeclaration));

                if (initEntitiesArray != null)
                {
                    blockSyntax = blockSyntax.AddStatements(initEntitiesArray);
                }

                blockSyntax = blockSyntax
                              .AddStatements(m_InitComponentDataArrays.ToArray())
                              .AddStatements(RoslynEcsTranslatorExtensions.ComponentQueryForLoop(forBody, loopIndexName, IterationContext.EntitiesArrayName))
                              .AddStatements(m_DisposeComponentDataArrays.ToArray());

                if (disposeEntitiesArray != null)
                {
                    blockSyntax = blockSyntax.AddStatements(disposeEntitiesArray);
                }
            }

            return(AddMissingEventBuffers(IterationContext, blockSyntax));
        }
示例#27
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))))))));
            }
        }