public override TranslationContext PushContext(IIteratorStackModel query, RoslynEcsTranslator roslynEcsTranslator, UpdateMode mode, bool isCoroutine = false) { if (isCoroutine) { return(new CoroutineContext(this, roslynEcsTranslator)); } return(new ForEachContext(query, this, mode)); }
public void BuildCriteria(RoslynEcsTranslator translator, TranslationContext context, ExpressionSyntax entity, IEnumerable <CriteriaModel> criteriaModels) { this.BuildCriteria( translator, context, entity, criteriaModels.Where(x => x.Criteria.Any()), ContinueStatement() ); }
public override TranslationContext PushContext(IIteratorStackModel query, RoslynEcsTranslator roslynEcsTranslator, UpdateMode mode) { if (roslynEcsTranslator.GameObjectCodeGen || !m_TranslationOptions.HasFlag(RoslynEcsTranslator.TranslationOptions.UseJobs)) { m_NeedToCompleteDependenciesFirst = true; return(new ForEachLambdaContext(query, this, mode)); } return(new JobContext(query, this, mode) { BurstCompileJobs = m_TranslationOptions.HasFlag(RoslynEcsTranslator.TranslationOptions.BurstCompile) }); }
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)); }
public void BuildComponent(RoslynEcsTranslator translator) { // Create coroutine component var members = BuildComponentMembers(translator); DeclareComponent <ISystemStateComponentData>(m_ComponentTypeName, members); // Add coroutine in the query archetype IncludeCoroutineComponent(IterationContext, m_ComponentTypeName); // Add coroutine component var rootContext = (RootContext)Parent.Parent; rootContext.PrependStatement(BuildAddCoroutineComponent(IterationContext, m_ComponentTypeName)); }
public override void BuildComponent(IStackModel stack, RoslynEcsTranslator translator) { // Build stack BuildStack(translator, stack, 0); // Create coroutine component var members = BuildComponentMembers(); DeclareComponent <ISystemStateComponentData>(m_ComponentTypeName, members); // Create coroutine update method DeclareSystemMethod(BuildUpdateCoroutineMethod()); // Add a nestedCoroutine field in the parent coroutine component ((CoroutineContext)Parent).AddComponentField(m_ComponentTypeName, NestedCoroutineFieldName); }
public static IEnumerable <SyntaxNode> BuildReturn(this RoslynEcsTranslator translator, ReturnNodeModel returnModel, IPortModel portModel) { // TODO Implement Return statement in coroutine if (translator.context is CoroutineContext) { translator.AddError(returnModel, "Return node isn't allowed in Coroutine (e.g. Wait) execution stack for now. This feature is coming in a further release"); yield break; } if (returnModel.InputPort == null) { yield return(ReturnStatement()); } else { yield return(ReturnStatement( translator.BuildPort(returnModel.InputPort).FirstOrDefault() as ExpressionSyntax)); } }
public virtual void BuildComponent(IStackModel stack, RoslynEcsTranslator translator) { // Build stack BuildStack(translator, stack, 0); // Create coroutine component var members = BuildComponentMembers(); DeclareComponent <ISystemStateComponentData>(m_ComponentTypeName, members); // Add coroutine in the lambda/job execute method IncludeCoroutineComponent(IterationContext, m_ComponentTypeName); // Add coroutine component PrependStatement(BuildAddCoroutineComponent(IterationContext, m_ComponentTypeName)); // Create coroutine update method DeclareSystemMethod(BuildUpdateCoroutineMethod()); }
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); }
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(); }
public static IEnumerable <SyntaxNode> BuildFunctionRefCall(this RoslynEcsTranslator translator, FunctionRefCallNodeModel call, IPortModel portModel) { if (!call.Function) { yield break; } ExpressionSyntax instance = translator.BuildArgumentList(call, out var argumentList); if (!call.Function.IsInstanceMethod) { instance = IdentifierName(((VSGraphModel)call.Function.GraphModel).TypeName); } var invocationExpressionSyntax = instance == null || instance is LiteralExpressionSyntax && instance.IsKind(SyntaxKind.NullLiteralExpression) ? InvocationExpression(IdentifierName(call.Function.CodeTitle)) : InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, instance, IdentifierName(call.Function.CodeTitle))); invocationExpressionSyntax = invocationExpressionSyntax.WithArgumentList( ArgumentList(SeparatedList(argumentList))); if (portModel == null) { yield return(ExpressionStatement(invocationExpressionSyntax).NormalizeWhitespace()); } else { yield return(invocationExpressionSyntax.NormalizeWhitespace()); } }
public static IEnumerable <SyntaxNode> BuildBinaryOperator(this RoslynEcsTranslator translator, BinaryOperatorNodeModel model, IPortModel portModel) { if (model.kind == BinaryOperatorKind.Equals) { yield return(InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, PredefinedType(Token(SyntaxKind.ObjectKeyword)), IdentifierName("Equals"))) .WithArgumentList( ArgumentList( SeparatedList(new[] { Argument((ExpressionSyntax)translator.BuildPort(model.InputPortA).SingleOrDefault()), Argument((ExpressionSyntax)translator.BuildPort(model.InputPortB).SingleOrDefault()) })))); } else { yield return(RoslynBuilder.BinaryOperator(model.kind, translator.BuildPort(model.InputPortA).SingleOrDefault(), translator.BuildPort(model.InputPortB).SingleOrDefault())); } }
internal static void BuildCriteria(this IEntityManipulationTranslator self, RoslynEcsTranslator translator, TranslationContext context, ExpressionSyntax entity, IEnumerable <CriteriaModel> criteriaModels, StatementSyntax conditionBreak) { var criteriaList = criteriaModels.ToList(); if (!criteriaList.Any()) { return; } ExpressionSyntax ifExpressionSyntax = null; foreach (var model in criteriaList) { ExpressionSyntax finalExpression = null; foreach (var criterion in model.Criteria) { if (!(criterion is Criterion componentCriterion)) { continue; } var rightValue = componentCriterion.Value is ConstantNodeModel constantNodeModel ? translator.Constant(constantNodeModel.ObjectValue, translator.Stencil, constantNodeModel.Type) : IdentifierName(componentCriterion.Value.DeclarationModel.VariableName); var expression = BinaryExpression( componentCriterion.Operator.ToSyntaxKind(), GetLeftValueFromCriterion(self, context, translator.Stencil, entity, componentCriterion), rightValue) as ExpressionSyntax; // TODO : Temporary. Once Unity.Mathematics have IComparable interface, remove this // and use IComparable and IEquatable methods instead of operators var rightValueType = GetRightValueType(componentCriterion, translator.Stencil); if (rightValueType.Namespace != null && rightValueType.Namespace.StartsWith("Unity.Mathematics")) { expression = RoslynBuilder.MethodInvocation( nameof(math.all), typeof(math).ToTypeSyntax(), new[] { Argument(expression) }, Enumerable.Empty <TypeSyntax>()); } finalExpression = finalExpression == null ? expression : BinaryExpression(SyntaxKind.LogicalAndExpression, finalExpression, expression); } if (finalExpression == null) { continue; } context.AddStatement(RoslynBuilder.DeclareLocalVariable( typeof(bool), model.Name, finalExpression, RoslynBuilder.VariableDeclarationType.InferredType)); var unaryExpression = PrefixUnaryExpression(SyntaxKind.LogicalNotExpression, IdentifierName(model.Name)); if (model != criteriaList.First()) { ifExpressionSyntax = BinaryExpression( SyntaxKind.LogicalAndExpression, ifExpressionSyntax, unaryExpression); } else { ifExpressionSyntax = unaryExpression; } } if (ifExpressionSyntax != null) { BlockSyntax statementSyntax; if ((translator.Options & CompilationOptions.Tracing) != 0 && context is JobContext jobContext) { statementSyntax = Block(List <SyntaxNode>() .Add(jobContext.MakeTracingEndForEachIndexStatement()) .Add(conditionBreak)); } else { statementSyntax = Block(SingletonList(conditionBreak)); } context.AddStatement(IfStatement(ifExpressionSyntax, statementSyntax)); } }
protected void BuildStack(RoslynEcsTranslator translator, IStackModel stack, int currentStateIndex, StackExitStrategy exitStrategy = StackExitStrategy.Return) { if (stack == null || stack.State == ModelState.Disabled) { return; } translator.RegisterBuiltStack(stack); if (m_StackIndexes.TryGetValue(stack, out var endStackIndex)) { currentStateIndex = endStackIndex; } // JUST in case... until we validate the previous failsafe if (m_BuiltStackCounter++ > 10000) { throw new InvalidOperationException("Infinite loop while building the script, aborting"); } var origStackExitStrategy = m_StackExitStrategy; if (exitStrategy != StackExitStrategy.Inherit) { m_StackExitStrategy = exitStrategy; } if (m_States.Count == 0) { var state = RequestNewState(); state.NextStateIndex = GetCurrentStateIndex(); } var origEndStack = translator.EndStack; foreach (var node in stack.NodeModels) { if (node.State == ModelState.Disabled) { continue; } switch (node) { case CoroutineNodeModel coroutineNode: BuildCoroutineNode(coroutineNode, translator, ref currentStateIndex); continue; case IfConditionNodeModel ifConditionNodeModel: BuildIfConditionNode(ifConditionNodeModel, translator, currentStateIndex); continue; default: { var blocks = translator.BuildNode(node); var currentState = m_States[currentStateIndex]; currentState.SkipStateBuilding = currentState.SkipStateBuilding || SkipStateBuilding; currentState.Statements.AddRange(ConvertNodesToSyntaxList(node, blocks, translator.Options)); if (!SkipStateBuilding && stack.NodeModels.Last() == node && !HasConnectedStack(stack)) { currentState.SkipStateBuilding = true; currentState.Statements.Add(ReturnStatement( LiteralExpression(SyntaxKind.FalseLiteralExpression))); } SkipStateBuilding = false; break; } } } if (stack.DelegatesOutputsToNode(out _)) { var nextStack = translator.EndStack; m_StackExitStrategy = origStackExitStrategy; if (translator.EndStack == origEndStack) { return; } translator.EndStack = origEndStack; if (nextStack != null) { BuildStack(translator, nextStack, m_StackIndexes[nextStack], exitStrategy); } return; } foreach (var outputPort in stack.OutputPorts) { foreach (var connectedStack in outputPort.ConnectionPortModels) { if (connectedStack.NodeModel is IStackModel nextStack) { if (!ReferenceEquals(nextStack, translator.EndStack)) { BuildStack(translator, nextStack, currentStateIndex, exitStrategy); } } } } m_StackExitStrategy = origStackExitStrategy; }
public static IEnumerable <SyntaxNode> BuildReturn(this RoslynEcsTranslator translator, ReturnNodeModel returnModel, IPortModel portModel) { yield return(ReturnStatement( translator.BuildPort(returnModel.InputPort).FirstOrDefault() as ExpressionSyntax)); }
public static IEnumerable <SyntaxNode> BuildThisNode(this RoslynEcsTranslator translator, ThisNodeModel model, IPortModel portModel) { yield return(ThisExpression()); }
public ReplaceExpressionPorts(RoslynEcsTranslator translator, InlineExpressionNodeModel model) { m_Translator = translator; m_Model = model; }
public abstract TranslationContext PushContext(IIteratorStackModel query, RoslynEcsTranslator roslynEcsTranslator, UpdateMode mode);
public abstract TranslationContext PushContext(IIteratorStackModel query, RoslynEcsTranslator roslynEcsTranslator, UpdateMode mode, bool isCoroutine = false);
public CoroutineContext(TranslationContext parent, RoslynEcsTranslator translator) : base(parent) { IterationContext = parent.IterationContext; m_ComponentTypeName = translator.MakeUniqueName($"{IterationContext.GroupName}Coroutine").ToPascalCase(); }
void BuildIfConditionNode(IfConditionNodeModel node, RoslynEcsTranslator translator, int stateIndex) { translator.BuildNode(node); var firstThenStack = RoslynTranslator.GetConnectedStack(node, 0); var firstElseStack = RoslynTranslator.GetConnectedStack(node, 1); var ifState = m_States[stateIndex]; var ifIndex = GetCurrentStateIndex(); var endStackIndex = 0; if (translator.EndStack != null) { m_StackIndexes.TryGetValue(translator.EndStack, out endStackIndex); } // Reserve then/else/complete states first var thenIndex = ifIndex; var thenBlock = Block().AddStatements(ReturnStatement(LiteralExpression(SyntaxKind.FalseLiteralExpression))); StateData thenState = null; if (firstThenStack != null) { if (firstThenStack == translator.EndStack && endStackIndex != 0) { thenBlock = Block().AddStatements(BuildGoToState(endStackIndex)); } else { thenIndex += 1; thenState = RequestNewState(); TryAddStackIndex(firstThenStack, thenIndex); thenBlock = Block().AddStatements(BuildGoToState(thenIndex)); } } var elseIndex = thenIndex + 1; var elseBlock = Block().AddStatements(ReturnStatement(LiteralExpression(SyntaxKind.FalseLiteralExpression))); StateData elseState = null; if (firstElseStack != null) { if (firstElseStack == translator.EndStack && endStackIndex != 0) { elseBlock = Block().AddStatements(BuildGoToState(endStackIndex)); } else { elseState = RequestNewState(); TryAddStackIndex(firstElseStack, elseIndex); elseBlock = Block().AddStatements(BuildGoToState(elseIndex)); } } // Then Build stacks ifState.Statements.Add(RoslynBuilder.IfStatement( translator.BuildPort(node.IfPort).SingleOrDefault(), thenBlock, elseBlock) .WithAdditionalAnnotations( new SyntaxAnnotation(Annotations.VSNodeMetadata, node.Guid.ToString()))); ifState.Statements.Add(ReturnStatement(LiteralExpression(SyntaxKind.TrueLiteralExpression))); ifState.SkipStateBuilding = true; var reserveEndStackState = translator.EndStack != null && translator.EndStack != firstElseStack && translator.EndStack != firstThenStack && endStackIndex == 0; if (reserveEndStackState) { var endState = RequestNewState(); endState.NextStateIndex = GetNextStateIndex(translator.EndStack); TryAddStackIndex(translator.EndStack, GetCurrentStateIndex()); } var origBuiltStacks = translator.BuiltStacks; translator.BuiltStacks = new HashSet <IStackModel>(origBuiltStacks); if (translator.EndStack != firstThenStack) { if (translator.EndStack != null && thenState != null) { thenState.NextStateIndex = m_StackIndexes[translator.EndStack]; } BuildStack(translator, firstThenStack, thenIndex, StackExitStrategy.Inherit); } var partialStacks = translator.BuiltStacks; translator.BuiltStacks = new HashSet <IStackModel>(origBuiltStacks); if (translator.EndStack != firstElseStack) { if (translator.EndStack != null && elseState != null) { elseState.NextStateIndex = m_StackIndexes[translator.EndStack]; } BuildStack(translator, firstElseStack, elseIndex, StackExitStrategy.Inherit); } translator.BuiltStacks.UnionWith(partialStacks); }
public ClassDeclarationSyntax Build(RoslynTranslator translator, VSGraphModel graphModel) { var baseClass = m_NeedToCompleteDependenciesFirst ? nameof(ComponentSystem) : nameof(JobComponentSystem); m_ClassDeclaration = m_ClassDeclaration.WithBaseList( BaseList( SingletonSeparatedList <BaseTypeSyntax>( SimpleBaseType( IdentifierName(baseClass))))); foreach (var queryTracking in m_QueryHasStateTracking) { var trackingMembers = new List <MemberDeclarationSyntax>(); if (queryTracking.Value.Tracking) { trackingMembers.Add( FieldDeclaration( VariableDeclaration( PredefinedType( Token(SyntaxKind.BoolKeyword))) .WithVariables( SingletonSeparatedList( VariableDeclarator( Identifier("Processed"))))) .WithModifiers( TokenList( Token(SyntaxKind.InternalKeyword)))); } DeclareComponent <ISystemStateComponentData>(queryTracking.Value.ComponentName, trackingMembers); } foreach (var eventSystem in m_EventSystems) { // ClearEvents<TestEvent2>.Initialize(World); InitializationStatements.Add(ExpressionStatement(InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, GenericName( Identifier("EventSystem")) .WithTypeArgumentList( TypeArgumentList( SingletonSeparatedList <TypeSyntax>( IdentifierName(eventSystem.FullName)))), IdentifierName("Initialize"))) .WithArgumentList( ArgumentList( SingletonSeparatedList( Argument( IdentifierName("World"))))))); } if ((TranslationOptions & RoslynEcsTranslator.TranslationOptions.Tracing) != 0) { DeclareAndInitField(typeof(TracingRecorderSystem), nameof(TracingRecorderSystem), initValue: InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, IdentifierName("World"), GenericName( Identifier(nameof(World.GetExistingSystem))) .WithTypeArgumentList( TypeArgumentList( SingletonSeparatedList <TypeSyntax>( IdentifierName(nameof(TracingRecorderSystem)))))))); } HashSet <string> declaredQueries = new HashSet <string>(); foreach (var group in m_WrittenComponentsPerGroup) { declaredQueries.Add(group.Key.Query.ComponentQueryDeclarationModel.GetId()); DeclareEntityQueries(group.Value); } // declare unused queries in case there's a Count Entities In Query node somewhere foreach (var graphVariable in graphModel.GraphVariableModels.OfType <ComponentQueryDeclarationModel>().Where(q => !declaredQueries.Contains(q.GetId()))) { var args = graphVariable.Components.Select(c => SyntaxFactory.Argument( InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, IdentifierName("ComponentType"), GenericName( Identifier("ReadOnly")) .WithTypeArgumentList( TypeArgumentList( SingletonSeparatedList <TypeSyntax>( IdentifierName(c.Component.TypeHandle.Resolve(graphModel.Stencil) .FullName)))))) )); var initValue = MakeInitQueryExpression(args); DeclareAndInitField(typeof(EntityQuery), graphVariable.VariableName, initValue: initValue); } var singletonMembers = new List <FieldDeclarationSyntax>(); var initArguments = new List <AssignmentExpressionSyntax>(); foreach (var graphVariable in graphModel.GraphVariableModels .Where(g => g.VariableType == VariableType.GraphVariable)) { singletonMembers.Add(graphVariable.DeclareField(translator, false) .WithAdditionalAnnotations(new SyntaxAnnotation(Annotations.VariableAnnotationKind))); initArguments.Add(RoslynBuilder.Assignment( IdentifierName(graphVariable.VariableName), translator.Constant(graphVariable.InitializationModel.ObjectValue, m_Stencil))); } if (singletonMembers.Any()) { DeclareComponent <IComponentData>(SingletonComponentTypeName, singletonMembers); InitializationStatements.Add(ExpressionStatement( RoslynBuilder.MethodInvocation( nameof(EntityManager.CreateEntity), IdentifierName(nameof(EntityManager)), new[] { Argument(TypeOfExpression(IdentifierName(SingletonComponentTypeName))) }, Enumerable.Empty <TypeSyntax>()))); InitializationStatements.Add( ExpressionStatement( RoslynBuilder.MethodInvocation( SafeGuardNamingSystem.SetSingletonName, null, new[] { Argument(RoslynBuilder.DeclareNewObject( IdentifierName(SingletonComponentTypeName), Enumerable.Empty <ArgumentSyntax>(), initArguments)) }, Enumerable.Empty <TypeSyntax>()))); } // TODO : Remove this once there is real Systems' dependency tool var attributes = new List <AttributeListSyntax>(); foreach (var assetModel in m_Stencil.UpdateAfter.Where(a => a.GraphModel.Stencil is EcsStencil)) { RegisterAttributes <UpdateAfterAttribute>(attributes, assetModel.Name); } foreach (var assetModel in m_Stencil.UpdateBefore.Where(a => a.GraphModel.Stencil is EcsStencil)) { RegisterAttributes <UpdateBeforeAttribute>(attributes, assetModel.Name); } m_ClassDeclaration = m_ClassDeclaration .AddAttributeLists(attributes.ToArray()) .AddMembers(m_ClassMembers.OrderBy(x => x is FieldDeclarationSyntax ? 0 : 1).ToArray()); if (m_InitializationStatements != null) { var onCreateManagerOverride = RoslynBuilder.DeclareMethod( SafeGuardNamingSystem.OnCreateManagerName, AccessibilityFlags.Protected | AccessibilityFlags.Override, typeof(void)); m_ClassDeclaration = m_ClassDeclaration .AddMembers( onCreateManagerOverride.WithBody( Block(m_InitializationStatements))); } if (m_SingletonUpdateSyntax != null) { AddStatement(m_SingletonUpdateSyntax); } var onUpdateBlock = Block(m_UpdateStatements); return(m_ClassDeclaration.AddMembers( RoslynEcsTranslator.MakeOnUpdateOverride( onUpdateBlock, m_NeedToCompleteDependenciesFirst, m_CreatedManagers))); }
public override TranslationContext PushContext(IIteratorStackModel query, RoslynEcsTranslator roslynEcsTranslator, UpdateMode mode) { return(new ForEachContext(query, this, mode)); }
protected override IEnumerable <StatementSyntax> OnPopContext() { var syntax = RoslynEcsTranslator.MakeCondition(m_BodyConditions, BuildInner()); yield return(AddMissingEventBuffers(IterationContext, syntax)); }
public void BuildCriteria(RoslynEcsTranslator translator, TranslationContext context, ExpressionSyntax entity, IEnumerable <CriteriaModel> criteriaModels) { this.BuildCriteria(translator, context, entity, criteriaModels, ReturnStatement()); }
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.ComponentQueryField: yield return(RoslynBuilder.LocalVariableReference(v.DeclarationModel.VariableName)); break; case VariableType.FunctionParameter: var variableDeclarationModel = v.DeclarationModel; if (variableDeclarationModel.IsGeneratedEcsComponent(out var groupDeclaration)) { var relevantContext = translator.FindContext(groupDeclaration); if (relevantContext == null) { var variableName = v.DeclarationModel.Name; translator.AddError(v, $"Could not find a matching component query for variable \"{variableName}\""); throw new InvalidOperationException("No matching translation context for Declaration"); } translator.context.RecordComponentAccess(relevantContext, v.DeclarationModel.DataType, translator.IsRecordingComponentAccesses); yield return(RoslynBuilder.ArgumentReference(translator.context.GetComponentVariableName(groupDeclaration, variableDeclarationModel.DataType))); } else { if (variableDeclarationModel.IsGeneratedEntity()) { translator.context.RecordEntityAccess(variableDeclarationModel); } yield return(RoslynBuilder.ArgumentReference(variableDeclarationModel.VariableName)); } break; default: throw new ArgumentOutOfRangeException(); } }