Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
ShaderMixinSource.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 using System.Text;
7 
8 using SiliconStudio.Core;
9 
10 namespace SiliconStudio.Paradox.Shaders
11 {
12  /// <summary>
13  /// A mixin performing a combination of <see cref="ShaderClassSource"/> and other mixins.
14  /// </summary>
15  [DataContract]
16  public sealed class ShaderMixinSource : ShaderSource, IEquatable<ShaderMixinSource>
17  {
18  /// <summary>
19  /// Initializes a new instance of the <see cref="ShaderMixinSource"/> class.
20  /// </summary>
22  {
23  Mixins = new List<ShaderClassSource>();
24  Compositions = new Core.Collections.SortedList<string, ShaderSource>();
25  Macros = new List<ShaderMacro>();
26  }
27 
28  /// <summary>
29  /// Gets or sets the name of this mixin source (if this ShaderMixinSource was generated from a <see cref="ShaderMixinGeneratorSource"/>,
30  /// it contains the name of <see cref="ShaderMixinGeneratorSource.Name"/>.
31  /// </summary>
32  /// <value>The name.</value>
33  //public string Name { get; set; }
34 
35  /// <summary>
36  /// Gets or sets the mixins.
37  /// </summary>
38  /// <value>The mixins.</value>
39  public List<ShaderClassSource> Mixins { get; set; }
40 
41  /// <summary>
42  /// Gets or sets the macros.
43  /// </summary>
44  /// <value>The macros.</value>
45  public List<ShaderMacro> Macros { get; set; }
46 
47  /// <summary>
48  /// Gets or sets the compositions.
49  /// </summary>
50  /// <value>The compositions.</value>
51  public Core.Collections.SortedList<string, ShaderSource> Compositions { get; set; }
52 
53  /// <summary>
54  /// Adds a composition to this mixin.
55  /// </summary>
56  /// <param name="name">The name.</param>
57  /// <param name="shaderSource">The shader source.</param>
58  public void AddComposition(string name, ShaderSource shaderSource)
59  {
60  Compositions[name] = shaderSource;
61  }
62 
63  /// <summary>
64  /// Adds a composition to this mixin.
65  /// </summary>
66  /// <param name="name">The name.</param>
67  /// <param name="shaderSource">The shader source element.</param>
68  public void AddCompositionToArray(string name, ShaderSource shaderSourceElement)
69  {
70  ShaderSource shaderSource;
71  if (!Compositions.TryGetValue(name, out shaderSource))
72  Compositions.Add(name, shaderSource = new ShaderArraySource());
73 
74  var shaderArraySource = (ShaderArraySource)shaderSource;
75  shaderArraySource.Add(shaderSourceElement);
76  }
77 
78  /// <summary>
79  /// Adds a macro to this mixin.
80  /// </summary>
81  /// <param name="name">The name.</param>
82  /// <param name="value">The value.</param>
83  public void AddMacro(string name, object value)
84  {
85  Macros.Add(new ShaderMacro(name, value));
86  }
87 
88  /// <summary>
89  /// Clones from the specified <see cref="ShaderMixinSource"/>.
90  /// </summary>
91  /// <param name="parent">The parent mixin to clone from.</param>
92  /// <exception cref="System.ArgumentNullException">parent</exception>
93  public void CloneFrom(ShaderMixinSource parent)
94  {
95  if (parent == null)
96  throw new ArgumentNullException("parent", string.Format("Cannot clone mixin [{0}] from a null parent"));
97 
98  Mixins.AddRange(parent.Mixins);
99  Macros.AddRange(parent.Macros);
100  foreach (var shaderBasic in parent.Compositions)
101  {
102  Compositions[shaderBasic.Key] = shaderBasic.Value;
103  }
104  }
105 
106  /// <summary>
107  /// Clones from the specified <see cref="ShaderMixinSource"/>. Clones members too.
108  /// </summary>
109  /// <param name="parent">The parent mixin to clone from.</param>
110  /// <exception cref="System.ArgumentNullException">parent</exception>
111  public void DeepCloneFrom(ShaderMixinSource parent)
112  {
113  if (parent == null)
114  throw new ArgumentNullException("parent", string.Format("Cannot deep clone mixin [{0}] from a null parent"));
115 
116  foreach (var mixin in parent.Mixins)
117  Mixins.Add((ShaderClassSource)mixin.Clone());
118  Macros.AddRange(parent.Macros);
119  foreach (var shaderBasic in parent.Compositions)
120  {
121  Compositions[shaderBasic.Key] = (ShaderSource)shaderBasic.Value.Clone();
122  }
123  }
124 
125  public override bool Equals(object against)
126  {
127  if (ReferenceEquals(null, against)) return false;
128  if (ReferenceEquals(this, against)) return true;
129  if (against.GetType() != this.GetType()) return false;
130  return Equals((ShaderMixinSource)against);
131  }
132 
133  public bool Equals(ShaderMixinSource other)
134  {
135  if (ReferenceEquals(null, other)) return false;
136  if (ReferenceEquals(this, other)) return true;
137 
138  // Doesn't check for Parent for Children
139  return Utilities.Compare(Mixins, other.Mixins) && Utilities.Compare(Macros, other.Macros) && Utilities.Compare<string, ShaderSource>(Compositions, other.Compositions);
140  }
141  public override int GetHashCode()
142  {
143  unchecked
144  {
145  int hashCode = 0;
146  hashCode = (hashCode * 397) ^ Utilities.GetHashCode(Mixins);
147  hashCode = (hashCode * 397) ^ Utilities.GetHashCode(Macros);
148  hashCode = (hashCode * 397) ^ Utilities.GetHashCode(Compositions);
149  return hashCode;
150  }
151  }
152 
153  public override object Clone()
154  {
155  var newMixin = (ShaderMixinSource)MemberwiseClone();
156  newMixin.Compositions = Compositions == null ? null : ToSortedList(Compositions.Select(x => new KeyValuePair<string, ShaderSource>(x.Key, (ShaderSource)x.Value.Clone())));
157  newMixin.Mixins = Mixins == null ? null : Mixins.Select(x => (ShaderClassSource)x.Clone()).ToList();
158  newMixin.Macros = Macros == null ? null : new List<ShaderMacro>(Macros.ToArray());
159  return newMixin;
160  }
161 
162  private static Core.Collections.SortedList<TKey, TValue> ToSortedList<TKey, TValue>(IEnumerable<KeyValuePair<TKey, TValue>> list)
163  {
164  var values = new Core.Collections.SortedList<TKey, TValue>();
165  foreach(var item in list)
166  values.Add(item.Key, item.Value);
167  return values;
168  }
169 
170  public override string ToString()
171  {
172  var result = new StringBuilder();
173 
174  if (Mixins != null && Mixins.Count > 0)
175  {
176  result.Append(" : ");
177  for (int i = 0; i < Mixins.Count; i++)
178  {
179  if (i > 0)
180  result.Append(", ");
181  result.Append(Mixins[i]);
182  }
183  }
184 
185  if (Compositions != null && Compositions.Count > 0)
186  {
187  result.Append(" [");
188  var keys = Compositions.Keys.ToList();
189  keys.Sort();
190  for (int i = 0; i < keys.Count; i++)
191  {
192  var key = keys[i];
193  if (i > 0)
194  result.Append(", ");
195  result.AppendFormat("{{{0} = {1}}}", key, Compositions[key]);
196  }
197  result.Append("]");
198  }
199  return result.ToString();
200  }
201  }
202 }
SiliconStudio.Paradox.Shaders.ShaderMacro ShaderMacro
void CloneFrom(ShaderMixinSource parent)
Clones from the specified ShaderMixinSource.
static bool Compare(IEnumerable left, IEnumerable right)
Compares two collection, element by elements.
Definition: Utilities.cs:584
A mixin performing a combination of ShaderClassSource and other mixins.
List< ShaderMacro > Macros
Gets or sets the macros.
void AddComposition(string name, ShaderSource shaderSource)
Adds a composition to this mixin.
override object Clone()
Deep clones this instance.
override bool Equals(object against)
Determines whether the specified System.Object is equal to this instance.
static int GetHashCode(IDictionary dict)
Computes a hashcode for a dictionary.
Definition: Utilities.cs:527
void DeepCloneFrom(ShaderMixinSource parent)
Clones from the specified ShaderMixinSource. Clones members too.
An array of ShaderSource used only in shader mixin compositions.
ShaderMixinSource()
Initializes a new instance of the ShaderMixinSource class.
void AddMacro(string name, object value)
Adds a macro to this mixin.
void AddCompositionToArray(string name, ShaderSource shaderSourceElement)
Adds a composition to this mixin.