/// <summary> /// Internal ctor that allows for overriding the default continue strategy. /// </summary> /// <param name="nodes"></param> /// <param name="continueStrategy"></param> internal SelectorTreeNode(IEnumerable <TreeNode <TContextType> > nodes, ICompositeContinuationStrategy continueStrategy) : base(nodes) { if (continueStrategy == null) { throw new ArgumentNullException(nameof(continueStrategy)); } EvaluationEnumerator = new EvaluationEnumeratorMediator <TContextType>(CompositionNodes.GetEnumerator(), continueStrategy); }
/// <summary> /// Load the shader and extract the information. /// </summary> public void PrepareNode(ConcurrentDictionary <string, string> projectShaders) { if (!MixinReference.HasLocation()) { return; } var newGenerics = new GenericDictionary(); var newCompositionNodes = new Dictionary <string, IMaterialNode>(); var newMembers = new Dictionary <ParameterKey, object>(); var localMixinName = Path.GetFileNameWithoutExtension(MixinReference.Location); ShaderClassType shader; string source; if (projectShaders.TryGetValue(localMixinName, out source)) { shader = MaterialNodeClassLoader.GetLoader().ParseShader(source); } else { shader = MaterialNodeClassLoader.GetLoader().GetShader(localMixinName); } if (shader == null) { return; } var acceptLinkedVariable = true; foreach (var generic in shader.ShaderGenerics) { if (generic.Type.Name.Text == "float4") { AddKey <Vector4>(generic.Name.Text, newGenerics); } else if (generic.Type.Name.Text == "float3") { AddKey <Vector3>(generic.Name.Text, newGenerics); } else if (generic.Type.Name.Text == "float2") { AddKey <Vector2>(generic.Name.Text, newGenerics); } else if (generic.Type.Name.Text == "float") { AddKey <float>(generic.Name.Text, newGenerics); } else if (generic.Type.Name.Text == "int") { AddKey <int>(generic.Name.Text, newGenerics); } else if (generic.Type.Name.Text == "Texture2D") { AddKey <Texture2D>(generic.Name.Text, newGenerics); } else if (generic.Type.Name.Text == "SamplerState") { AddKey <SamplerState>(generic.Name.Text, newGenerics); } else { AddKey <string>(generic.Name.Text, newGenerics); } if (generic.Type is LinkType) { acceptLinkedVariable = false; // since the behavior is unpredictable, safely prevent addition of linked variable (= with Link annotation) } } foreach (var member in shader.Members.OfType <Variable>()) { // TODO: enough detect compositions? if (member.Type is TypeName && (member.Type.TypeInference == null || member.Type.TypeInference.TargetType == null)) { // ComputeColor only if (member.Type.Name.Text == "ComputeColor") { if (CompositionNodes.ContainsKey(member.Name.Text)) { newCompositionNodes.Add(member.Name.Text, CompositionNodes[member.Name.Text]); } else { newCompositionNodes.Add(member.Name.Text, null); } } } else { var isColor = false; string linkName = null; var isStage = member.Qualifiers.Contains(ParadoxStorageQualifier.Stage); var isStream = member.Qualifiers.Contains(ParadoxStorageQualifier.Stream); foreach (var annotation in member.Attributes.OfType <SiliconStudio.Shaders.Ast.Hlsl.AttributeDeclaration>()) { if (annotation.Name == "Color") { isColor = true; } if (acceptLinkedVariable && annotation.Name == "Link" && annotation.Parameters.Count > 0) { linkName = (string)annotation.Parameters[0].Value; } } if (!isStream && (isStage || !string.IsNullOrEmpty(linkName))) { if (linkName == null) { linkName = localMixinName + "." + member.Name.Text; } var memberType = member.Type.ResolveType(); if (isColor) { AddMember <Color4>(linkName, newMembers); } else if (memberType == ScalarType.Float || memberType == ScalarType.Half) { AddMember <float>(linkName, newMembers); } else if (memberType == ScalarType.Double) { AddMember <double>(linkName, newMembers); } else if (memberType == ScalarType.Int) { AddMember <int>(linkName, newMembers); } else if (memberType == ScalarType.UInt) { AddMember <uint>(linkName, newMembers); } else if (memberType == ScalarType.Bool) { AddMember <bool>(linkName, newMembers); } else if (memberType is VectorType) { switch (((VectorType)memberType).Dimension) { case 2: AddMember <Vector2>(linkName, newMembers); break; case 3: AddMember <Vector3>(linkName, newMembers); break; case 4: AddMember <Vector4>(linkName, newMembers); break; } } else if (member.Type.Name.Text == "Texture2D") { AddMember <Graphics.Texture>(linkName, newMembers); } else if (member.Type.Name.Text == "SamplerState") { AddMember <Graphics.SamplerState>(linkName, newMembers); } } } } Generics = newGenerics; CompositionNodes = newCompositionNodes; Members = newMembers; }
/// <inheritdoc /> public override IEnumerator <TreeNode <TContextType> > GetEnumerator() { return(CompositionNodes.GetEnumerator()); }