private InstantiationContext(InstantiationContext parentContext, int sequenceNumber) { _random = parentContext._random; _logger = parentContext._logger; _insertionEntityProperties = parentContext._insertionEntityProperties; _parentContext = parentContext; ID = parentContext.ID; SequenceNumber = sequenceNumber; RecursionDepth = parentContext.RecursionDepth; Template = parentContext.Template; CurrentWorkingDirectory = parentContext.CurrentWorkingDirectory; SubTemplates = parentContext.SubTemplates; Transform = parentContext.Transform; Globals = parentContext.Globals; OutputMap = parentContext.OutputMap; _evaluationContext = Evaluation.ContextFromProperties(_insertionEntityProperties, ID, SequenceNumber, _random, Globals, _logger, parentContext._evaluationContext); }
private void ApplyRewriteDirective(Dictionary <string, string> entityProperties, RewriteDirective rewriteDirective, int entityID, Random random, IDictionary <string, object> globals) { var context = Evaluation.ContextFromProperties(entityProperties, entityID, entityID, random, globals, Logger); NativeUtils.RegisterInstanceMethods(context, _directoryFunctions); foreach (var ruleGroup in rewriteDirective.RuleGroups) { if (!ruleGroup.HasCondition || Interpreter.IsTrue(PropertyExtensions.ParseProperty(Evaluation.EvaluateInterpolatedString(ruleGroup.Condition, context)))) { foreach (var rule in ruleGroup.Rules) { ApplyRewriteRule(entityProperties, rule, context); } } else if (ruleGroup.HasCondition) { foreach (var rule in ruleGroup.AlternateRules) { ApplyRewriteRule(entityProperties, rule, context); } } } }
/// <summary> /// Removes any template areas (<see cref="MacroEntity.Template"/>) and their contents from the given map, returning them as a dictionary. /// Template area names do not need to be unique. /// </summary> private static IEnumerable <MapTemplate> ExtractSubTemplates(Map map, IDictionary <string, object> globals, ILogger logger) { var templateEntities = map.GetEntitiesWithClassName(MacroEntity.Template); var objectsMarkedForRemoval = new HashSet <object>(templateEntities); var randomSeed = (int)(map.Properties.GetNumericProperty(Attributes.RandomSeed) ?? 0); var context = Evaluation.ContextFromProperties(map.Properties, 0, 0, new Random(randomSeed), globals, logger); // Create a MapTemplate for each macro_template entity. These 'sub-templates' can only be used within the current map: var subTemplates = new List <MapTemplate>(); foreach (var templateEntity in templateEntities) { var templateArea = templateEntity.BoundingBox.ExpandBy(0.5f); var templateName = templateEntity.GetStringProperty(Attributes.Targetname) ?? ""; var selectionWeight = templateEntity.GetStringProperty(Attributes.SelectionWeight) ?? ""; var offset = GetTemplateEntityOrigin(templateEntity, context) * -1; var templateMap = new Map(); // Copy custom properties into the template map properties - these will serve as local variables that will be evaluated whenever the template is instantiated: foreach (var property in templateEntity.Properties) { templateMap.Properties[property.Key] = property.Value; } templateMap.Properties.Remove(Attributes.Targetname); templateMap.Properties.Remove(Attributes.SelectionWeight); templateMap.Properties.Remove(Attributes.Anchor); // Include all entities that are fully inside this template area (except for other macro_template entities - nesting is not supported): foreach (var entity in map.Entities.Where(entity => entity.ClassName != MacroEntity.Template)) { if (templateArea.Contains(entity)) { templateMap.Entities.Add(entity.Copy(offset)); objectsMarkedForRemoval.Add(entity); } } // Include all brushes that are fully inside this template area: foreach (var brush in map.WorldGeometry) { if (templateArea.Contains(brush)) { templateMap.AddBrush(brush.Copy(offset)); objectsMarkedForRemoval.Add(brush); } } var conditionalContent = ExtractConditionalContent(templateMap); subTemplates.Add(new MapTemplate(templateMap, templateName, true, selectionWeight, conditionalContent: conditionalContent)); } // Now that we've checked all template areas, we can remove the macro_template entities and their contents from the map: foreach (var mapObject in objectsMarkedForRemoval) { switch (mapObject) { case Entity entity: map.Entities.Remove(entity); break; case Brush brush: map.RemoveBrush(brush); break; } // TODO: They're also still part of groups, vis-groups, etc! } return(subTemplates); }
/// <summary> /// Calls <see cref="Evaluation.EvaluateExpression(string, EvaluationContext)"/>, using this instance's evaluation context. /// </summary> public object EvaluateExpression(string expression) => Evaluation.EvaluateExpression(expression, _evaluationContext);
/// <summary> /// Calls <see cref="Evaluation.EvaluateInterpolatedString(string, EvaluationContext)"/>, using this instance's evaluation context. /// </summary> public string EvaluateInterpolatedString(string interpolatedString) => Evaluation.EvaluateInterpolatedString(interpolatedString, _evaluationContext);