Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
SerializerSelector.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.Serialization.Serializers;
6 using SiliconStudio.Core.Storage;
7 
8 namespace SiliconStudio.Core.Serialization
9 {
10  public delegate void SerializeObjectDelegate(SerializationStream stream, ref object obj, ArchiveMode archiveMode);
11 
12  public class SerializerContext
13  {
15 
17  {
18  SerializerSelector = SerializerSelector.Default;
19  Tags = new PropertyContainer(this);
20  }
21 
22  /// <summary>
23  /// Gets or sets the serializer.
24  /// </summary>
25  /// <value>
26  /// The serializer.
27  /// </value>
29 
30  public T Get<T>(PropertyKey<T> key)
31  {
32  return Tags.Get(key);
33  }
34 
35  public void Set<T>(PropertyKey<T> key, T value)
36  {
37  Tags.SetObject(key, value);
38  }
39  }
40 
41  /// <summary>
42  /// Serializer context. It holds DataSerializer{T} objects and their factories.
43  /// </summary>
44  public class SerializerSelector
45  {
46  private readonly List<DataSerializerFactory> dataSerializerFactories = new List<DataSerializerFactory>();
47  private readonly Dictionary<Type, DataSerializer> dataSerializersByType = new Dictionary<Type, DataSerializer>();
48  private readonly Dictionary<ObjectId, DataSerializer> dataSerializersByTypeId = new Dictionary<ObjectId, DataSerializer>();
49 
50  /// <summary>
51  /// Gets the default instance of Serializer.
52  /// </summary>
53  /// <value>
54  /// The default instance.
55  /// </value>
56  public static SerializerSelector Default { get; internal set; }
57  public static SerializerSelector DefaultWithReuse { get; internal set; }
58 
59  static SerializerSelector()
60  {
62  Default.RegisterProfile("Default");
63 
64  DefaultWithReuse = new SerializerSelector();
65  DefaultWithReuse.RegisterProfile("Default");
66  DefaultWithReuse.ReuseReferences = true;
67  }
68 
69  /// <summary>
70  /// Gets or sets a value indicating whether [serialization reuses references]
71  /// (that is, each reference gets assigned an ID and if it is serialized again, same instance will be reused).
72  /// </summary>
73  /// <value>
74  /// <c>true</c> if [serialization reuses references]; otherwise, <c>false</c>.
75  /// </value>
76  public bool ReuseReferences { get; set; }
77 
78  public bool HashOnly { get; set; }
79 
80  public SerializerSelector RegisterProfile(string profileName)
81  {
82  RegisterFactory(DataSerializerFactory.CreateDataSerializerFactory(profileName));
83  return this;
84  }
85 
86  /// <summary>
87  /// Registers the <see cref="DataSerializer{T}"/> factory.
88  /// </summary>
89  /// <param name="factory">The factory.</param>
91  {
92  dataSerializerFactories.Add(factory);
93  return this;
94  }
95 
96  /// <summary>
97  /// Registers the serializer.
98  /// </summary>
99  /// <typeparam name="T"></typeparam>
100  /// <param name="serializer">The serializer.</param>
101  public SerializerSelector RegisterSerializer<T>(DataSerializer<T> serializer)
102  {
103  lock (dataSerializersByType)
104  {
105  PrepareSerializer(serializer);
106  dataSerializersByType[typeof(T)] = serializer;
107  dataSerializersByTypeId[serializer.SerializationTypeId] = serializer;
108  }
109 
110  return this;
111  }
112 
114  {
115  lock (dataSerializersByType)
116  {
117  DataSerializer dataSerializer;
118  if (!dataSerializersByTypeId.TryGetValue(typeId, out dataSerializer))
119  {
120  // Iterate over IDataSerializerFactory
121  for (int index = dataSerializerFactories.Count - 1; index >= 0; index--)
122  {
123  var dataSerializerFactory = dataSerializerFactories[index];
124  if (!dataSerializerFactory.CanSerialize(ref typeId))
125  continue;
126 
127  // Found a serializer, initialize it
128  dataSerializer = dataSerializerFactory.GetSerializer(ref typeId);
129  dataSerializersByType[dataSerializer.SerializationType] = dataSerializer;
130  dataSerializersByTypeId[typeId] = dataSerializer;
131 
132  if (dataSerializer != null)
133  PrepareSerializer(dataSerializer);
134 
135  return dataSerializer;
136  }
137 
138  return null;
139  }
140 
141  return dataSerializer;
142  }
143  }
144 
145  private void PrepareSerializer(DataSerializer dataSerializer)
146  {
147  // Ensure a serialization type ID has been generated (otherwise do so now)
148  if (dataSerializer.SerializationTypeId == ObjectId.Empty)
149  {
150  // Need to generate serialization type id
151  var typeName = dataSerializer.SerializationType.FullName;
152  dataSerializer.SerializationTypeId = ObjectId.FromBytes(System.Text.Encoding.UTF8.GetBytes(typeName));
153  }
154 
155  if (dataSerializer is IDataSerializerInitializer)
156  ((IDataSerializerInitializer)dataSerializer).Initialize(this);
157  }
158 
159  /// <summary>
160  /// Gets the serializer.
161  /// </summary>
162  /// <param name="type">The type that you want to (de)serialize.</param>
163  /// <returns>The <see cref="DataSerializer{T}"/> for this type if it exists or can be created, otherwise null.</returns>
164  public DataSerializer GetSerializer(Type type)
165  {
166  lock (dataSerializersByType)
167  {
168  DataSerializer dataSerializer;
169  if (!dataSerializersByType.TryGetValue(type, out dataSerializer))
170  {
171  // Iterate over IDataSerializerFactory
172  for (int index = dataSerializerFactories.Count - 1; index >= 0; index--)
173  {
174  var dataSerializerFactory = dataSerializerFactories[index];
175  if (!dataSerializerFactory.CanSerialize(type))
176  continue;
177 
178  // Found a serializer, initialize it
179  var dataSerializerWithId = dataSerializerFactory.GetSerializer(type);
180  dataSerializer = dataSerializerWithId.Value;
181  dataSerializersByType[type] = dataSerializer;
182  dataSerializersByTypeId[dataSerializerWithId.Key] = dataSerializer;
183 
184  if (dataSerializer != null)
185  PrepareSerializer(dataSerializer);
186 
187  return dataSerializer;
188  }
189 
190  return null;
191  }
192 
193  return dataSerializer;
194  }
195  }
196 
197  /// <summary>
198  /// Gets the serializer.
199  /// </summary>
200  /// <typeparam name="T">The type that you want to (de)serialize.</typeparam>
201  /// <returns>The <see cref="DataSerializer{T}"/> for this type if it exists or can be created, otherwise null.</returns>
202  public DataSerializer<T> GetSerializer<T>()
203  {
204  return (DataSerializer<T>)GetSerializer(typeof(T));
205  }
206  }
207 }
delegate void SerializeObjectDelegate(SerializationStream stream, ref object obj, ArchiveMode archiveMode)
Represents a container that can hold properties, lightweight to embed (lazy initialized).
DataSerializer GetSerializer(ref ObjectId typeId)
Use the default mode depending on the type of the field/property.
SerializerSelector RegisterProfile(string profileName)
A class that represents a typed tag propety.
Definition: PropertyKey.cs:138
static readonly ObjectId Empty
Definition: ObjectId.cs:15
Serializer context. It holds DataSerializer{T} objects and their factories.
A hash to uniquely identify data.
Definition: ObjectId.cs:13
SerializerSelector RegisterFactory(DataSerializerFactory factory)
Registers the DataSerializer{T} factory.
Describes how to serialize and deserialize an object without knowing its type. Used as a common base ...
ArchiveMode
Enumerates the different mode of serialization (either serialization or deserialization).
Definition: ArchiveMode.cs:8
Describes how to serialize and deserialize an object of a given type.
DataSerializer GetSerializer(Type type)
Gets the serializer.
static DataSerializerFactory CreateDataSerializerFactory(string profileName)