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