Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
ContentSerializerContext.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 SiliconStudio.Core.Serialization;
4 using System;
5 using System.Collections.Generic;
6 using System.Linq;
7 using System.Text;
8 using System.Threading.Tasks;
9 using SiliconStudio.Core.Serialization.Assets;
10 using SiliconStudio.Core.Serialization.Converters;
11 using SiliconStudio.Core.Serialization.Serializers;
12 
13 // Serializer for ContentSerializerContext.SerializeReferences()
14 namespace SiliconStudio.Core.Serialization.Contents
15 {
16  // TODO: Many simplifications/cleaning (lot of leftover from old system)
17  [DataSerializerGlobal(typeof(ListSerializer<ChunkReference>))]
19  {
20  internal readonly List<ChunkReference> chunkReferences = new List<ChunkReference>();
21  private readonly Dictionary<Type, int> objectsPerType = new Dictionary<Type, int>();
22  private readonly HashSet<object> generatedUrlObjects = new HashSet<object>();
23  private string generatedUrlPrefix;
24 
25  public static PropertyKey<ContentSerializerContext> ContentSerializerContextProperty = new PropertyKey<ContentSerializerContext>("ContentSerializerContext", typeof(ContentSerializerContext));
26 
27  public AssetManager AssetManager { get; private set; }
28  public string Url { get; protected set; }
29  public ArchiveMode Mode { get; protected set; }
30 
31  public List<ContentReference> ContentReferences { get; set; }
32 
33  public ConverterContext ConverterContext { get; set; }
34 
35  public bool RegenerateUrls { get; set; }
36 
37  internal AssetManager.AssetReference AssetReference { get; set; }
38 
39  internal ContentSerializerContext(string url, ArchiveMode mode, AssetManager assetManager)
40  {
41  Url = url;
42  Mode = mode;
43  AssetManager = assetManager;
44  ContentReferences = new List<ContentReference>();
45  generatedUrlPrefix = Url + "/gen/";
46  }
47 
48  public int AddContentReference(ContentReference contentReference)
49  {
50  if (contentReference == null)
51  return ChunkReference.NullIdentifier;
52 
53  // TODO: This behavior should be controllable
54  if (contentReference.State != ContentReferenceState.NeverLoad && contentReference.ObjectValue != null)
55  {
56  // Auto-generate URL if necessary
57  var serializer = AssetManager.Serializer.GetSerializer(null, contentReference.ObjectValue.GetType());
58  BuildUrl(contentReference, serializer.ActualType);
59  //Executor.ProcessObject(this, contentReference.Type, contentReference);
60  ContentReferences.Add(contentReference);
61  }
62 
63  return AddChunkReference(contentReference.Location, contentReference.Type);
64  }
65 
66  public ContentReference<T> GetContentReference<T>(int index) where T : class
67  {
68  if (index == ChunkReference.NullIdentifier)
69  return null;
70 
71  var chunkReference = GetChunkReference(index);
72 
73  var contentReference = new ContentReference<T>(Guid.Empty, chunkReference.Location);
74 
75  ContentReferences.Add(contentReference);
76 
77  return contentReference;
78  }
79 
81  {
82  return chunkReferences[index];
83  }
84 
85  public int AddChunkReference(string url, Type type)
86  {
87  // Starting search from the end is maybe more likely to hit quickly (and cache friendly)?
88  for (int i = chunkReferences.Count - 1; i >= 0; --i)
89  {
90  var currentReference = chunkReferences[i];
91  if (currentReference.Location == url && currentReference.ObjectType == type)
92  {
93  return i;
94  }
95  }
96 
97  var reference = new ChunkReference(type, url);
98  var index = chunkReferences.Count;
99  chunkReferences.Add(reference);
100  return index;
101  }
102 
103 
104  public void BuildUrl(ContentReference contentReference, Type serializationType)
105  {
106  var content = contentReference.ObjectValue;
107  string url = contentReference.Location;
108 
109  if (content == null)
110  return;
111 
112  // If URL has been auto-generated previously, regenerates it (so that no collision occurs if item has been modified)
113  if (url == null || (RegenerateUrls && url.StartsWith(generatedUrlPrefix) && !generatedUrlObjects.Contains(content)))
114  {
115  // Already registered?
116  if (AssetManager.TryGetAssetUrl(content, out url))
117  {
118  contentReference.Location = url;
119  return;
120  }
121 
122  generatedUrlObjects.Add(content);
123 
124  // No URL, need to generate one.
125  // Try to be as deterministic as possible (generated from root URL, type and index).
126  var contentType = content.GetType();
127 
128  // Get and update current count
129  int currentCount;
130  objectsPerType.TryGetValue(contentType, out currentCount);
131  objectsPerType[contentType] = ++currentCount;
132 
133  contentReference.Location = string.Format("{0}{1}_{2}", generatedUrlPrefix, content.GetType().Name, currentCount);
134  }
135 
136  // Register it
137  //if (contentReference.Location != null)
138  // AssetManager.RegisterAsset(contentReference.Location, contentReference.ObjectValue, serializationType, false);
139  }
140 
141  public object SerializeContent(SerializationStream stream, IContentSerializer serializer, object objToSerialize)
142  {
143  stream.Context.SerializerSelector = AssetManager.Serializer.LowLevelSerializerSelector;
144  serializer.Serialize(this, stream, ref objToSerialize);
145  return objToSerialize;
146  }
147 
149  {
150  var references = chunkReferences;
151  stream.Context.SerializerSelector = AssetManager.Serializer.LowLevelSerializerSelector;
152  stream.Serialize(ref references, Mode);
153  }
154  }
155 }
Base class for implementation of SerializationStream.
object SerializeContent(SerializationStream stream, IContentSerializer serializer, object objToSerialize)
abstract string Location
Gets or sets the URL of the referenced data.
bool TryGetAssetUrl(object obj, out string url)
Definition: AssetManager.cs:75
ArchiveMode
Enumerates the different mode of serialization (either serialization or deserialization).
Definition: ArchiveMode.cs:8
Describe a reference between an object and another.
A class that represents a tag propety.
Definition: PropertyKey.cs:17
void BuildUrl(ContentReference contentReference, Type serializationType)