public JobContext(IIteratorStackModel query, RootContext parent, UpdateMode mode) : base(parent) { IterationContext = new RoslynEcsTranslator.IterationContext(this, query, parent.MakeUniqueName(query.ComponentQueryDeclarationModel.VariableName), mode); m_JobName = query is OnEventNodeModel onEventNodeModel ? parent.MakeUniqueName($"On_{onEventNodeModel.EventTypeHandle.Name(IterationContext.Stencil)}_Job") : parent.MakeUniqueName($"Update_{IterationContext.GroupName}_Job"); m_ExcludedComponents = new HashSet <TypeHandle>(query.ComponentQueryDeclarationModel.Components.Where(c => c.Component.Subtract) .Select(c => c.Component.TypeHandle)); GetOrDeclareComponentQuery(IterationContext); }
protected override StatementSyntax GetOrDeclareEntityArray(RoslynEcsTranslator.IterationContext iterationContext, out StatementSyntax arrayDisposal) { arrayDisposal = ExpressionStatement( InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, IdentifierName(iterationContext.EntitiesArrayName), IdentifierName(nameof(IDisposable.Dispose))))) .NormalizeWhitespace(); return(RoslynBuilder.DeclareLocalVariable( typeof(NativeArray <Entity>), iterationContext.EntitiesArrayName, ForEachContext.MakeInitEntityArray(iterationContext), RoslynBuilder.VariableDeclarationType.InferredType)); }
public override void RecordComponentAccess(RoslynEcsTranslator.IterationContext query, TypeHandle componentType, RoslynEcsTranslator.AccessMode mode) { if (IterationContext == query) { // if already in write mode, don't downgrade it to read mode if (m_WrittenComponents.TryGetValue(componentType, out var prevMode) && prevMode >= mode) { mode = prevMode; } m_WrittenComponents[componentType] = mode; } // propagate max mode to parent (eg. write), not initial one (eg. read) Parent.RecordComponentAccess(query, componentType, mode); }
protected override StatementSyntax GetOrDeclareEntityArray(RoslynEcsTranslator.IterationContext iterationContext, out StatementSyntax arrayDisposal) { m_MemberDeclarations.Insert(0, AddAttribute( RoslynBuilder.DeclareField( typeof(NativeArray <Entity>), iterationContext.EntitiesArrayName, AccessibilityFlags.Public), nameof(DeallocateOnJobCompletionAttribute), nameof(NativeDisableParallelForRestrictionAttribute))); m_JobInitializers.Add(AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, IdentifierName(iterationContext.EntitiesArrayName), ForEachContext.MakeInitEntityArray(iterationContext))); arrayDisposal = null; return(null); // nothing to declare in context }
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 static ExpressionSyntax MakeInitEntityArray(RoslynEcsTranslator.IterationContext iterationContext) { return(InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, IdentifierName(iterationContext.GroupName), IdentifierName("ToEntityArray"))) .WithArgumentList( ArgumentList( SingletonSeparatedList( Argument( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, IdentifierName(nameof(Allocator)), IdentifierName(iterationContext.AllocatorType.ToString())))))) .NormalizeWhitespace()); }
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)); }
public override string GetOrDeclareComponentArray(RoslynEcsTranslator.IterationContext ctx, string componentTypeName, out LocalDeclarationStatementSyntax arrayInitialization, out StatementSyntax arrayDisposal) { arrayInitialization = null; arrayDisposal = null; if (m_DeclaredComponentArray.TryGetValue(componentTypeName, out var arrayName)) { return(arrayName); } arrayName = ctx.GetComponentDataArrayName(componentTypeName); m_DeclaredComponentArray.Add(componentTypeName, arrayName); var field = FieldDeclaration( VariableDeclaration( GenericName( Identifier("NativeArray")) .WithTypeArgumentList( TypeArgumentList( SingletonSeparatedList <TypeSyntax>( IdentifierName(componentTypeName))))) .WithVariables( SingletonSeparatedList( VariableDeclarator( Identifier(arrayName))))) .WithModifiers( TokenList( Token(SyntaxKind.PublicKeyword))); m_MemberDeclarations.Add(AddAttribute(field, nameof(DeallocateOnJobCompletionAttribute))); m_JobInitializers.Add(AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, IdentifierName(arrayName), RootContext.MakeInitComponentDataArrayExpression(ctx, componentTypeName) )); return(ctx.GetComponentDataArrayName(componentTypeName)); }
static ExpressionStatementSyntax BuildAddCoroutineComponent( RoslynEcsTranslator.IterationContext iterationContext, string coroutineName) { return(ExpressionStatement( InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, IdentifierName(nameof(EntityManager)), GenericName( Identifier(nameof(EntityManager.AddComponent))) .WithTypeArgumentList( TypeArgumentList( SingletonSeparatedList <TypeSyntax>( IdentifierName(coroutineName)))))) .WithArgumentList( ArgumentList( SingletonSeparatedList( Argument( IdentifierName( CoroutineTranslator.MakeExcludeCoroutineQueryName(iterationContext)))))))); }
public JobContext(IIteratorStackModel query, RootContext parent, UpdateMode mode) : base(parent) { IterationContext = new RoslynEcsTranslator.IterationContext(this, query, parent.MakeUniqueName(query.ComponentQueryDeclarationModel.VariableName), mode); m_JobName = query is OnEventNodeModel onEventNodeModel ? parent.MakeUniqueName($"On_{onEventNodeModel.EventTypeHandle.Name(IterationContext.Stencil)}_Job") : parent.MakeUniqueName($"Update_{IterationContext.GroupName}_Job"); m_ExcludedComponents = new HashSet <TypeHandle>(query.ComponentQueryDeclarationModel.Components.Where(c => c.Component.Subtract) .Select(c => c.Component.TypeHandle)); GetOrDeclareComponentQuery(IterationContext); if ((TranslationOptions & RoslynEcsTranslator.TranslationOptions.Tracing) != 0) { m_RecorderJobFieldName = (IdentifierNameSyntax)GetCachedValue(k_RecorderWriterName, InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, IdentifierName($"{IterationContext.GroupName}Recorder"), IdentifierName("AsWriter"))), typeof(GraphStream.Writer).GenerateTypeHandle(this.IterationContext.Stencil)); } }
public override string GetOrDeclareComponentArray(RoslynEcsTranslator.IterationContext ctx, string componentTypeName, out LocalDeclarationStatementSyntax arrayInitialization, out StatementSyntax arrayDisposal) { var arrayName = ctx.GetComponentDataArrayName(componentTypeName); arrayInitialization = RoslynBuilder.DeclareLocalVariable( (Type)null, arrayName, MakeInitComponentDataArrayExpression(ctx, componentTypeName), RoslynBuilder.VariableDeclarationType.InferredType); arrayDisposal = ExpressionStatement( InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, IdentifierName(arrayName), IdentifierName(nameof(IDisposable.Dispose))))) .NormalizeWhitespace(); return(arrayName); }
internal static ExpressionSyntax MakeInitComponentDataArrayExpression(RoslynEcsTranslator.IterationContext ctx, string componentTypeName) { return(InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, IdentifierName(ctx.GroupName), GenericName( Identifier("ToComponentDataArray")) .WithTypeArgumentList( TypeArgumentList( SingletonSeparatedList <TypeSyntax>( IdentifierName(componentTypeName)))))) .WithArgumentList( ArgumentList( SingletonSeparatedList( Argument( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, IdentifierName(nameof(Allocator)), IdentifierName(ctx.AllocatorType.ToString())))))) .NormalizeWhitespace()); }
public virtual bool GetEventSystem(RoslynEcsTranslator.IterationContext iterationContext, Type eventType) { return(Parent.GetEventSystem(iterationContext, eventType)); }
internal virtual void IncludeCoroutineComponent(RoslynEcsTranslator.IterationContext iterationContext, string coroutineComponentName) { Parent.IncludeCoroutineComponent(iterationContext, coroutineComponentName); }
protected virtual StatementSyntax GetOrDeclareEntityArray(RoslynEcsTranslator.IterationContext iterationContext, out StatementSyntax arrayDisposal) { return(Parent.GetOrDeclareEntityArray(iterationContext, out arrayDisposal)); }
public abstract void RecordComponentAccess(RoslynEcsTranslator.IterationContext query, TypeHandle componentType, RoslynEcsTranslator.AccessMode mode);
public ForEachContext(IIteratorStackModel query, TranslationContext parent, UpdateMode mode) : base(parent) { IterationContext = new RoslynEcsTranslator.IterationContext(this, query, parent.MakeUniqueName(query.ComponentQueryDeclarationModel.VariableName), mode); GetOrDeclareComponentQuery(IterationContext); }
public virtual string GetOrDeclareComponentQuery(RoslynEcsTranslator.IterationContext iterationContext) { return(Parent.GetOrDeclareComponentQuery(iterationContext)); }
public override string GetOrDeclareComponentQuery(RoslynEcsTranslator.IterationContext ctx) { return(Parent.GetOrDeclareComponentQuery(ctx)); }
protected override StatementSyntax AddMissingEventBuffers(RoslynEcsTranslator.IterationContext iterationContext, StatementSyntax onPopContext) => onPopContext;
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)))))))); } }
public virtual IdentifierNameSyntax GetEventBufferWriter(RoslynEcsTranslator.IterationContext iterationContext, ExpressionSyntax entity, Type eventType, out StatementSyntax bufferInitialization) { return(Parent.GetEventBufferWriter(iterationContext, entity, eventType, out bufferInitialization)); }
public PerGroupCtxComponents(RoslynEcsTranslator.IterationContext context) { Context = context; }
protected virtual StatementSyntax AddMissingEventBuffers(RoslynEcsTranslator.IterationContext iterationContext, StatementSyntax onPopContext) => Parent.AddMissingEventBuffers(iterationContext, onPopContext);
public override bool GetEventSystem(RoslynEcsTranslator.IterationContext iterationContext, Type eventType) { m_EventSystems.Add(eventType); return(m_WrittenComponentsPerGroup[iterationContext].WrittenEvents.Add(eventType)); }
public virtual string GetOrDeclareComponentArray(RoslynEcsTranslator.IterationContext ctx, string componentTypeName, out LocalDeclarationStatementSyntax arrayInitialization, out StatementSyntax arrayDisposal) { return(Parent.GetOrDeclareComponentArray(ctx, componentTypeName, out arrayInitialization, out arrayDisposal)); }
public override IdentifierNameSyntax GetEventBufferWriter(RoslynEcsTranslator.IterationContext iterationContext, ExpressionSyntax entity, Type eventType, out StatementSyntax bufferInitialization) { GetEventSystem(iterationContext, eventType); var bufferVariableName = SendEventTranslator.GetBufferVariableName(iterationContext, eventType); var buffersFromEntityVariableName = bufferVariableName + "s"; var cmdBuffer = GetOrDeclareCommandBuffer(true); bufferInitialization = RoslynBuilder.DeclareLocalVariable((Type)null, bufferVariableName, variableDeclarationType: RoslynBuilder.VariableDeclarationType.InferredType, initValue: ConditionalExpression( InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, IdentifierName(buffersFromEntityVariableName), IdentifierName("Exists"))) .WithArgumentList( ArgumentList( SingletonSeparatedList( Argument( IdentifierName(EntityName))))), ElementAccessExpression( IdentifierName(buffersFromEntityVariableName)) .WithArgumentList( BracketedArgumentList( SingletonSeparatedList( Argument( IdentifierName(EntityName))))), InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, cmdBuffer, GenericName( Identifier(nameof(EntityCommandBuffer.AddBuffer))) .WithTypeArgumentList( TypeArgumentList( SingletonSeparatedList( eventType.ToTypeSyntax()))))) .WithArgumentList( ArgumentList( SeparatedList <ArgumentSyntax>( new SyntaxNodeOrToken[] { Argument( IdentifierName(GetJobIndexParameterName())), Token(SyntaxKind.CommaToken), Argument( IdentifierName(EntityName)) }))))); GetCachedValue(buffersFromEntityVariableName, InvocationExpression( GenericName( Identifier(nameof(JobComponentSystem.GetBufferFromEntity))) .WithTypeArgumentList( TypeArgumentList( SingletonSeparatedList( eventType.ToTypeSyntax())))), typeof(BufferFromEntity <>).MakeGenericType(eventType).GenerateTypeHandle(iterationContext.Stencil)); // The BufferFromEntity<EventStruct> is not parallel-write safe. We might have multiple iterations sending // events to the same separate entity, so we run the job on a single thread to be safe m_ScheduleSingleThreaded = true; return(IdentifierName(bufferVariableName)); }