/// <summary>Set a local token value.</summary>
        /// <param name="name">The token name.</param>
        /// <param name="value">The token value.</param>
        /// <param name="ready">Whether to mark the token ready.</param>
        public void SetLocalValue(string name, ITokenString value, bool ready = true)
        {
            // get or create token
            ManagedManualToken managed;

            {
                if (!this.LocalTokens.TryGetValue(name, out managed))
                {
                    this.LocalTokens[name] = managed = new ManagedManualToken(name, this.Scope);
                }
            }

            // update values
            managed.ValueProvider.SetValue(value);
            managed.ValueProvider.SetReady(ready);
        }
Esempio n. 2
0
        /// <summary>Add a dynamic token value to the context.</summary>
        /// <param name="name">The token name.</param>
        /// <param name="rawValue">The token value to set.</param>
        /// <param name="conditions">The conditions that must match to set this value.</param>
        public void AddDynamicToken(string name, IManagedTokenString rawValue, IEnumerable <Condition> conditions)
        {
            // validate
            if (this.ParentContext.Contains(name, enforceContext: false))
            {
                throw new InvalidOperationException($"Can't register a '{name}' token because there's a global token with that name.");
            }
            if (this.LocalContext.Contains(name, enforceContext: false))
            {
                throw new InvalidOperationException($"Can't register a '{name}' dynamic token because there's a config token with that name.");
            }

            // get (or create) token
            if (!this.DynamicTokens.TryGetValue(name, out ManagedManualToken managed))
            {
                managed = new ManagedManualToken(name, this.Scope);
                this.DynamicTokens[name] = managed;
                this.DynamicContext.Save(managed.Token);
            }

            // create token value handler
            var tokenValue = new DynamicTokenValue(managed, rawValue, conditions);

            string[] tokensUsed = tokenValue.GetTokensUsed().ToArray();

            // save value info
            managed.ValueProvider.AddTokensUsed(tokensUsed);
            managed.ValueProvider.AddAllowedValues(rawValue);
            this.DynamicTokenValues.Add(tokenValue);

            // track tokens which should trigger an update to this token
            Queue <string>   tokenQueue = new Queue <string>(tokensUsed);
            InvariantHashSet visited    = new InvariantHashSet();

            while (tokenQueue.Any())
            {
                // get token name
                string usedTokenName = tokenQueue.Dequeue();
                if (!visited.Add(usedTokenName))
                {
                    continue;
                }

                // if the used token uses other tokens, they may affect the one being added too
                IToken usedToken = this.GetToken(usedTokenName, enforceContext: false);
                foreach (string nextTokenName in usedToken.GetTokensUsed())
                {
                    tokenQueue.Enqueue(nextTokenName);
                }

                // add new token as a dependent of the used token
                if (!this.TokenDependents.TryGetValue(usedToken.Name, out InvariantHashSet used))
                {
                    this.TokenDependents.Add(usedToken.Name, used = new InvariantHashSet());
                }
                used.Add(name);
            }

            // track new token
            this.HasNewTokens = true;
        }