Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
ParameterKeys.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.Reflection;
6 
7 namespace SiliconStudio.Paradox.Effects
8 {
9  public static class ParameterKeys
10  {
11  /// <summary>
12  /// Creates a value key.
13  /// </summary>
14  /// <typeparam name="T"></typeparam>
15  /// <param name="defaultValue">The default value.</param>
16  /// <param name="name"></param>
17  /// <returns></returns>
18  public static ParameterKey<T> New<T>(T defaultValue, string name = null)
19  {
20  if (name == null)
21  name = string.Empty;
22 
23  var length = typeof(T).IsArray ? (defaultValue != null ? ((Array)(object)defaultValue).Length : -1) : 1;
24  var metadata = new ParameterKeyMetadata<T>(defaultValue);
25  var result = new ParameterKey<T>(name, length, metadata);
26  return result;
27  }
28 
29  public static ParameterKey<T> New<T>()
30  {
31  return New<T>(default(T));
32  }
33 
34  internal static ParameterKey<T> New<T>(string name)
35  {
36  return New<T>(default(T), name);
37  }
38 
39  public static ParameterKey<T> NewDynamic<T>(ParameterDynamicValue<T> dynamicValue, string name = null)
40  {
41  if (name == null)
42  name = string.Empty;
43 
44  var metadata = new ParameterKeyMetadata<T>(dynamicValue);
45  var result = new ParameterKey<T>(name, 1, metadata);
46  return result;
47  }
48 
49  public static ParameterKey<T[]> NewDynamic<T>(int arraySize, ParameterDynamicValue<T[]> dynamicValue, string name = null) where T : struct
50  {
51  if (name == null)
52  name = string.Empty;
53 
54  var metadata = new ParameterKeyMetadata<T[]>(dynamicValue);
55  var result = new ParameterKey<T[]>(name, arraySize, metadata);
56  return result;
57  }
58 
59  /// <summary>
60  /// Creates the key with specified index.
61  /// </summary>
62  /// <param name="index">The index.</param>
63  /// <returns></returns>
64  public static ParameterKey<T> IndexedKey<T>(ParameterKey<T> key, int index)
65  {
66  if (index == 0)
67  return key;
68 
69  string keyName;
70 
71  if (key.Name[key.Name.Length - 1] == '0')
72  {
73  keyName = key.Name.Substring(0, key.Name.Length - 1) + index;
74  }
75  else
76  {
77  keyName = key.Name + index;
78  }
79 
80  return New<T>(default(T), keyName);
81  }
82 
83  private static Dictionary<string, ParameterKey> keyByNames = new Dictionary<string,ParameterKey>();
84 
85  public static ParameterKey Merge(ParameterKey key, Type ownerType, string name)
86  {
87  lock (keyByNames)
88  {
89  /*if (keyByNames.TryGetValue(name, out duplicateKey))
90  {
91  if (duplicateKey.PropertyType != key.PropertyType)
92  {
93  // TODO: For now, throw an exception, but we should be nicer about it
94  // (log and allow the two keys to co-exist peacefully?)
95  throw new InvalidOperationException("Two ParameterKey with same name but different types have been initialized.");
96  }
97  return key;
98  }*/
99 
100  if (string.IsNullOrEmpty(key.Name))
101  key.SetName(name);
102  keyByNames[name] = key;
103 
104  if (key.OwnerType == null && ownerType != null)
105  key.SetOwnerType(ownerType);
106  }
107  return key;
108  }
109 
110  public static T AppendKey<T>(this T key, object name) where T : ParameterKey
111  {
112  return (T)FindByName(key.Name + name);
113  }
114 
115  public static ParameterKey FindByName(string name)
116  {
117  lock (keyByNames)
118  {
119  ParameterKey key;
120  keyByNames.TryGetValue(name, out key);
121  if (key == null)
122  {
123  var firstDot = name.IndexOf('.');
124  if (firstDot == -1)
125  return null;
126 
127  var subKeyNameIndex = name.IndexOfAny(new[] { '.', '[' }, firstDot + 1);
128  if (subKeyNameIndex == -1)
129  subKeyNameIndex = name.Length;
130 
131  // Ignore digits at ending
132  while (subKeyNameIndex > 0 && char.IsDigit(name, subKeyNameIndex - 1))
133  subKeyNameIndex--;
134 
135  if (subKeyNameIndex != name.Length)
136  {
137  string keyName = name.Substring(0, subKeyNameIndex);
138  string subKeyName = subKeyNameIndex != -1 ? name.Substring(subKeyNameIndex) : null;
139 
140  // It is possible this key has been appended with mixin path (i.e. Test becomes Test.mixin[0])
141  // if it was not a "stage" value
142  if (keyByNames.TryGetValue(keyName, out key) && subKeyName != "0")
143  {
144  var realName = key.Name != keyName ? key.Name + subKeyName : name;
145 
146  var baseParameterKeyType = key.GetType();
147  while (baseParameterKeyType.GetGenericTypeDefinition() != typeof(ParameterKey<>))
148  baseParameterKeyType = baseParameterKeyType.GetTypeInfo().BaseType;
149 
150  // Get default value and use it for the new subkey
151  var defaultValue = key.DefaultMetadata.DefaultDynamicValue ?? key.DefaultMetadata.GetDefaultValue();
152 
153  // Create metadata
154  var metadataParameters = defaultValue != null ? new[] { defaultValue } : new object[0];
155  var metadata = Activator.CreateInstance(typeof(ParameterKeyMetadata<>).MakeGenericType(baseParameterKeyType.GetTypeInfo().GenericTypeArguments[0]), metadataParameters);
156 
157  var args = new[] { name, metadata };
158  if (key.GetType().GetGenericTypeDefinition() == typeof(ParameterKey<>))
159  {
160  args = new[] { name, key.Length, metadata };
161  }
162  key = (ParameterKey)Activator.CreateInstance(key.GetType(), args);
163 
164  // Register key. Also register real name in case it was remapped.
165  keyByNames[name] = key;
166  if (name != realName)
167  keyByNames[realName] = key;
168  }
169  }
170  }
171 
172  return key;
173  }
174  }
175  }
176 }
Key of an effect parameter.
Definition: ParameterKey.cs:15
Type OwnerType
Gets the type of the owner.
Definition: PropertyKey.cs:108
string Name
Gets the name of this key.
Definition: PropertyKey.cs:60
Key of an gereric effect parameter.
_In_ size_t _In_ const TexMetadata & metadata
Definition: DirectXTexP.h:116
static ParameterKey Merge(ParameterKey key, Type ownerType, string name)
Base class for ParameterDynamicValue{T}.
static ParameterKey FindByName(string name)