Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
ShaderKeyGeneratorBase.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using System.Collections.Generic;
5 using System.Linq;
6 
7 using SiliconStudio.Paradox.Shaders.Parser.Ast;
8 using SiliconStudio.Shaders.Ast;
9 using SiliconStudio.Shaders.Ast.Hlsl;
10 using SiliconStudio.Shaders.Visitor;
11 using SiliconStudio.Shaders.Writer;
12 
14 
15 namespace SiliconStudio.Paradox.Shaders.Parser.Mixins
16 {
18  {
19  /// <summary>
20  /// A flag stating if the currently visited variable is a Color.
21  /// </summary>
22  protected bool IsColorStatus = false;
23 
24  /// <summary>
25  /// A flag stating if the currently visited variable is an array.
26  /// </summary>
27  protected bool IsArrayStatus = false;
28 
29  /// <summary>
30  /// A flag stating if the initial value of the variable should be processed.
31  /// </summary>
32  protected bool ProcessInitialValueStatus = false;
33 
34  /// <summary>
35  /// A flag indicating whether a variable must be transformed to a parameter key
36  /// </summary>
37  protected bool VariableAsParameterKey = true;
38 
39  /// <summary>
40  /// Runs the code generation. Results is accessible from <see cref="ShaderWriter.Text"/> property.
41  /// </summary>
42  public virtual bool Run()
43  {
44  return true;
45  }
46 
47  /// <inheritdoc />
48  [Visit]
49  public override void Visit(Variable variable)
50  {
51  if (VariableAsParameterKey)
52  {
53  WriteVariableAsParameterKey(variable);
54  }
55  else
56  {
57  base.Visit(variable);
58  }
59  }
60 
61  /// <summary>
62  /// Visits the specified namespace block.
63  /// </summary>
64  /// <param name="namespaceBlock">The namespace block.</param>
65  [Visit]
66  protected virtual void Visit(NamespaceBlock namespaceBlock)
67  {
68  WriteLinkLine(namespaceBlock);
69  Write("namespace ").Write(namespaceBlock.Name);
70  OpenBrace();
71  foreach (Node node in namespaceBlock.Body)
72  {
73  VisitDynamic(node);
74  }
75  CloseBrace();
76  }
77 
78  internal bool IsParameterKey(Variable variable)
79  {
80  // Don't generate a parameter key for variable stored storage qualifier: extern, const, compose, stream
81  if (variable.Qualifiers.Contains(SiliconStudio.Shaders.Ast.Hlsl.StorageQualifier.Extern)
82  || variable.Qualifiers.Contains(StorageQualifier.Const)
84  || variable.Qualifiers.Contains(ParadoxStorageQualifier.PatchStream)
86  return false;
87 
88  // Don't generate a parameter key for [Link] or [RenameLink]
89  if (variable.Attributes.OfType<AttributeDeclaration>().Any(x => x.Name == "RenameLink" || x.Name == "Link"))
90  return false;
91 
92  return true;
93  }
94 
95  protected void WriteVariableAsParameterKey(Variable variable)
96  {
97  if (!IsParameterKey(variable))
98  {
99  return;
100  }
101 
102  IsColorStatus = variable.Attributes.OfType<AttributeDeclaration>().Any(x => x.Name == "Color");
103  ProcessInitialValueStatus = false;
104  IsArrayStatus = false;
105 
106  var variableType = variable.Attributes.OfType<AttributeDeclaration>().Where(x => x.Name == "Type").Select(x => (string)x.Parameters[0].Value).FirstOrDefault();
107  var variableMap = variable.Attributes.OfType<AttributeDeclaration>().Where(x => x.Name == "Map").Select(x => (string)x.Parameters[0].Value).FirstOrDefault();
108 
109  Write("public static readonly ParameterKey<");
110  if (variableType == null)
111  VisitDynamic(variable.Type);
112  else
113  Write(variableType);
114  Write("> ");
115  Write(variable.Name);
116  Write(" = ");
117  if (variableMap == null)
118  {
119  Write("ParameterKeys.New<");
120  if (variableType == null)
121  VisitDynamic(variable.Type);
122  else
123  Write(variableType);
124  Write(">(");
125  if (ProcessInitialValueStatus && variable.InitialValue != null)
126  {
127  var initialValueString = variable.InitialValue.ToString();
128 
129  if (initialValueString != "null")
130  {
131  if (IsArrayStatus)
132  {
133  initialValueString = variable.Type.ToString() + initialValueString;
134  }
135 
136  // Rename float2/3/4 to Vector2/3/4
137  if (initialValueString.StartsWith("float2")
138  || initialValueString.StartsWith("float3")
139  || initialValueString.StartsWith("float4"))
140  initialValueString = initialValueString.Replace("float", "new Vector");
141  else if (IsArrayStatus)
142  {
143  initialValueString = "new " + initialValueString;
144  }
145 
146  if (IsColorStatus)
147  {
148  initialValueString = initialValueString.Replace("Vector3", "Color3");
149  initialValueString = initialValueString.Replace("Vector4", "Color4");
150  }
151  }
152  Write(initialValueString);
153  }
154  Write(")");
155  }
156  else
157  {
158  Write(variableMap);
159  }
160  WriteLine(";");
161 
162  IsColorStatus = false;
163  IsArrayStatus = false;
164  ProcessInitialValueStatus = false;
165  }
166 
167  /// <summary>
168  /// Visits the specified type.
169  /// </summary>
170  /// <param name="typeName">the type.</param>
171  [Visit]
172  public override void Visit(TypeName typeName)
173  {
174  var type = typeName.ResolveType();
175  if (ReferenceEquals(typeName, type))
176  {
177  base.Visit(typeName);
178  ProcessInitialValueStatus = true;
179  }
180  else
181  {
182  VisitDynamic(type);
183  }
184  }
185 
186  /// <inheritdoc />
187  [Visit]
188  public override void Visit(ScalarType scalarType)
189  {
190  base.Visit(scalarType);
191  ProcessInitialValueStatus = true;
192  }
193 
194  /// <summary>
195  /// Visits the specified type.
196  /// </summary>
197  /// <param name="type">the type.</param>
198  [Visit]
199  protected virtual void Visit(VectorType type)
200  {
201  var finalTypeName = "Vector" + type.Dimension;
202  if (IsColorStatus)
203  {
204  if (type.Dimension == 3)
205  finalTypeName = "Color3";
206  else if (type.Dimension == 4)
207  finalTypeName = "Color4";
208  else
209  throw new NotSupportedException("Color attribute is only valid for float3/float4.");
210  }
211  Write(finalTypeName);
212  ProcessInitialValueStatus = true;
213  }
214 
215  /// <summary>
216  /// Visits the specified type.
217  /// </summary>
218  /// <param name="type">the type.</param>
219  [Visit]
220  protected virtual void Visit(MatrixType type)
221  {
222  Write("Matrix");
223  ProcessInitialValueStatus = true;
224  }
225 
226  /// <summary>
227  /// Visits the specified type.
228  /// </summary>
229  /// <param name="type">the type.</param>
230  [Visit]
231  protected virtual void Visit(TextureType type)
232  {
233  Write("Texture");
234  }
235 
236  /// <summary>
237  /// Visits the specified type.
238  /// </summary>
239  /// <param name="type">the type.</param>
240  [Visit]
241  protected virtual void Visit(StateType type)
242  {
243  Write("SamplerState");
244  }
245 
246  /// <summary>
247  /// Visits the specified type.
248  /// </summary>
249  /// <param name="type">the type.</param>
250  [Visit]
251  public override void Visit(ArrayType type)
252  {
253  var dimensions = type.Dimensions;
254  if (dimensions.Count != 1)
255  throw new NotSupportedException();
256  /*
257  var expressionEvaluator = new ExpressionEvaluator();
258  if (dimensions.All(x => !(x is EmptyExpression)))
259  {
260  var expressionResult = expressionEvaluator.Evaluate(dimensions[0]);
261  if (expressionResult.HasErrors)
262  throw new InvalidOperationException();
263  Write(expressionResult.Value.ToString());
264  }
265  */
266  VisitDynamic(type.Type);
267  Write("[]");
268  ProcessInitialValueStatus = true;
269  IsArrayStatus = true;
270  }
271 
272  /// <summary>
273  /// Visits the specified type.
274  /// </summary>
275  /// <param name="type">the type.</param>
276  [Visit]
277  protected virtual void Visit(TypeBase type)
278  {
279  Write(type.Name);
280  ProcessInitialValueStatus = true;
281  }
282 
283  protected static bool IsStringInList(string value, params string[] list)
284  {
285  return list.Any(str => string.Compare(value, str, StringComparison.InvariantCultureIgnoreCase) == 0);
286  }
287  }
288 }
static readonly SiliconStudio.Shaders.Ast.StorageQualifier Compose
Compose keyword (compose).
Base class for all vector types
Definition: VectorType.cs:10
Identifier Name
Gets or sets the name.
Definition: Variable.cs:77
virtual bool Run()
Runs the code generation. Results is accessible from ShaderWriter.Text property.
TypeBase Type
Gets or sets the type.
Definition: Variable.cs:61
override void Visit(TypeName typeName)
Visits the specified type.
virtual void Visit(StateType type)
Visits the specified type.
A typeless reference.
Definition: TypeName.cs:10
virtual void Visit(TextureType type)
Visits the specified type.
static readonly SiliconStudio.Shaders.Ast.StorageQualifier Stream
Stream keyword (stream).
virtual void Visit(NamespaceBlock namespaceBlock)
Visits the specified namespace block.
Qualifier Qualifiers
Gets or sets the qualifiers.
Definition: Variable.cs:53
int Dimension
Gets or sets the dimension.
Definition: VectorType.cs:114
override void Visit(ArrayType type)
Visits the specified type.
Abstract node.
Definition: Node.cs:15
virtual void Visit(VectorType type)
Visits the specified type.
SiliconStudio.Shaders.Ast.StorageQualifier StorageQualifier
A variable declaration.
Definition: Variable.cs:11
virtual void Visit(TypeBase type)
Visits the specified type.
Base type for all types.
Definition: TypeBase.cs:11
List< AttributeBase > Attributes
Definition: Variable.cs:45
bool Contains(CompositeEnum enumValue)
Determines whether [contains] [the specified enum value].
Expression InitialValue
Gets or sets the initial value.
Definition: Variable.cs:69
static bool IsStringInList(string value, params string[] list)
TypeBase Type
Gets or sets the type.
Definition: ArrayType.cs:68
virtual void Visit(MatrixType type)
Visits the specified type.
Identifier Name
Gets or sets the type name.
Definition: TypeBase.cs:77