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 })); }
protected override IEnumerable <StatementSyntax> OnPopContext() { // Build Coroutine MoveNext call statement var block = Block(); // Remove component when coroutine is completed var removeStatement = Parent.GetEntityManipulationTranslator().RemoveComponent( Parent, IdentifierName(Parent.EntityName), m_ComponentTypeName); // TODO Technical Debt : We should be able to RecordComponentAccess with CoroutineComponent to automate this var arguments = m_Parameters.Keys.ToList(); // QUICKFIX : This is ugly. Make a copy to avoid adding extra arguments by the SetComponent in the thenStatement if (Parent.GetType() == typeof(ForEachContext)) { var thenStatement = Block( ExpressionStatement( Parent.GetEntityManipulationTranslator().SetComponent( this, ElementAccessExpression(IdentifierName(IterationContext.EntitiesArrayName)) .WithArgumentList( BracketedArgumentList( SingletonSeparatedList( Argument( IdentifierName(IterationContext.IndexVariableName))))), m_ComponentTypeName, IdentifierName(CoroutineParameterName), false) .Cast <ExpressionSyntax>() .Single())); block = block.AddStatements(IfStatement( RoslynBuilder.MethodInvocation( UpdateMethodName, IdentifierName(GetSystemClassName()), arguments, Enumerable.Empty <TypeSyntax>()), thenStatement) .WithElse( ElseClause(removeStatement.Aggregate(Block(), (c, s) => c.AddStatements(s))))); yield return(block); yield break; } // Call Update block = block.AddStatements(IfStatement( PrefixUnaryExpression( SyntaxKind.LogicalNotExpression, RoslynBuilder.MethodInvocation( UpdateMethodName, IdentifierName(GetSystemClassName()), arguments, Enumerable.Empty <TypeSyntax>())), removeStatement.Aggregate(block, (current, syntax) => current.AddStatements(syntax)))); yield return(block); }
public static IEnumerable <SyntaxNode> BuildFunctionCall(this RoslynEcsTranslator translator, FunctionCallNodeModel call, IPortModel portModel) { if (call.MethodInfo == null) { yield break; } var instance = translator.BuildArgumentList(call, out var argumentList); var typeArgumentList = new List <TypeSyntax>(); if (call.MethodInfo.IsGenericMethod) { typeArgumentList.AddRange(call.TypeArguments.Select(t => IdentifierName(t.GetMetadata(translator.Stencil).Name))); } TypeArgumentListSyntax typeArgList = null; if (typeArgumentList.Any()) { typeArgList = TypeArgumentList(SingletonSeparatedList(typeArgumentList.First())); } var method = RoslynBuilder.MethodInvocation(call.MethodInfo.Name, call.MethodInfo, instance, argumentList, typeArgList); if (method is ExpressionSyntax exp && call.MethodInfo is MethodInfo mi && mi.ReturnType != typeof(void) && call.MethodInfo.DeclaringType.Namespace.StartsWith("UnityEngine")) { var key = call.DeclaringType.Name(translator.Stencil).ToPascalCase() + call.Title.ToPascalCase(); yield return(translator.context.GetCachedValue(key, exp, mi.ReturnType.GenerateTypeHandle(translator.Stencil))); }
protected override StatementSyntax OnPopContext() { var coroutineParameterName = RoslynEcsBuilder.BuildCoroutineParameterName(m_ComponentTypeName); // Build Coroutine MoveNext call statement var block = Block(); // Assign times fields block = block.AddStatements(ExpressionStatement(RoslynBuilder.Assignment( RoslynBuilder.MemberReference( IdentifierName(coroutineParameterName), nameof(ICoroutine.DeltaTime)), Parent.GetOrDeclareDeltaTime()))); // Call MoveNext block = block.AddStatements(IfStatement( RoslynBuilder.MethodInvocation( k_MoveNext, IdentifierName(coroutineParameterName), m_Parameters.Keys, Enumerable.Empty <TypeSyntax>()), ReturnStatement())); // Remove component when coroutine is completed var removeStatement = Parent.GetEntityManipulationTranslator().RemoveComponent( Parent, IdentifierName(Parent.EntityName), m_ComponentTypeName); block = removeStatement.Aggregate(block, (current, syntax) => current.AddStatements(syntax)); return(block); }
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); }
public IEnumerable <StatementSyntax> AddComponent(TranslationContext context, ExpressionSyntax entity, ExpressionSyntax componentDeclaration, TypeSyntax componentTypeSyntax, bool isSharedComponent) { var expressionId = isSharedComponent ? nameof(EntityCommandBuffer.Concurrent.AddSharedComponent) : nameof(EntityCommandBuffer.Concurrent.AddComponent); var arguments = m_Concurrent ? new[] { Argument(IdentifierName(context.GetJobIndexParameterName())), Argument(entity), Argument(componentDeclaration) } : new[] { Argument(entity), Argument(componentDeclaration) }; yield return(ExpressionStatement(RoslynBuilder.MethodInvocation( expressionId, context.GetOrDeclareCommandBuffer(true), arguments, new[] { componentTypeSyntax }))); }
protected override IEnumerable <StatementSyntax> OnPopContext() { var thenStatement = ExpressionStatement(RoslynBuilder.Assignment( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, GetNestedCoroutineField(), IdentifierName(k_CoroutineStateVariableName)), PrefixUnaryExpression( SyntaxKind.UnaryMinusExpression, LiteralExpression( SyntaxKind.NumericLiteralExpression, Literal(1))))); var ifStatement = IfStatement( PrefixUnaryExpression( SyntaxKind.LogicalNotExpression, RoslynBuilder.MethodInvocation( UpdateMethodName, IdentifierName(GetSystemClassName()), m_Parameters.Keys, Enumerable.Empty <TypeSyntax>())), thenStatement); yield return(ifStatement); }
public IEnumerable <SyntaxNode> Instantiate(TranslationContext context, ExpressionSyntax entity) { yield return(RoslynBuilder.MethodInvocation( nameof(EntityManager.Instantiate), IdentifierName(nameof(EntityManager)), new[] { Argument(entity) }, Enumerable.Empty <TypeSyntax>())); }
public IEnumerable <SyntaxNode> CreateEntity(TranslationContext context) { yield return(RoslynBuilder.MethodInvocation( nameof(EntityManager.CreateEntity), IdentifierName(nameof(EntityManager)), Enumerable.Empty <ArgumentSyntax>(), Enumerable.Empty <TypeSyntax>())); }
public IEnumerable <StatementSyntax> RemoveComponent(TranslationContext context, ExpressionSyntax entity, TypeSyntax componentType) { yield return(ExpressionStatement(RoslynBuilder.MethodInvocation( nameof(EntityManager.RemoveComponent), IdentifierName(nameof(EntityManager)), new[] { Argument(entity) }, new[] { componentType }))); }
internal override void RequestSingletonUpdate() { m_SingletonUpdateSyntax = ExpressionStatement( RoslynBuilder.MethodInvocation( SafeGuardNamingSystem.SetSingletonName, null, new[] { Argument(IdentifierName(SingletonVariableName)) }, Enumerable.Empty <TypeSyntax>())); }
public IEnumerable <SyntaxNode> CreateEntity(TranslationContext context) { yield return(RoslynBuilder.MethodInvocation( nameof(EntityCommandBuffer.Concurrent.CreateEntity), context.GetOrDeclareCommandBuffer(true), m_Concurrent ? new[] { Argument(IdentifierName(context.GetJobIndexParameterName())), } : Enumerable.Empty <ArgumentSyntax>(), Enumerable.Empty <TypeSyntax>())); }
public IEnumerable <SyntaxNode> Instantiate(TranslationContext context, ExpressionSyntax entity) { yield return(RoslynBuilder.MethodInvocation( nameof(EntityCommandBuffer.Concurrent.Instantiate), context.GetOrDeclareCommandBuffer(true), m_Concurrent ? new[] { Argument(IdentifierName(context.GetJobIndexParameterName())), Argument(entity) } : new[] { Argument(entity) }, Enumerable.Empty <TypeSyntax>())); }
public IEnumerable <StatementSyntax> AddComponent(TranslationContext context, ExpressionSyntax entity, ExpressionSyntax componentDeclaration, TypeSyntax componentTypeSyntax, bool isSharedComponent) { string expressionId = isSharedComponent ? nameof(EntityManager.AddSharedComponentData) : nameof(EntityManager.AddComponentData); yield return(ExpressionStatement(RoslynBuilder.MethodInvocation( expressionId, IdentifierName(nameof(EntityManager)), new[] { Argument(entity), Argument(componentDeclaration) }, new[] { componentTypeSyntax }))); }
public IEnumerable <SyntaxNode> SetComponent(TranslationContext context, ExpressionSyntax entity, string componentTypeName, ExpressionSyntax componentDeclaration, bool isSharedComponent) { var expressionId = isSharedComponent ? nameof(EntityManager.SetSharedComponentData) : nameof(EntityManager.SetComponentData); yield return(RoslynBuilder.MethodInvocation( expressionId, IdentifierName(nameof(EntityManager)), new[] { Argument(entity), Argument(componentDeclaration) }, new[] { IdentifierName(componentTypeName) })); }
public IEnumerable <StatementSyntax> RemoveComponent(TranslationContext context, ExpressionSyntax entity, string componentName) { yield return(ExpressionStatement(RoslynBuilder.MethodInvocation( nameof(EntityCommandBuffer.Concurrent.RemoveComponent), context.GetOrDeclareCommandBuffer(true), m_Concurrent ? new[] { Argument(IdentifierName(context.GetJobIndexParameterName())), Argument(entity) } : new[] { Argument(entity) }, new[] { IdentifierName(Identifier(componentName)) }))); }
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 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 })); }
public override ExpressionSyntax GetSingletonVariable(IVariableDeclarationModel variable) { if (m_SingletonDeclarationSyntax == null) { var init = RoslynBuilder.MethodInvocation( SafeGuardNamingSystem.GetSingletonName, null, Enumerable.Empty <ArgumentSyntax>(), new[] { IdentifierName(SingletonComponentTypeName) }); m_SingletonDeclarationSyntax = RoslynBuilder.DeclareLocalVariable( SingletonComponentTypeName, SingletonVariableName, init); AddStatement(m_SingletonDeclarationSyntax); } return(MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, IdentifierName(SingletonVariableName), IdentifierName(variable.VariableName))); }
public IEnumerable <SyntaxNode> SetComponent(TranslationContext context, ExpressionSyntax entity, string componentTypeName, ExpressionSyntax componentDeclaration, bool isSharedComponent) { var expressionId = isSharedComponent ? 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[] { IdentifierName(componentTypeName) })); }
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)); } }
public ClassDeclarationSyntax Build(RoslynTranslator translator, VSGraphModel graphModel) { var baseClass = m_NeedToCompleteDependenciesFirst ? nameof(ComponentSystem) : nameof(JobComponentSystem); m_ClassDeclaration = m_ClassDeclaration.WithBaseList( BaseList( SingletonSeparatedList <BaseTypeSyntax>( SimpleBaseType( IdentifierName(baseClass))))); foreach (var queryTracking in m_QueryHasStateTracking) { var trackingMembers = new List <MemberDeclarationSyntax>(); if (queryTracking.Value.Tracking) { trackingMembers.Add( FieldDeclaration( VariableDeclaration( PredefinedType( Token(SyntaxKind.BoolKeyword))) .WithVariables( SingletonSeparatedList( VariableDeclarator( Identifier("Processed"))))) .WithModifiers( TokenList( Token(SyntaxKind.InternalKeyword)))); } DeclareComponent <ISystemStateComponentData>(queryTracking.Value.ComponentName, trackingMembers); } foreach (var eventSystem in m_EventSystems) { // ClearEvents<TestEvent2>.Initialize(World); InitializationStatements.Add(ExpressionStatement(InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, GenericName( Identifier("EventSystem")) .WithTypeArgumentList( TypeArgumentList( SingletonSeparatedList <TypeSyntax>( IdentifierName(eventSystem.FullName)))), IdentifierName("Initialize"))) .WithArgumentList( ArgumentList( SingletonSeparatedList( Argument( IdentifierName("World"))))))); } if ((TranslationOptions & RoslynEcsTranslator.TranslationOptions.Tracing) != 0) { DeclareAndInitField(typeof(TracingRecorderSystem), nameof(TracingRecorderSystem), initValue: InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, IdentifierName("World"), GenericName( Identifier(nameof(World.GetExistingSystem))) .WithTypeArgumentList( TypeArgumentList( SingletonSeparatedList <TypeSyntax>( IdentifierName(nameof(TracingRecorderSystem)))))))); } HashSet <string> declaredQueries = new HashSet <string>(); foreach (var group in m_WrittenComponentsPerGroup) { declaredQueries.Add(group.Key.Query.ComponentQueryDeclarationModel.GetId()); DeclareEntityQueries(group.Value); } // declare unused queries in case there's a Count Entities In Query node somewhere foreach (var graphVariable in graphModel.GraphVariableModels.OfType <ComponentQueryDeclarationModel>().Where(q => !declaredQueries.Contains(q.GetId()))) { var args = graphVariable.Components.Select(c => SyntaxFactory.Argument( InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, IdentifierName("ComponentType"), GenericName( Identifier("ReadOnly")) .WithTypeArgumentList( TypeArgumentList( SingletonSeparatedList <TypeSyntax>( IdentifierName(c.Component.TypeHandle.Resolve(graphModel.Stencil) .FullName)))))) )); var initValue = MakeInitQueryExpression(args); DeclareAndInitField(typeof(EntityQuery), graphVariable.VariableName, initValue: initValue); } var singletonMembers = new List <FieldDeclarationSyntax>(); var initArguments = new List <AssignmentExpressionSyntax>(); foreach (var graphVariable in graphModel.GraphVariableModels .Where(g => g.VariableType == VariableType.GraphVariable)) { singletonMembers.Add(graphVariable.DeclareField(translator, false) .WithAdditionalAnnotations(new SyntaxAnnotation(Annotations.VariableAnnotationKind))); initArguments.Add(RoslynBuilder.Assignment( IdentifierName(graphVariable.VariableName), translator.Constant(graphVariable.InitializationModel.ObjectValue, m_Stencil))); } if (singletonMembers.Any()) { DeclareComponent <IComponentData>(SingletonComponentTypeName, singletonMembers); InitializationStatements.Add(ExpressionStatement( RoslynBuilder.MethodInvocation( nameof(EntityManager.CreateEntity), IdentifierName(nameof(EntityManager)), new[] { Argument(TypeOfExpression(IdentifierName(SingletonComponentTypeName))) }, Enumerable.Empty <TypeSyntax>()))); InitializationStatements.Add( ExpressionStatement( RoslynBuilder.MethodInvocation( SafeGuardNamingSystem.SetSingletonName, null, new[] { Argument(RoslynBuilder.DeclareNewObject( IdentifierName(SingletonComponentTypeName), Enumerable.Empty <ArgumentSyntax>(), initArguments)) }, Enumerable.Empty <TypeSyntax>()))); } // TODO : Remove this once there is real Systems' dependency tool var attributes = new List <AttributeListSyntax>(); foreach (var assetModel in m_Stencil.UpdateAfter.Where(a => a.GraphModel.Stencil is EcsStencil)) { RegisterAttributes <UpdateAfterAttribute>(attributes, assetModel.Name); } foreach (var assetModel in m_Stencil.UpdateBefore.Where(a => a.GraphModel.Stencil is EcsStencil)) { RegisterAttributes <UpdateBeforeAttribute>(attributes, assetModel.Name); } m_ClassDeclaration = m_ClassDeclaration .AddAttributeLists(attributes.ToArray()) .AddMembers(m_ClassMembers.OrderBy(x => x is FieldDeclarationSyntax ? 0 : 1).ToArray()); if (m_InitializationStatements != null) { var onCreateManagerOverride = RoslynBuilder.DeclareMethod( SafeGuardNamingSystem.OnCreateManagerName, AccessibilityFlags.Protected | AccessibilityFlags.Override, typeof(void)); m_ClassDeclaration = m_ClassDeclaration .AddMembers( onCreateManagerOverride.WithBody( Block(m_InitializationStatements))); } if (m_SingletonUpdateSyntax != null) { AddStatement(m_SingletonUpdateSyntax); } var onUpdateBlock = Block(m_UpdateStatements); return(m_ClassDeclaration.AddMembers( RoslynEcsTranslator.MakeOnUpdateOverride( onUpdateBlock, m_NeedToCompleteDependenciesFirst, m_CreatedManagers))); }