Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
ParameterKey.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 SiliconStudio.Core;
6 using System.Reflection;
7 using SiliconStudio.Core.Serialization.Serializers;
8 using SiliconStudio.Core.Storage;
9 
10 namespace SiliconStudio.Paradox.Effects
11 {
12  /// <summary>
13  /// Key of an effect parameter.
14  /// </summary>
15  public abstract class ParameterKey : PropertyKey
16  {
17  public ulong HashCode;
18 
19  /// <summary>
20  /// Initializes a new instance of the <see cref="ParameterKey"/> class.
21  /// </summary>
22  /// <param name="name">The name.</param>
23  /// <param name="parameterKeyMetadata">Associated metadatas</param>
24  protected ParameterKey(Type propertyType, string name, int length, ParameterKeyMetadata parameterKeyMetadata)
25  : base(name, propertyType, null, parameterKeyMetadata)
26  {
27  Length = length;
28  // Cache hashCode for faster lookup (string is immutable)
29  // TODO: Make it unique (global dictionary?)
30  UpdateName();
31 
32  DefaultMetadata = parameterKeyMetadata;
33  }
34 
36 
37  /// <summary>
38  /// Gets the number of elements for this key.
39  /// </summary>
40  public int Length { get; private set; }
41 
42  internal void SetName(string name)
43  {
44  if (name == null) throw new ArgumentNullException("name");
45 
46 #if SILICONSTUDIO_PLATFORM_WINDOWS_RUNTIME
47  Name = name;
48 #else
49  Name = string.Intern(name);
50 #endif
51  UpdateName();
52  }
53 
54  internal void SetOwnerType(Type ownerType)
55  {
56  OwnerType = ownerType;
57  }
58 
59  /// <summary>
60  /// Determines whether the specified <see cref="System.Object"/> is equal to this instance.
61  /// </summary>
62  /// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
63  /// <returns>
64  /// <c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.
65  /// </returns>
66  public override bool Equals(object obj)
67  {
68  //return ReferenceEquals(this, obj);
69  if (ReferenceEquals(null, obj)) return false;
70  if (ReferenceEquals(this, obj)) return true;
71  var against = obj as ParameterKey;
72  if (against == null) return false;
73  return (Equals(against.Name, Name));
74  }
75 
76  /// <summary>
77  /// Returns a hash code for this instance.
78  /// </summary>
79  /// <returns>
80  /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
81  /// </returns>
82  public override int GetHashCode()
83  {
84  return (int)HashCode;
85  }
86 
87  /// <summary>
88  /// Implements the operator ==.
89  /// </summary>
90  /// <param name="left">The left.</param>
91  /// <param name="right">The right.</param>
92  /// <returns>
93  /// The result of the operator.
94  /// </returns>
95  public static bool operator ==(ParameterKey left, ParameterKey right)
96  {
97  return Equals(left, right);
98  }
99 
100  /// <summary>
101  /// Implements the operator !=.
102  /// </summary>
103  /// <param name="left">The left.</param>
104  /// <param name="right">The right.</param>
105  /// <returns>
106  /// The result of the operator.
107  /// </returns>
108  public static bool operator !=(ParameterKey left, ParameterKey right)
109  {
110  return !Equals(left, right);
111  }
112 
113  //public abstract ParameterKey AppendKeyOverride(object obj);
114 
115  public virtual ParameterKey CloneLength(int length)
116  {
117  throw new InvalidOperationException();
118  }
119 
120  private unsafe void UpdateName()
121  {
122  fixed (char* bufferStart = Name)
123  {
124  var objectIdBuilder = new ObjectIdBuilder();
125  objectIdBuilder.Write((byte*)bufferStart, sizeof(char) * Name.Length);
126 
127  var objId = objectIdBuilder.ComputeHash();
128  var objIdData = (ulong*)&objId;
129  HashCode = objIdData[0] ^ objIdData[1];
130  }
131  }
132 
133  /// <summary>
134  /// Converts the value passed by parameter to the expecting value of this parameter key (for example, if value is
135  /// an integer while this parameter key is expecting a float)
136  /// </summary>
137  /// <param name="value">The value.</param>
138  /// <returns>System.Object.</returns>
139  public object ConvertValue(object value)
140  {
141  // If not a value type, return the value as-is
142  if (!PropertyType.GetTypeInfo().IsValueType)
143  {
144  return value;
145  }
146 
147  if (value != null)
148  {
149  // If target type is same type, then return the value directly
150  if (PropertyType == value.GetType())
151  {
152  return value;
153  }
154 
155  if (PropertyType.GetTypeInfo().IsEnum)
156  {
157  value = Enum.Parse(PropertyType, value.ToString());
158  }
159  }
160 
161  // Convert the value to the target type if different
162  value = Convert.ChangeType(value, PropertyType);
163  return value;
164  }
165 
166  internal abstract ParameterCollection.InternalValue CreateInternalValue();
167  }
168 
169  /// <summary>
170  /// Key of an gereric effect parameter.
171  /// </summary>
172  /// <typeparam name="T">Type of the parameter key.</typeparam>
173  [DataSerializer(typeof(ParameterKeySerializer<>), Mode = DataSerializerGenericMode.GenericArguments)]
174  public sealed class ParameterKey<T> : ParameterKey
175  {
176  private static bool isValueType = typeof(T).GetTypeInfo().IsValueType;
177  private static bool isValueArrayType = typeof(T).GetTypeInfo().IsArray && typeof(T).GetElementType().GetTypeInfo().IsValueType;
178  private static Type internalValueArrayType = isValueArrayType ? typeof(ParameterCollection.InternalValueArray<>).MakeGenericType(typeof(T).GetElementType()) : null;
179 
180  public override bool IsValueType
181  {
182  get { return isValueType; }
183  }
184 
185  /// <summary>
186  /// Initializes a new instance of the <see cref="ParameterKey{T}"/> class.
187  /// </summary>
188  /// <param name="name">The name.</param>
189  /// <param name="parameterKeyMetadata">Associated metadatas</param>
190  public ParameterKey(string name, int length = 1, ParameterKeyMetadata<T> parameterKeyMetadata = null)
191  : base(typeof(T), name, length, parameterKeyMetadata = parameterKeyMetadata ?? new ParameterKeyMetadata<T>())
192  {
193  DefaultMetadataT = parameterKeyMetadata;
194  }
195 
197 
198  public override string ToString()
199  {
200  return string.Format("{0}", Name);
201  }
202 
203  public override ParameterKey CloneLength(int length)
204  {
205  if (!typeof(T).IsArray)
206  throw new InvalidOperationException("Operation not valid on ParameterKey<T> if T is not an array type.");
207  var elementType = typeof(T).GetElementType();
208  return new ParameterKey<T>(Name, length, new ParameterKeyMetadata<T>((T)(object)Array.CreateInstance(elementType, length)));
209  }
210 
211  internal override ParameterCollection.InternalValue CreateInternalValue()
212  {
213  if (isValueType)
214  return new ParameterCollection.InternalValue<T>();
215 
216  if (isValueArrayType)
217  {
218  // Still a slow path for arrays due to generic constraints...
219  return (ParameterCollection.InternalValue)Activator.CreateInstance(internalValueArrayType, Length);
220  }
221 
222  return new ParameterCollection.InternalValueBase<T>();
223  }
224 
225  internal override PropertyContainer.ValueHolder CreateValueHolder(object value)
226  {
227  throw new NotImplementedException();
228  }
229  }
230 }
Key of an effect parameter.
Definition: ParameterKey.cs:15
virtual ParameterKey CloneLength(int length)
DataSerializerGenericMode
Defines what generic parameters to pass to the serializer.
override int GetHashCode()
Returns a hash code for this instance.
Definition: ParameterKey.cs:82
Key of an gereric effect parameter.
readonly ParameterKeyMetadata< T > DefaultMetadataT
readonly ParameterKeyMetadata DefaultMetadata
Definition: ParameterKey.cs:35
ParameterKey(string name, int length=1, ParameterKeyMetadata< T > parameterKeyMetadata=null)
Initializes a new instance of the ParameterKey{T} class.
The type of the serialized type will be passed as a generic arguments of the serializer. Example: serializer of A becomes instantiated as Serializer{A}.
override ParameterKey CloneLength(int length)
override bool Equals(object obj)
Determines whether the specified System.Object is equal to this instance.
Definition: ParameterKey.cs:66
object ConvertValue(object value)
Converts the value passed by parameter to the expecting value of this parameter key (for example...
ParameterKey(Type propertyType, string name, int length, ParameterKeyMetadata parameterKeyMetadata)
Initializes a new instance of the ParameterKey class.
Definition: ParameterKey.cs:24
A class that represents a tag propety.
Definition: PropertyKey.cs:17
A container to handle a hierarchical collection of effect variables.