Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
DataSerializerFactory.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.Storage;
6 
7 namespace SiliconStudio.Core.Serialization
8 {
9  public class DataSerializerFactory
10  {
11  private readonly List<Action<DataSerializerFactory>> serializationProfileInitializers;
12  private int serializationProfileInitializerCount; // Cached count so that we know if items are added
13 
14  private readonly Dictionary<ObjectId, DataSerializer> dataSerializersById = new Dictionary<ObjectId, DataSerializer>();
15  private readonly Dictionary<Type, KeyValuePair<ObjectId, DataSerializer>> dataSerializersByType = new Dictionary<Type, KeyValuePair<ObjectId, DataSerializer>>();
16 
17  public static readonly Dictionary<string, List<Action<DataSerializerFactory>>> SerializationProfileInitializers = new Dictionary<string, List<Action<DataSerializerFactory>>>();
18 
19  public static void RegisterSerializationProfile(string profileName, Action<DataSerializerFactory> serializationProfileInitializer)
20  {
21  lock (SerializationProfileInitializers)
22  {
23  List<Action<DataSerializerFactory>> existingSerializationProfileInitializers;
24 
25  // If there was already existing delegate, combine it at the end
26  if (!SerializationProfileInitializers.TryGetValue(profileName, out existingSerializationProfileInitializers))
27  {
28  existingSerializationProfileInitializers = new List<Action<DataSerializerFactory>>();
29  SerializationProfileInitializers.Add(profileName, existingSerializationProfileInitializers);
30  }
31 
32  // Register new combined delegate
33  existingSerializationProfileInitializers.Add(serializationProfileInitializer);
34  }
35  }
36 
37  public static DataSerializerFactory CreateDataSerializerFactory(string profileName)
38  {
39  lock (SerializationProfileInitializers)
40  {
41  // Run all initializers
42  var serializationProfileInitializers = SerializationProfileInitializers[profileName];
43  var dataSerializerFactory = new DataSerializerFactory(serializationProfileInitializers);
44 
45  return dataSerializerFactory;
46  }
47  }
48 
49  public DataSerializerFactory(List<Action<DataSerializerFactory>> serializationProfileInitializers)
50  {
51  this.serializationProfileInitializers = serializationProfileInitializers;
52  this.serializationProfileInitializerCount = 0;
53  }
54 
55  /// <summary>
56  /// Registers the serializer.
57  /// </summary>
58  /// <param name="serializer">The serializer.</param>
59  public void RegisterSerializer(ObjectId id, DataSerializer serializer)
60  {
61  lock (dataSerializersByType)
62  {
63  serializer.SerializationTypeId = id;
64  dataSerializersByType[serializer.SerializationType] = new KeyValuePair<ObjectId, DataSerializer>(id, serializer);
65  dataSerializersById[id] = serializer;
66  }
67  }
68 
69  /// <summary>
70  /// Registers the type has having no serializer (useful for abstract types, interfaces and special types such as object).
71  /// </summary>
72  /// <param name="type">The type.</param>
73  public void RegisterNullSerializer(ObjectId id, Type type)
74  {
75  lock (dataSerializersByType)
76  {
77  dataSerializersByType[type] = new KeyValuePair<ObjectId, DataSerializer>(id, null);
78  dataSerializersById[id] = null;
79  }
80  }
81 
82  /// <summary>
83  /// Should return true when factory is able to create a <see cref="DataSerializer{T}"/> for this type.
84  /// </summary>
85  /// <param name="type">The type to create a <see cref="DataSerializer{T}"/> for.</param>
86  /// <returns>
87  /// <c>true</c> if this instance can serialize the specified type; otherwise, <c>false</c>.
88  /// </returns>
89  public bool CanSerialize(Type type)
90  {
91  CheckForNewAssemblies();
92 
93  return dataSerializersByType.ContainsKey(type);
94  }
95 
96  /// <summary>
97  /// Should return true when factory is able to create a <see cref="DataSerializer{T}"/> for this type.
98  /// </summary>
99  /// <param name="typeId">The type ID to create a <see cref="DataSerializer{T}"/> for.</param>
100  /// <returns>
101  /// <c>true</c> if this instance can serialize the specified type; otherwise, <c>false</c>.
102  /// </returns>
103  public bool CanSerialize(ref ObjectId typeId)
104  {
105  CheckForNewAssemblies();
106 
107  return dataSerializersById.ContainsKey(typeId);
108  }
109 
110  private void CheckForNewAssemblies()
111  {
112  // New assemblies loaded?
113  if (serializationProfileInitializers.Count > serializationProfileInitializerCount)
114  {
115  lock (SerializationProfileInitializers)
116  {
117  var start = serializationProfileInitializerCount;
118  serializationProfileInitializerCount = serializationProfileInitializers.Count;
119 
120  // Execute new serializer profile initializers appended at the end
121  for (int i = start; i < serializationProfileInitializers.Count; ++i)
122  {
123  serializationProfileInitializers[i](this);
124  }
125  }
126  }
127  }
128 
129  /// <summary>
130  /// Gets the (de)serializer. It should only be called if CanSerialize(type) is true.
131  /// </summary>
132  /// <param name="type">The type to create a serializer from.</param>
133  /// <returns>A <see cref="DataSerializer{T}"/> that can serialize this specific type.</returns>
134  public KeyValuePair<ObjectId, DataSerializer> GetSerializer(Type type)
135  {
136  return dataSerializersByType[type];
137  }
138 
139  /// <summary>
140  /// Gets the (de)serializer. It should only be called if CanSerialize(type) is true.
141  /// </summary>
142  /// <param name="type">The type to create a serializer from.</param>
143  /// <returns>A <see cref="DataSerializer{T}"/> that can serialize this specific type.</returns>
145  {
146  return dataSerializersById[typeId];
147  }
148  }
149 }
void RegisterNullSerializer(ObjectId id, Type type)
Registers the type has having no serializer (useful for abstract types, interfaces and special types ...
void RegisterSerializer(ObjectId id, DataSerializer serializer)
Registers the serializer.
KeyValuePair< ObjectId, DataSerializer > GetSerializer(Type type)
Gets the (de)serializer. It should only be called if CanSerialize(type) is true.
static void RegisterSerializationProfile(string profileName, Action< DataSerializerFactory > serializationProfileInitializer)
bool CanSerialize(Type type)
Should return true when factory is able to create a DataSerializer{T} for this type.
DataSerializerFactory(List< Action< DataSerializerFactory >> serializationProfileInitializers)
A hash to uniquely identify data.
Definition: ObjectId.cs:13
Describes how to serialize and deserialize an object without knowing its type. Used as a common base ...
bool CanSerialize(ref ObjectId typeId)
Should return true when factory is able to create a DataSerializer{T} for this type.
static DataSerializerFactory CreateDataSerializerFactory(string profileName)
DataSerializer GetSerializer(ref ObjectId typeId)
Gets the (de)serializer. It should only be called if CanSerialize(type) is true.