4 using System.Collections.Generic;
6 using System.Reflection;
8 using SiliconStudio.Core;
9 using SiliconStudio.Paradox.Effects;
11 namespace SiliconStudio.
Paradox.Shaders
19 private readonly Stack<ParameterCollection> propertyContainers =
new Stack<ParameterCollection>();
20 private readonly Dictionary<string, IShaderMixinBuilder> registeredBuilders;
21 private readonly Dictionary<object, object> strippedPropertyContainers =
new Dictionary<object, object>();
22 private readonly Stack<ShaderMixinParameters> currentUsedParameters =
new Stack<ShaderMixinParameters>();
23 private readonly List<ShaderMixinParameters> finalUsedParameters =
new List<ShaderMixinParameters>();
24 private readonly Stack<string> shaderNames =
new Stack<string>();
25 private readonly Stack<HashSet<ParameterKey>> blackListKeys =
new Stack<HashSet<ParameterKey>>();
26 private readonly Stack<ParameterCollection> currentPropertyContainers =
new Stack<ParameterCollection>();
41 if (defaultPropertyContainer == null)
42 throw new ArgumentNullException(
"defaultPropertyContainer");
44 if (registeredBuilders == null)
45 throw new ArgumentNullException(
"registeredBuilders");
48 this.defaultPropertyContainer = defaultPropertyContainer;
49 this.registeredBuilders = registeredBuilders;
54 shaderNames.Push(shaderBaseName);
55 blackListKeys.Push(
new HashSet<ParameterKey>());
56 currentPropertyContainers.Push(defaultPropertyContainer);
66 propertyContainers.Push(propertyContainer);
74 propertyContainers.Pop();
87 throw new ArgumentNullException(
"key");
93 foreach (var propertyContainer
in propertyContainers)
95 if (propertyContainer.TryGet(key, out value))
97 sourcePropertyContainer = propertyContainer;
103 sourcePropertyContainer = defaultPropertyContainer;
104 value = currentPropertyContainers.Peek().Get(key);
106 if (!blackListKeys.Peek().Contains(key))
107 currentUsedParameters.Peek().Set(key, value);
112 var stripPropertyContainer = (
ParameterCollection)ReplicateContainer(sourcePropertyContainer);
114 if (!stripPropertyContainer.ContainsKey(key))
116 var stripValue = value;
117 if (IsPropertyContainer(value))
119 stripValue = (T)ReplicateContainer(value);
121 stripPropertyContainer.Set(key, stripValue);
138 while (currentUsedParameters.Count > 0)
139 finalUsedParameters.Add(currentUsedParameters.Pop());
140 return finalUsedParameters;
143 private bool IsPropertyContainer(
object source)
148 private object ReplicateContainer(
object source)
150 object objectToReplicate = null;
151 if (!strippedPropertyContainers.TryGetValue(source, out objectToReplicate))
159 var containers = source as ParameterCollection[];
160 if (containers != null)
163 for (
int i = 0; i < containers.Length; i++)
167 objectToReplicate = containers;
171 strippedPropertyContainers.Add(source, objectToReplicate);
173 return objectToReplicate;
179 throw new ArgumentNullException(
"key");
181 var propertyContainer = propertyContainers.Count > 0 ? propertyContainers.Peek() : currentPropertyContainers.Peek();
182 propertyContainer.Set(key, value);
184 if (propertyContainers.Count == 0)
185 blackListKeys.Peek().Add(key);
195 var mixinParent = mixinTree.Mixin;
196 for (
int i = mixinParent.Mixins.Count - 1; i >= 0; i--)
198 var mixin = mixinParent.Mixins[i];
199 if (mixin.ClassName == name)
201 mixinParent.Mixins.RemoveAt(i);
216 if (!registeredBuilders.TryGetValue(name, out builder))
224 if (genericParameters.Length != 0)
226 throw new InvalidOperationException(
string.Format(
"Generic Parameters are not supported with [{0}]", builder.GetType().GetTypeInfo().Name));
228 builder.Generate(mixinTree,
this);
237 var parentName = shaderNames.Peek();
238 var childName = parentName +
"." + subMixin.Name;
240 shaderNames.Push(childName);
243 var blk =
new HashSet<ParameterKey>();
244 foreach (var blackKey
in blackListKeys.Peek())
246 blackListKeys.Push(blk);
249 var pc =
new ParameterCollection();
250 currentPropertyContainers.Peek().CopyTo(pc);
251 currentPropertyContainers.Push(pc);
259 if (currentUsedParameters.Count > 1)
261 var childUsedParameters = currentUsedParameters.Pop();
262 var parentUsedParameters = currentUsedParameters.Peek();
263 parentUsedParameters.CopyTo(childUsedParameters);
264 currentUsedParameters.Push(childUsedParameters);
275 currentPropertyContainers.Pop();
276 finalUsedParameters.Add(currentUsedParameters.Pop());
286 mixinTree.Mixin.CloneFrom(shaderMixinSource);
Parameters used for mixin.
A mixin performing a combination of ShaderClassSource and other mixins.
Contains a tree of ShaderMixinSource.
ShaderMixinContext(ParameterCollection defaultPropertyContainer, Dictionary< string, IShaderMixinBuilder > registeredBuilders, string shaderBaseName)
Initializes a new instance of the ShaderMixinContext class.
Represents a container that can hold properties, lightweight to embed (lazy initialized).
A context used when mixin ShaderSource.
Key of an gereric effect parameter.
void Mixin(ShaderMixinSourceTree mixinTree, ShaderMixinSource shaderMixinSource)
Mixins a ShaderMixinSource into the specified mixin tree.
List< ShaderMixinParameters > GetUsedParameters()
void BeginChild(ShaderMixinSourceTree subMixin)
Creates a new ParameterCollection for a child shader.
ShaderMixinParameters GetMainUsedParameters()
Gets all parameters used by this context when mixin a shader.
void Mixin(ShaderMixinSourceTree mixinTree, string name, params object[] genericParameters)
Mixins a ShaderClassSource identified by its name/generic parameters into the specified mixin tree...
void PopParameters()
Pops the parameters collection.
void EndChild()
Ends the computation of the child mixin and store the used parameters.
void CloneProperties()
Copy the properties of the parent to the calling clone.
Interface to be implemented for dynamic mixin generation.
void RemoveMixin(ShaderMixinSourceTree mixinTree, string name)
Removes the specified mixin from this instance.
A container to handle a hierarchical collection of effect variables.
A shader class used for mixin.