Esempio n. 1
0
        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 }));
        }
Esempio n. 2
0
        public override IdentifierNameSyntax GetEventBufferWriter(RoslynEcsTranslator.IterationContext iterationContext, ExpressionSyntax entity, Type eventType, out StatementSyntax bufferInitialization)
        {
            bufferInitialization = null;
            var bufferVariableName = SendEventTranslator.GetBufferVariableName(iterationContext, eventType);

            iterationContext.WrittenEventTypes.Add(eventType);
            if (GetEventSystem(iterationContext, eventType))
            {
                // var buffer = EntityManager.GetBuffer<EventType>(entity);
                var bufferInitValue = InvocationExpression(
                    MemberAccessExpression(
                        SyntaxKind.SimpleMemberAccessExpression,
                        IdentifierName("EntityManager"),
                        GenericName(
                            Identifier("GetBuffer"))
                        .WithTypeArgumentList(
                            TypeArgumentList(
                                SingletonSeparatedList(
                                    eventType.ToTypeSyntax())))))
                                      .WithArgumentList(
                    ArgumentList(
                        SingletonSeparatedList(
                            Argument(entity)
                            )
                        )
                    );
                bufferInitialization = RoslynBuilder.DeclareLocalVariable((Type)null, bufferVariableName, bufferInitValue, RoslynBuilder.VariableDeclarationType.InferredType);
            }
            return(IdentifierName(bufferVariableName));
        }
Esempio n. 3
0
        public override string GetOrDeclareComponentArray(
            RoslynEcsTranslator.IterationContext ctx,
            ComponentDefinition componentDefinition,
            out LocalDeclarationStatementSyntax arrayInitialization,
            out StatementSyntax arrayDisposal)
        {
            Type resolvedType = componentDefinition.TypeHandle.Resolve(m_Stencil);
            var  arrayName    = ctx.GetComponentDataArrayName(resolvedType);

            Type arrayType = typeof(NativeArray <>).MakeGenericType(resolvedType);

            arrayInitialization = RoslynBuilder.DeclareLocalVariable(
                arrayType, arrayName,
                MakeInitComponentDataArrayExpression(ctx, resolvedType),
                RoslynBuilder.VariableDeclarationType.InferredType);

            arrayDisposal = ExpressionStatement(
                InvocationExpression(
                    MemberAccessExpression(
                        SyntaxKind.SimpleMemberAccessExpression,
                        IdentifierName(arrayName),
                        IdentifierName(nameof(IDisposable.Dispose)))))
                            .NormalizeWhitespace();

            return(arrayName);
        }
Esempio n. 4
0
        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 })));
        }
Esempio n. 5
0
        protected override IEnumerable <StatementSyntax> OnPopContext()
        {
            var rootContext = (RootContext)Parent;
            var build       = BuildJobStruct();

            if (build != null)
            {
                rootContext.AddMember(build);
                if ((TranslationOptions & RoslynEcsTranslator.TranslationOptions.Tracing) == 0)
                {
                    yield return(MakeJobSchedulingStatement());

                    yield break;
                }

                var recorderName = $"{IterationContext.GroupName}Recorder";
                yield return(RoslynBuilder.DeclareLocalVariable(typeof(GraphStream), recorderName,
                                                                InvocationExpression(
                                                                    MemberAccessExpression(
                                                                        SyntaxKind.SimpleMemberAccessExpression,
                                                                        IdentifierName(nameof(TracingRecorderSystem)),
                                                                        IdentifierName(nameof(TracingRecorderSystem.GetRecordingStream))))
                                                                .WithArgumentList(
                                                                    ArgumentList(
                                                                        SeparatedList(
                                                                            new[]
                {
                    Argument(
                        InvocationExpression(
                            MemberAccessExpression(
                                SyntaxKind.SimpleMemberAccessExpression,
                                IdentifierName(IterationContext.GroupName),
                                IdentifierName(nameof(EntityQuery.CalculateEntityCount))))),
                    Argument(
                        LiteralExpression(
                            SyntaxKind.NumericLiteralExpression,
                            Literal(((UnityEngine.Object)IterationContext.Query.GraphModel.AssetModel).GetInstanceID())))
                })))));

                yield return(MakeJobSchedulingStatement());

                yield return(ExpressionStatement(
                                 InvocationExpression(
                                     MemberAccessExpression(
                                         SyntaxKind.SimpleMemberAccessExpression,
                                         IdentifierName(nameof(TracingRecorderSystem)),
                                         IdentifierName(nameof(TracingRecorderSystem.FlushRecordingStream))))
                                 .WithArgumentList(
                                     ArgumentList(
                                         SeparatedList(
                                             new[]
                {
                    Argument(
                        IdentifierName(recorderName)),
                    Argument(
                        IdentifierName("inputDeps"))
                })))));
            }
        }
 public IEnumerable <SyntaxNode> Instantiate(TranslationContext context, ExpressionSyntax entity)
 {
     yield return(RoslynBuilder.MethodInvocation(
                      nameof(EntityManager.Instantiate),
                      IdentifierName(nameof(EntityManager)),
                      new[] { Argument(entity) },
                      Enumerable.Empty <TypeSyntax>()));
 }
Esempio n. 7
0
 public IEnumerable <SyntaxNode> CreateEntity(TranslationContext context)
 {
     yield return(RoslynBuilder.MethodInvocation(
                      nameof(EntityManager.CreateEntity),
                      IdentifierName(nameof(EntityManager)),
                      Enumerable.Empty <ArgumentSyntax>(),
                      Enumerable.Empty <TypeSyntax>()));
 }
 internal override void RequestSingletonUpdate()
 {
     m_SingletonUpdateSyntax = ExpressionStatement(
         RoslynBuilder.MethodInvocation(
             SafeGuardNamingSystem.SetSingletonName,
             null,
             new[] { Argument(IdentifierName(SingletonVariableName)) },
             Enumerable.Empty <TypeSyntax>()));
 }
        public static IEnumerable <SyntaxNode> BuildUnaryOperator(this RoslynTranslator translator, UnaryOperatorNodeModel model, IPortModel portModel)
        {
            var semantic = model.Kind == UnaryOperatorKind.PostDecrement ||
                           model.Kind == UnaryOperatorKind.PostIncrement
                ? RoslynTranslator.PortSemantic.Write
                : RoslynTranslator.PortSemantic.Read;

            yield return(RoslynBuilder.UnaryOperator(model.Kind, translator.BuildPort(model.InputPort, semantic).SingleOrDefault()));
        }
 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 })));
 }
Esempio n. 11
0
        public static IEnumerable <SyntaxNode> BuildVariable(this RoslynEcsTranslator translator, IVariableModel v, IPortModel portModel)
        {
            if (v is IConstantNodeModel model)
            {
                if (model.ObjectValue != null)
                {
                    yield return(translator.Constant(model.ObjectValue, translator.Stencil, model.Type));
                }

                yield break;
            }

            if (translator.InMacro.Count > 0 && v.DeclarationModel.VariableType == VariableType.GraphVariable && v.DeclarationModel.Modifiers == ModifierFlags.ReadOnly)
            {
                MacroRefNodeModel oldValue = translator.InMacro.Pop();

                var syntaxNodes = translator.BuildPort(oldValue.InputsById[v.DeclarationModel.VariableName]);
                translator.InMacro.Push(oldValue);
                foreach (var syntaxNode in syntaxNodes)
                {
                    yield return(syntaxNode);
                }
                yield break;
            }

            switch (v.DeclarationModel.VariableType)
            {
            case VariableType.GraphVariable:
                yield return(translator.context.GetSingletonVariable(v.DeclarationModel));

                break;

            case VariableType.FunctionVariable:
            case VariableType.ComponentGroupField:
                yield return(RoslynBuilder.LocalVariableReference(v.DeclarationModel.VariableName));

                break;

            case VariableType.FunctionParameter:
                var variableDeclarationModel = v.DeclarationModel;
                if (variableDeclarationModel.VariableIsAGeneratedEcsComponent(out var groupDeclaration))
                {
                    var relevantContext = translator.FindContext(groupDeclaration);
                    translator.context.RecordComponentAccess(relevantContext, v.DeclarationModel.DataType, translator.IsRecordingComponentAccesses);
                    yield return(RoslynBuilder.ArgumentReference(translator.context.GetComponentVariableName(groupDeclaration, variableDeclarationModel.DataType)));
                }
                else
                {
                    yield return(RoslynBuilder.ArgumentReference(v.DeclarationModel.VariableName));
                }
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
 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 static IEnumerable <SyntaxNode> BuildVariable(this RoslynTranslator translator, IVariableModel v, IPortModel portModel)
        {
            if (v is IConstantNodeModel constantNodeModel)
            {
                if (constantNodeModel.ObjectValue != null)
                {
                    if (constantNodeModel is IStringWrapperConstantModel)
                    {
                        yield return(translator.Constant(constantNodeModel.ObjectValue.ToString(), translator.Stencil));
                    }
                    else
                    {
                        yield return(translator.Constant(constantNodeModel.ObjectValue, translator.Stencil));
                    }
                }

                yield break;
            }

            if (translator.InMacro.Count > 0 && v.DeclarationModel.VariableType == VariableType.GraphVariable && v.DeclarationModel.Modifiers == ModifierFlags.ReadOnly)
            {
                MacroRefNodeModel oldValue = translator.InMacro.Pop();

                var syntaxNodes = translator.BuildPort(oldValue.InputsById[v.DeclarationModel.VariableName]);
                translator.InMacro.Push(oldValue);
                foreach (var syntaxNode in syntaxNodes)
                {
                    yield return(syntaxNode);
                }
                yield break;
            }

            switch (v.DeclarationModel.VariableType)
            {
            case VariableType.FunctionVariable:
            case VariableType.GraphVariable:
            case VariableType.ComponentQueryField:
                yield return(RoslynBuilder.LocalVariableReference(v.DeclarationModel.Name));

                break;

            case VariableType.FunctionParameter:
                yield return(RoslynBuilder.ArgumentReference(v.DeclarationModel.Name));

                break;

//                case VariableType.Literal:
//                case VariableType.InlineExpression:
            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Esempio n. 14
0
        public static IEnumerable <SyntaxNode> BuildSetVariable(this RoslynEcsTranslator translator, SetVariableNodeModel statement, IPortModel portModel)
        {
            if (statement.InstancePort.ConnectionPortModels.First().NodeModel is VariableNodeModel variableNode &&
                variableNode.ReferencedObject is IVariableDeclarationModel &&
                variableNode.DeclarationModel.VariableType == VariableType.GraphVariable)
            {
                translator.context.RequestSingletonUpdate();
            }

            var decl  = translator.BuildPort(statement.InstancePort).SingleOrDefault();
            var value = translator.BuildPort(statement.ValuePort).SingleOrDefault();

            yield return(decl == null || value == null ? null : RoslynBuilder.Assignment(decl, value));
        }
Esempio n. 15
0
        static MemberAccessExpressionSyntax GetLeftValueFromCriterion(IEntityManipulationTranslator self,
                                                                      TranslationContext context, Stencil stencil, ExpressionSyntax entity, Criterion criterion)
        {
            var componentType       = criterion.ObjectType.Resolve(stencil);
            var componentExpression = self.GetComponent(context, entity, componentType).Single();

            var access = RoslynBuilder.MemberReference(componentExpression, criterion.Member.Path[0]);

            for (var i = 1; i < criterion.Member.Path.Count; i++)
            {
                access = RoslynBuilder.MemberReference(access, criterion.Member.Path[i]);
            }

            return(access);
        }
Esempio n. 16
0
 public override void AddEntityDeclaration(string variableName)
 {
     // Entity {m_EntityName} = {IterationContext.EntitiesArrayName}[{IterationContext.IndexVariableName}];
     EntityName          = variableName;
     m_EntityDeclaration = RoslynBuilder.DeclareLocalVariable(
         typeof(Entity),
         EntityName,
         ElementAccessExpression(IdentifierName(IterationContext.EntitiesArrayName))
         .WithArgumentList(
             BracketedArgumentList(
                 SingletonSeparatedList(
                     Argument(
                         IdentifierName(IterationContext.IndexVariableName))))),
         RoslynBuilder.VariableDeclarationType.InferredType);
 }
 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 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>()));
 }
        protected MethodDeclarationSyntax BuildUpdateCoroutineMethod()
        {
            var states = new List <SwitchSectionSyntax>();
            var index  = 0;

            foreach (var state in m_States)
            {
                if (!state.SkipStateBuilding)
                {
                    state.Statements.Add(BuildGoToState(state.NextStateIndex));
                    state.Statements.Add(ReturnStatement(LiteralExpression(SyntaxKind.TrueLiteralExpression)));
                }

                states.Add(SwitchSection()
                           .WithLabels(
                               SingletonList <SwitchLabelSyntax>(
                                   CaseSwitchLabel(
                                       LiteralExpression(
                                           SyntaxKind.NumericLiteralExpression,
                                           Literal(index)))))
                           .WithStatements(
                               SingletonList <StatementSyntax>(
                                   Block(state.Statements))));

                index++;
            }

            var coroutineIdentifier = BuildCoroutineParameter();

            return(RoslynBuilder.DeclareMethod(
                       UpdateMethodName,
                       AccessibilityFlags.Private | AccessibilityFlags.Static,
                       typeof(bool))
                   .WithParameterList(
                       ParameterList(SeparatedList(m_Parameters.Values)))
                   .WithBody(
                       Block(
                           SwitchStatement(
                               MemberAccessExpression(
                                   SyntaxKind.SimpleMemberAccessExpression,
                                   coroutineIdentifier,
                                   IdentifierName(k_CoroutineStateVariableName)))
                           .WithOpenParenToken(Token(SyntaxKind.OpenParenToken))
                           .WithCloseParenToken(Token(SyntaxKind.CloseParenToken))
                           .WithSections(List(states)),
                           ReturnStatement(
                               LiteralExpression(SyntaxKind.FalseLiteralExpression)))));
        }
Esempio n. 20
0
 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
 }
        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);
        }
        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> 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,
                                                     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 <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> 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 }));
        }
Esempio n. 27
0
        public static IEnumerable <SyntaxNode> BuildIfCondition(this RoslynEcsTranslator translator, IfConditionNodeModel statement, IPortModel portModel)
        {
            // TODO: de-duplicate code after if stacks
            var firstThenStack = RoslynTranslator.GetConnectedStack(statement, 0);
            var firstElseStack = RoslynTranslator.GetConnectedStack(statement, 1);

            // this enables more elegant code generation with no duplication
            // find first stack reachable from both then/else stacks
            var endStack = RoslynTranslator.FindCommonDescendant(firstThenStack, firstElseStack);

            if (endStack != null)
            {
//                Debug.Log($"If in stack {statement.parentStackModel} Common descendant: {endStack}");
                // building the branches will stop at the common descendant
                translator.EndStack = endStack;
            }

            // ie. follow outputs, find all stacks with multiple inputs, compare them until finding the common one if it exists
            // BuildStack should take an abort stack parameter, returning when recursing on it
            // the parent buildStack call will then continue on this end stack

            var thenBlock = Block();

            if (endStack != firstThenStack)
            {
                translator.BuildStack(firstThenStack, ref thenBlock, StackExitStrategy.Inherit);
            }

            var elseBlock = Block();

            if (endStack != firstElseStack)
            {
                translator.BuildStack(firstElseStack, ref elseBlock, StackExitStrategy.Inherit);
            }

            var ifNode = RoslynBuilder.IfStatement(
                translator.BuildPort(statement.IfPort).SingleOrDefault(),
                thenBlock,
                elseBlock);

            yield return(ifNode);
        }
        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 static IEnumerable <SyntaxNode> BuildGetPropertyNode(this RoslynTranslator translator, GetPropertyGroupNodeModel model, IPortModel portModel)
        {
            var instancePort = model.InstancePort;
            var input        = !instancePort.Connected ? SyntaxFactory.ThisExpression() : translator.BuildPort(instancePort).SingleOrDefault();

            if (input == null)
            {
                yield break;
            }

            var member = model.Members.FirstOrDefault(m => m.GetId() == portModel.UniqueId);

            if (member.Path == null || member.Path.Count == 0)
            {
                yield break;
            }

            var access = RoslynBuilder.MemberReference(input, member.Path.ToArray());

            yield return(access);
        }
        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);
        }