void DeclareEntityQueries(PerGroupCtxComponents ctx) { List <ComponentDefinition> flattenedComponentDefinitions = ctx.Context.FlattenedComponentDefinitions().ToList(); IEnumerable <ArgumentSyntax> arguments = BuildArguments(ctx, flattenedComponentDefinitions); foreach (var(name, buildQuery) in BuildQueries(ctx, m_QueryHasStateTracking, m_Coroutines, arguments, ctx.Context.GroupName)) { var initValue = MakeInitQueryExpression(buildQuery); DeclareAndInitField(typeof(EntityQuery), name, initValue: initValue); } }
IEnumerable <ArgumentSyntax> BuildArguments(PerGroupCtxComponents ctx, List <ComponentDefinition> flattenedComponentDefinitions) { IEnumerable <ArgumentSyntax> ComponentTypeHandlesDeclarationSyntax(IEnumerable <ComponentDefinition> componentDefinitions, string declarationType) { return(componentDefinitions.Select(c => ComponentTypeDeclarationSyntax(c.TypeHandle.ToTypeSyntax(ctx.Context.Stencil), declarationType))); } var excludedComponents = flattenedComponentDefinitions.Where(c => c.Subtract); var writtenComponents = flattenedComponentDefinitions.Where(c => !c.Subtract && ctx.WrittenComponents.Contains(c.TypeHandle)); var readonlyComponents = flattenedComponentDefinitions.Where(c => !c.Subtract && !ctx.WrittenComponents.Contains(c.TypeHandle)); IEnumerable <ArgumentSyntax> arguments = ComponentTypeHandlesDeclarationSyntax(excludedComponents, nameof(ComponentType.Exclude)) .Concat(ComponentTypeHandlesDeclarationSyntax(writtenComponents, nameof(ComponentType.ReadWrite))) .Concat(ComponentTypeHandlesDeclarationSyntax(readonlyComponents, nameof(ComponentType.ReadOnly))); return(arguments); }
void DeclareEntityQueries(PerGroupCtxComponents ctx) { List <ComponentDefinition> flattenedComponentDefinitions = ctx.Context.FlattenedComponentDefinitions().ToList(); IEnumerable <ArgumentSyntax> arguments = BuildArguments(ctx, flattenedComponentDefinitions); foreach (var(name, buildQuery) in BuildQueries(ctx, m_QueryHasStateTracking, arguments, ctx.Context.GroupName)) { var initValue = !buildQuery.Any() ? (ExpressionSyntax)MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName("EntityManager"), IdentifierName("UniversalQuery")) : InvocationExpression(IdentifierName(SafeGuardNamingSystem.EntityQueryMethodName)) .WithArgumentList(ArgumentList(SeparatedList(buildQuery))); DeclareAndInitField(typeof(EntityQuery), name, initValue: initValue); } }
static IEnumerable <(string, IEnumerable <ArgumentSyntax>)> BuildQueries( PerGroupCtxComponents ctx, IReadOnlyDictionary <ComponentQueryDeclarationModel, QueryStateComponent> queryHasStateTracking, IReadOnlyDictionary <RoslynEcsTranslator.IterationContext, string> coroutineComponents, IEnumerable <ArgumentSyntax> arguments, string contextGroupName) { IEnumerable <ArgumentSyntax> PrependComponentToArguments(string name, string methodName) { return(Enumerable.Repeat(ComponentTypeDeclarationSyntax(IdentifierName(name), methodName), 1) .Concat(arguments)); } IEnumerable <ArgumentSyntax> PrependComponentFromTypeToArguments(Type t, string methodName) { return(Enumerable.Repeat(ComponentTypeDeclarationSyntax(t.ToTypeSyntax(), methodName), 1) .Concat(arguments)); } if (ctx.Context.Query is IPrivateIteratorStackModel updateMatching) { if (updateMatching.Mode == UpdateMode.OnEvent) { var eventType = ((OnEventNodeModel)updateMatching).EventTypeHandle.Resolve(updateMatching.GraphModel.Stencil); yield return(SendEventTranslator.MakeQueryIncludingEventName(ctx.Context, eventType), PrependComponentFromTypeToArguments( eventType, nameof(ComponentType.ReadOnly))); } var queryModel = ctx.Context.Query.ComponentQueryDeclarationModel; if (queryHasStateTracking.TryGetValue(queryModel, out var trackingComponent)) { string methodName = null; switch (updateMatching.Mode) { case UpdateMode.OnUpdate: case UpdateMode.OnEvent: methodName = nameof(ComponentType.ReadWrite); break; case UpdateMode.OnStart: methodName = nameof(ComponentType.Exclude); break; case UpdateMode.OnEnd: yield return(GetQueryAddStateName(contextGroupName), PrependComponentToArguments( trackingComponent.ComponentName, nameof(ComponentType.Exclude))); methodName = nameof(ComponentType.ReadOnly); break; } arguments = PrependComponentToArguments(trackingComponent.ComponentName, methodName); } // query_MissingEvents is only used in non-jobs context if ((ctx.Context.TranslationOptions & RoslynEcsTranslator.TranslationOptions.UseJobs) == 0) { foreach (Type eventType in ctx.WrittenEvents) { yield return(SendEventTranslator.MakeMissingEventQueryName(ctx.Context, eventType), PrependComponentFromTypeToArguments( eventType, nameof(ComponentType.Exclude))); } } } if (coroutineComponents.TryGetValue(ctx.Context, out var coroutine)) { yield return(CoroutineTranslator.MakeExcludeCoroutineQueryName(ctx.Context), PrependComponentToArguments(coroutine, nameof(ComponentType.Exclude))); arguments = PrependComponentToArguments(coroutine, nameof(ComponentType.ReadWrite)); } yield return(contextGroupName, arguments); }