示例#1
0
 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))))))));
 }
        void BuildCoroutineNode(CoroutineNodeModel node, RoslynEcsTranslator translator, ref int currentIndex)
        {
            foreach (var variable in node.Fields.Where(v => !m_ComponentVariables.ContainsKey(v.Key)))
            {
                m_ComponentVariables.Add(variable.Key, variable.Value);
            }

            // Coroutine initialization state
            var initState = m_States[currentIndex];

            initState.Statements.AddRange(CoroutineTranslator.BuildInitState(node, translator));

            var nextStateIndex = initState.NextStateIndex;

            initState.NextStateIndex = m_States.Count;

            // Coroutine update state
            var updateState = RequestNewState();

            updateState.SkipStateBuilding = true;

            var hasNextNode = node.ParentStackModel.NodeModels.Last() != node;
            var nextStack   = GetNextStack(node.ParentStackModel);
            int nextIndex;

            if (hasNextNode || nextStack != null && !m_StackIndexes.ContainsKey(nextStack))
            {
                nextIndex = m_States.Count;
                var newState = RequestNewState();
                newState.NextStateIndex = nextStateIndex;
            }
            else
            {
                nextIndex = nextStateIndex == 0 ? m_States.Count : nextStateIndex;
            }

            node.NextStateIndex = nextIndex;
            updateState.Statements.AddRange(translator.BuildNode(node).Cast <StatementSyntax>());
            currentIndex = GetCurrentStateIndex();
        }
        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);
        }