public void TryGetValueTest() { NamedObjectCollection <NamedTestObject> collection = new NamedObjectCollection <NamedTestObject>(); collection.Add(new NamedTestObject("foo1", 1)); collection.Add(new NamedTestObject("foo2", 2)); NamedTestObject namedObject; Assert.IsTrue(collection.TryGet("foo2", out namedObject)); Assert.AreEqual(2, namedObject.Value); Assert.IsFalse(collection.TryGet("not existing", out namedObject)); Assert.IsNull(namedObject); // Test with other comparer and without internal Dictionary. collection = new NamedObjectCollection <NamedTestObject>(StringComparer.InvariantCultureIgnoreCase, 5); Assert.IsFalse(collection.TryGet("notExisting", out namedObject)); collection.Add(new NamedTestObject("foo1", 1)); collection.Add(new NamedTestObject("foo2", 2)); Assert.IsTrue(collection.TryGet("foo2", out namedObject)); Assert.AreEqual(2, namedObject.Value); Assert.IsFalse(collection.TryGet("notExisting", out namedObject)); }
/// <summary> /// Gets a particle parameter with the specified type and name. (If the type is wrong an /// exception is thrown.) /// </summary> /// <typeparam name="T">The type of the parameter value.</typeparam> /// <param name="name">The name of the parameter (e.g. "Color", "Position", etc.).</param> /// <param name="excludeInherited"> /// If set to <see langword="true"/> only parameters of this /// <see cref="ParticleParameterCollection"/> are returned. If set to <see langword="false"/> /// the parent particle systems are also scanned for uniform particle parameters with the /// specified name. /// </param> /// <returns> /// The particle parameter, or <see langword="null"/> if no particle parameter with the given /// <paramref name="name"/> was found. /// </returns> /// <exception cref="ParticleSystemException"> /// A particle parameter with the given name was found, but the parameter type cannot be cast to /// type <typeparamref name="T"/>. /// </exception> public IParticleParameter <T> Get <T>(string name, bool excludeInherited) { // Do not throw exception. Simply return null. This simplifies ParticleEffectors. if (string.IsNullOrEmpty(name)) { return(null); } IParticleParameter parameter; _collection.TryGet(name, out parameter); if (parameter == null) { if (!excludeInherited) { if (ParticleSystem.Parent != null) { // Search the parent particle systems - but only accept uniform parameters. var parameterTyped = ParticleSystem.Parent.Parameters.Get <T>(name, false); if (parameterTyped != null && parameterTyped.Values == null) { return(parameterTyped); } } } return(null); } else { var parameterTyped = parameter as IParticleParameter <T>; if (parameterTyped != null) { return(parameterTyped); } // Invalid type. string message = string.Format(CultureInfo.InvariantCulture, "The particle parameter '{0}' cannot be cast to '{1}'.", name, typeof(T).Name); throw new ParticleSystemException(message) { ParticleSystem = ParticleSystem, ParticleParameter = name, }; } }
public void GenericTryGetValueTest() { NamedObjectCollection<NamedTestObject> collection = new NamedObjectCollection<NamedTestObject>(); collection.Add(new NamedTestObject("foo1", 1)); collection.Add(new NamedTestObject("foo2", 2)); collection.Add(new DerivedNamedTestObject("foo3", 3)); NamedTestObject namedObject; Assert.IsTrue(collection.TryGet<NamedTestObject>("foo2", out namedObject)); Assert.AreEqual(2, namedObject.Value); Assert.IsTrue(collection.TryGet<NamedTestObject>("foo3", out namedObject)); Assert.AreEqual(3, namedObject.Value); DerivedNamedTestObject derivedObject; Assert.IsFalse(collection.TryGet<DerivedNamedTestObject>("not existing", out derivedObject)); Assert.IsNull(derivedObject); Assert.IsFalse(collection.TryGet<DerivedNamedTestObject>("foo2", out derivedObject)); Assert.IsNull(derivedObject); Assert.IsTrue(collection.TryGet<DerivedNamedTestObject>("foo3", out derivedObject)); Assert.AreEqual(3, derivedObject.Value); // Test with other comparer and without internal Dictionary. collection = new NamedObjectCollection<NamedTestObject>(StringComparer.InvariantCultureIgnoreCase, 5); collection.Add(new NamedTestObject("foo1", 1)); collection.Add(new NamedTestObject("foo2", 2)); collection.Add(new DerivedNamedTestObject("foo3", 3)); Assert.IsFalse(collection.TryGet<DerivedNamedTestObject>("not existing", out derivedObject)); Assert.IsNull(derivedObject); Assert.IsFalse(collection.TryGet<DerivedNamedTestObject>("foo2", out derivedObject)); Assert.IsNull(derivedObject); Assert.IsTrue(collection.TryGet<DerivedNamedTestObject>("foo3", out derivedObject)); Assert.AreEqual(3, derivedObject.Value); }
/// <summary> /// Requests the completion window. /// </summary> /// <param name="key">The last typed character that was not yet inserted in the document or '\0'.</param> /// <param name="explicitRequest"> /// If set to <see langword="true"/> this is an explicit request to show the window; if <see langword="false"/> /// the user is typing. /// </param> private void RequestCompletionWindow(char key, bool explicitRequest) { // ----- Determine ShaderRegion of current caret position. var document = _textEditor.Document; int caretOffset = _textEditor.CaretOffset; IList <NamedCompletionData> collectedIdentifiers; IList <NamedCompletionData> collectedFields; ShaderRegion region = _parser.IdentifyRegion(document, caretOffset, out collectedIdentifiers, out collectedFields); // ----- Abort if current region has no IntelliSense. switch (region) { case ShaderRegion.Unknown: case ShaderRegion.Assembler: case ShaderRegion.LineComment: case ShaderRegion.BlockComment: case ShaderRegion.String: case ShaderRegion.CharacterLiteral: // No IntelliSense for these regions. return; } // ----- # --> PreprocessorCompletionData if (key == '#') { char characterBeforeHash = (caretOffset > 0) ? document.GetCharAt(caretOffset - 1) : '\0'; if (characterBeforeHash == '\0' || char.IsWhiteSpace(characterBeforeHash)) { ShowCompletionWindow(PreprocessorCompletionData, null, '#'); } return; } // ----- Abort if a key is set and it is not part of an identifier. bool letterDigitOrUnderscorePressed = (TextUtilities.GetCharacterClass(key) == CharacterClass.IdentifierPart); if (key != '\0' && !letterDigitOrUnderscorePressed) { _completionWindow?.Close(); return; } // ----- Find the symbol immediately before the caret. string symbol; int offset = TextUtilities.FindStartOfIdentifier(document, caretOffset - 1); if (offset >= 0) { symbol = document.GetText(offset, caretOffset - offset); } else { symbol = string.Empty; offset = caretOffset; } // ----- Find the character before the symbol. --offset; char previousCharacter = (offset >= 0) ? document.GetCharAt(offset) : '\0'; // ----- #xxxx --> PreprocessorCompletionData // Check for preprocessor directives if (previousCharacter == '#') { --offset; char characterBeforeHash = (0 <= offset) ? document.GetCharAt(offset) : '\0'; if (characterBeforeHash == '\0' || char.IsWhiteSpace(characterBeforeHash)) { symbol = '#' + symbol; ShowCompletionWindow(PreprocessorCompletionData, symbol, key); } return; } // ----- xxxxx. --> MemberCompletionData and guessed fields. // Check for object members such as "myTexture.|" if (previousCharacter == '.') { if (region == ShaderRegion.StructureOrInterface || region == ShaderRegion.Code) { --offset; bool showCompletionWindow = false; char characterBeforeDot = (0 <= offset) ? document.GetCharAt(offset) : '\0'; if (characterBeforeDot == ']' || characterBeforeDot == ')') { // Looks like something similar to "myArray[n].|" or "GetTexture(n).|". // We assume that a member is requested. showCompletionWindow = true; } else { // Check if we have something like "myVariable.|" string objectName = TextUtilities.GetIdentifierAt(document, offset); if (!string.IsNullOrEmpty(objectName) && !Keywords.Contains(objectName) && !_parser.IsType(objectName)) { showCompletionWindow = true; } } if (showCompletionWindow) { ShowCompletionWindow(MergeCompletionData(MemberCompletionData, collectedFields), symbol, key); } } return; } // ----- Get non-whitespace character before symbol. char previousNonWhitespaceChar = previousCharacter; if (char.IsWhiteSpace(previousNonWhitespaceChar) && offset > 0) { offset = _parser.SkipWhiteSpaceBackwards(document, offset - 1); previousNonWhitespaceChar = document.GetCharAt(offset); } // ----- Check for effect state assignments if (previousNonWhitespaceChar == '=' && _parser.IsStateGroup(region)) { // The line should look like this: // "EffectState = |" --offset; offset = _parser.SkipWhiteSpaceBackwards(document, offset); // Skip index if (document.GetCharAt(offset) == ']') { offset = TextUtilities.FindOpeningBracket(document, offset - 1, '[', ']') - 1; } string stateName = TextUtilities.GetIdentifierAt(document, offset); if (!string.IsNullOrEmpty(stateName)) { // Lookup the state and show the allowed values. NamedObjectCollection <NamedCompletionData> lookupTable = null; switch (region) { case ShaderRegion.BlendState10: lookupTable = BlendStates; break; case ShaderRegion.DepthStencilState10: lookupTable = DepthStencilStates; break; case ShaderRegion.RasterizerState10: lookupTable = RasterizerStates; break; case ShaderRegion.SamplerState: lookupTable = SamplerStates; break; case ShaderRegion.SamplerState10: lookupTable = SamplerStates10; break; case ShaderRegion.TechniqueOrPass: case ShaderRegion.TechniqueOrPass10: case ShaderRegion.StateBlock: lookupTable = EffectStates; break; default: break; } NamedCompletionData state; if (lookupTable != null && lookupTable.TryGet(stateName, out state)) { List <NamedCompletionData> stateValueCompletionData; string[] values = ((StateCompletionData)state).AllowedValues; if (values.Length > 0) { // Add the allowed values for this state to completion data. stateValueCompletionData = new List <NamedCompletionData>(values.Length); foreach (string value in values) { stateValueCompletionData.Add(EffectStateValues[value]); } } else { // This effect state has a generic parameter. // Add types ("bool", "int", etc.) to the completion data. stateValueCompletionData = new List <NamedCompletionData>(ScalarTypes.Count + Types.Count); foreach (NamedCompletionData type in ScalarTypes) { stateValueCompletionData.Add(type); } foreach (NamedCompletionData type in Types) { stateValueCompletionData.Add(type); } } // Add the collected identifiers foreach (NamedCompletionData collectedIdentifier in collectedIdentifiers) { stateValueCompletionData.Add(collectedIdentifier); } ShowCompletionWindow(stateValueCompletionData.ToArray(), symbol, key); return; } } } // If we know nothing about the key, and we are after a blank, we don't want to open // a completion window. // If we have a completion window, we want to continue. // If the user has explicitly request info (e.g. Ctrl+Space) we want to continue. if (key == '\0' && previousCharacter == ' ' && !explicitRequest && _completionWindow == null) { return; } // Show default completion data for each region. ICompletionData[] completionData; switch (region) { case ShaderRegion.Global: completionData = GlobalCompletionData; break; case ShaderRegion.StructureOrInterface: case ShaderRegion.Code: completionData = CodeCompletionData; break; case ShaderRegion.Annotation: completionData = AnnotationCompletionData; break; case ShaderRegion.TechniqueOrPass: case ShaderRegion.TechniqueOrPass10: completionData = TechniqueCompletionData; break; case ShaderRegion.BlendState10: completionData = BlendStateCompletionData; break; case ShaderRegion.DepthStencilState10: completionData = DepthStencilStateCompletionData; break; case ShaderRegion.RasterizerState10: completionData = RasterizerStateCompletionData; break; case ShaderRegion.SamplerState: completionData = SamplerStateCompletionData; break; case ShaderRegion.SamplerState10: completionData = SamplerState10CompletionData; break; case ShaderRegion.StateBlock: completionData = StateBlockCompletionData; break; default: completionData = null; break; } // No data --> close window. if (completionData == null) { _completionWindow?.Close(); return; } // Combine static completion data with guessed identifiers List <ICompletionData> entireCompletionData = new List <ICompletionData>(); foreach (ICompletionData completionEntry in completionData) { entireCompletionData.Add(completionEntry); } foreach (NamedCompletionData collectedIdentifier in collectedIdentifiers) { entireCompletionData.Add(collectedIdentifier); } // Show completion window ShowCompletionWindow(MergeCompletionData(completionData, collectedIdentifiers), symbol, key); }