Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
ParameterUpdater.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.Collections.Generic;
4 
5 namespace SiliconStudio.Paradox.Effects
6 {
7  /// <summary>
8  /// Describes the expected parameters when using a <see cref="ParameterUpdater"/>.
9  /// </summary>
10  internal abstract class ParameterUpdaterDefinition
11  {
12  public ParameterKey[] SortedKeys { get; protected set; }
13 
14  public ulong[] SortedKeyHashes { get; protected set; }
15  }
16 
17  /// <summary>
18  /// Merges and filters parameters coming from multiple <see cref="ParameterCollection"/>.
19  /// </summary>
20  internal class ParameterUpdater
21  {
22  protected KeyValuePair<int, ParameterCollection.InternalValue>[] InternalValues;
23 
24  public ParameterUpdater()
25  {
26  InternalValues = new KeyValuePair<int, ParameterCollection.InternalValue>[8];
27  }
28 
29  public void Update(ParameterUpdaterDefinition definition, ParameterCollection[] parameterCollections, int levelCount)
30  {
31  var sortedKeyHashes = definition.SortedKeyHashes;
32  var sortedKeyHashesLength = sortedKeyHashes.Length;
33  if (sortedKeyHashesLength == 0)
34  return;
35 
36  if (sortedKeyHashesLength > InternalValues.Length)
37  InternalValues = new KeyValuePair<int, ParameterCollection.InternalValue>[sortedKeyHashesLength];
38 
39  // Temporary clear data for debug/test purposes (shouldn't necessary)
40  for (int i = 0; i < sortedKeyHashesLength; ++i)
41  InternalValues[i] = new KeyValuePair<int, ParameterCollection.InternalValue>();
42 
43  // Optimization: List is already prepared (with previous SetKeyMapping() call)
44  var collection = parameterCollections[0];
45  var keys = collection.keys;
46  for (int i = 0; i < keys.Length; ++i)
47  {
48  var internalValue = keys[i];
49  if (internalValue != null)
50  InternalValues[i] = new KeyValuePair<int, ParameterCollection.InternalValue>(0, internalValue);
51  }
52 
53  // Iterate over parameter collections
54  for (int levelIndex = 1; levelIndex < levelCount; ++levelIndex)
55  {
56  var level = parameterCollections[levelIndex].valueList;
57  int index = 0;
58  var currentHash = sortedKeyHashes[index];
59  int internalValueCount = level.Count;
60  var items = level.Items;
61 
62  // Iterate over each items
63  // Since both expected values and parameter collection values are sorted,
64  // we iterate over both of them together so that we can easily detect what needs to be copied.
65  // Note: We use a 64-bit hash that we assume has no collision (maybe we should
66  // detect unlikely collision when registering them?)
67  for (int i = 0; i < internalValueCount; ++i)
68  {
69  var internalValue = items[i];
70  var expectedHash = internalValue.Key.HashCode;
71  //index = InternalValueBinarySearch(sortedKeyHashes, internalValue.Key.GetHashCode());
72  while (currentHash < expectedHash)
73  {
74  if (++index >= sortedKeyHashesLength)
75  break;
76  currentHash = sortedKeyHashes[index];
77  }
78  if (currentHash == expectedHash)
79  {
80  // Update element
81  InternalValues[index] = new KeyValuePair<int, ParameterCollection.InternalValue>(levelIndex, internalValue.Value);
82  }
83  }
84  }
85  }
86 
87  public object GetObject(int index)
88  {
89  return (InternalValues[index].Value).Object;
90  }
91  }
92 }