Exemplo n.º 1
0
        private static Vector3D GetTemplateEntityOrigin(Entity templateEntity, EvaluationContext context)
        {
            if (!Enum.TryParse <TemplateAreaAnchor>(Evaluation.EvaluateInterpolatedString(templateEntity.GetStringProperty(Attributes.Anchor), context), out var anchor))
            {
                anchor = TemplateAreaAnchor.OriginBrush;
            }

            if (anchor == TemplateAreaAnchor.OriginBrush)
            {
                if (templateEntity.GetOrigin() is Vector3D origin)
                {
                    return(origin);
                }
            }

            // NOTE: The bottom anchor point is our default fallback for when there's no origin brush.
            switch (anchor)
            {
            default:
            case TemplateAreaAnchor.Bottom: return(new Vector3D(templateEntity.BoundingBox.Center.X, templateEntity.BoundingBox.Center.Y, templateEntity.BoundingBox.Min.Z));

            case TemplateAreaAnchor.Center: return(templateEntity.BoundingBox.Center);

            case TemplateAreaAnchor.Top: return(new Vector3D(templateEntity.BoundingBox.Center.X, templateEntity.BoundingBox.Center.Y, templateEntity.BoundingBox.Max.Z));
            }
        }
Exemplo n.º 2
0
        public InstantiationContext(
            MapTemplate template,
            ILogger logger,
            Transform transform = null,
            IDictionary <string, string> insertionEntityProperties = null,
            InstantiationContext parentContext   = null,
            string workingDirectory              = null,
            IDictionary <string, object> globals = null,
            int sequenceNumber = 0)
        {
            // Every context uses its own PRNG. Seeding is done automatically, but can be done explicitly
            // by adding a 'random_seed' attribute to the inserting entity (or to the map properties, for the root context).
            // NOTE: even with explicit seeding, a random value is always obtained from the parent context.
            //       This ensures that switching between explicit and implicit seeding does not result in 'sibling' contexts
            //       getting different seed values.
            var randomSeed = parentContext?._random.Next() ?? 0;

            if (insertionEntityProperties?.GetNumericProperty(Attributes.RandomSeed) is double seed)
            {
                randomSeed = (int)seed;
            }
            _random = new Random(randomSeed);
            _logger = logger;
            _insertionEntityProperties = insertionEntityProperties;
            _parentContext             = parentContext;

            ID                      = GetRootContext()._nextID++;
            SequenceNumber          = sequenceNumber;
            RecursionDepth          = (parentContext?.RecursionDepth ?? -1) + 1;
            Template                = template;
            CurrentWorkingDirectory = workingDirectory ?? Path.GetDirectoryName(GetNearestMapFileContext().Template.Name);
            SubTemplates            = GetNearestMapFileContext().Template.SubTemplates;

            Transform = transform ?? Transform.Identity;
            Globals   = globals ?? parentContext?.Globals ?? new Dictionary <string, object>();

            var outerEvaluationContext      = Evaluation.ContextFromProperties(insertionEntityProperties, ID, SequenceNumber, _random, Globals, _logger);
            var evaluatedTemplateProperties = template.Map.Properties.ToDictionary(
                kv => Evaluation.EvaluateInterpolatedString(kv.Key, outerEvaluationContext),
                kv => PropertyExtensions.ParseProperty(Evaluation.EvaluateInterpolatedString(kv.Value, outerEvaluationContext)));

            _evaluationContext = new EvaluationContext(evaluatedTemplateProperties, outerEvaluationContext);

            // Every instantiation is written to the same map, but with a different transform:
            OutputMap = parentContext?.OutputMap;
            if (OutputMap == null)
            {
                // Copy original map properties:
                OutputMap = new Map();
                foreach (var kv in evaluatedTemplateProperties)
                {
                    OutputMap.Properties[kv.Key] = Interpreter.Print(kv.Value);
                }
            }
        }
Exemplo n.º 3
0
        private void ApplyRewriteRule(Dictionary <string, string> entityProperties, RewriteDirective.Rule rule, EvaluationContext context)
        {
            var attributeName = Evaluation.EvaluateInterpolatedString(rule.Attribute, context);

            if (rule.DeleteAttribute)
            {
                entityProperties.Remove(attributeName);
                context.Bind(attributeName, null);
            }
            else
            {
                var value = Evaluation.EvaluateInterpolatedString(rule.NewValue, context);
                entityProperties[attributeName] = value;
                context.Bind(attributeName, value);
            }
        }
Exemplo n.º 4
0
        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);
                    }
                }
            }
        }
Exemplo n.º 5
0
 /// <summary>
 /// Calls <see cref="Evaluation.EvaluateInterpolatedString(string, EvaluationContext)"/>, using this instance's evaluation context.
 /// </summary>
 public string EvaluateInterpolatedString(string interpolatedString) => Evaluation.EvaluateInterpolatedString(interpolatedString, _evaluationContext);