/// <summary>Add a dynamic token value to the context.</summary> /// <param name="tokenValue">The token to add.</param> public void Add(DynamicTokenValue tokenValue) { // validate if (this.ParentContext.Contains(tokenValue.Name, enforceContext: false)) { throw new InvalidOperationException($"Can't register a '{tokenValue}' token because there's a global token with that name."); } if (this.LocalContext.Contains(tokenValue.Name, enforceContext: false)) { throw new InvalidOperationException($"Can't register a '{tokenValue.Name}' dynamic token because there's a config token with that name."); } // get (or create) token if (!this.DynamicContext.Tokens.TryGetValue(tokenValue.Name, out DynamicToken token)) { this.DynamicContext.Save(token = new DynamicToken(tokenValue.Name, this.Scope)); } // add token value token.AddTokensUsed(tokenValue.GetTokensUsed()); token.AddAllowedValues(tokenValue.Value); this.DynamicTokenValues.Add(tokenValue); // track tokens which should trigger an update to this token Queue <string> tokenQueue = new Queue <string>(tokenValue.GetTokensUsed()); InvariantHashSet visited = new InvariantHashSet(); while (tokenQueue.Any()) { // get token name string tokenName = tokenQueue.Dequeue(); if (!visited.Add(tokenName)) { continue; } // if the current token uses other tokens, they may affect the being added too IToken curToken = this.GetToken(tokenName, enforceContext: false); foreach (string name in curToken.GetTokensUsed()) { tokenQueue.Enqueue(name); } if (curToken is DynamicToken curDynamicToken) { foreach (string name in curDynamicToken.GetPossibleTokensUsed()) { tokenQueue.Enqueue(name); } } // add dynamic value as a dependency of the current token if (!this.TokenDependents.TryGetValue(curToken.Name, out InvariantHashSet used)) { this.TokenDependents.Add(curToken.Name, used = new InvariantHashSet()); } used.Add(tokenValue.Name); } }
/// <summary>Add a dynamic token value to the context.</summary> /// <param name="tokenValue">The token to add.</param> public void Add(DynamicTokenValue tokenValue) { // validate if (this.GlobalContext.Contains(tokenValue.Name, enforceContext: false)) { throw new InvalidOperationException($"Can't register a '{tokenValue.Name}' token because there's a global token with that name."); } if (this.StandardContext.Contains(tokenValue.Name, enforceContext: false)) { throw new InvalidOperationException($"Can't register a '{tokenValue.Name}' dynamic token because there's a config token with that name."); } // get (or create) token if (!this.DynamicContext.Tokens.TryGetValue(tokenValue.Name, out DynamicToken token)) { this.DynamicContext.Save(token = new DynamicToken(tokenValue.Name)); } // add token value token.AddAllowedValues(tokenValue.Value); this.DynamicTokenValues.Add(tokenValue); }
/// <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; }