Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
ContentReference.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.Runtime.CompilerServices;
5 using SiliconStudio.Core.IO;
6 using SiliconStudio.Core.Serialization.Serializers;
7 
8 namespace SiliconStudio.Core.Serialization
9 {
10  public static class UrlServices
11  {
12  private static ConditionalWeakTable<object, UrlInfo> urls = new ConditionalWeakTable<object, UrlInfo>();
13 
14  public static string GetUrl(IContentData contentData)
15  {
16  return contentData.Url;
17  }
18 
19  public static void SetUrl(IContentData contentData, string url)
20  {
21  contentData.Url = url;
22  }
23 
24  public static string GetUrl(object obj)
25  {
26  var contentData = obj as IContentData;
27  if (contentData != null)
28  return contentData.Url;
29 
30  // TODO: Allow only IReferencable and/or ICollectionHolder
31  var urlInfo = urls.GetValue(obj, x => new UrlInfo());
32  return urlInfo.Url;
33  }
34 
35  public static void SetUrl(object obj, string url)
36  {
37  var contentData = obj as IContentData;
38  if (contentData != null)
39  {
40  contentData.Url = url;
41  return;
42  }
43 
44  // TODO: Allow only IReferencable and/or ICollectionHolder
45  var urlInfo = urls.GetValue(obj, x => new UrlInfo());
46  urlInfo.Url = url;
47  }
48 
49  class UrlInfo
50  {
51  public string Url;
52  }
53  }
54 
55  public abstract class ContentReference : ITypedContentReference, IEquatable<ContentReference>
56  {
57  internal const int NullIdentifier = -1;
58 
59  /// <summary>
60  /// Creates a content reference with the specified value..
61  /// </summary>
62  /// <typeparam name="T">Type of the value</typeparam>
63  /// <param name="value">The value.</param>
64  /// <returns>ContentReference{``0}.</returns>
65  public static ContentReference<T> Create<T>(T value) where T : class
66  {
67  return new ContentReference<T>() { Value = value };
68  }
69 
70  /// <summary>
71  /// Gets or sets the asset unique identifier.
72  /// </summary>
73  /// <value>The identifier.</value>
74  public Guid Id { get; set; }
75 
76  /// <summary>
77  /// Gets or sets the URL of the referenced data.
78  /// </summary>
79  /// <value>
80  /// The URL of the referenced data.
81  /// </value>
82  public abstract string Location { get; set; }
83 
84  public ContentReferenceState State { get; set; }
85 
86  public abstract Type Type { get; }
87 
88  public abstract object ObjectValue { get; set; }
89 
90 
91  public bool Equals(ContentReference other)
92  {
93  if (ReferenceEquals(null, other)) return false;
94  if (ReferenceEquals(this, other)) return true;
95  return Id.Equals(other.Id) && Equals(Location, other.Location);
96  }
97 
98  public override bool Equals(object obj)
99  {
100  if (ReferenceEquals(null, obj)) return false;
101  if (ReferenceEquals(this, obj)) return true;
102  if (obj.GetType() != this.GetType()) return false;
103  return Equals((ContentReference)obj);
104  }
105 
106  public override int GetHashCode()
107  {
108  unchecked
109  {
110  return (Id.GetHashCode()*397) ^ (Location != null ? Location.GetHashCode() : 0);
111  }
112  }
113 
114  public static bool operator ==(ContentReference left, ContentReference right)
115  {
116  return Equals(left, right);
117  }
118 
119  public static bool operator !=(ContentReference left, ContentReference right)
120  {
121  return !Equals(left, right);
122  }
123 
124 
125  public override string ToString()
126  {
127  return string.Format("{0}:{1}", Id, Location);
128  }
129  }
130 
131  [DataSerializer(typeof(ContentReferenceDataSerializer<>), Mode = DataSerializerGenericMode.GenericArguments)]
132  public sealed class ContentReference<T> : ContentReference where T : class
133  {
134  // Depending on state, either value or Location is null (they can't be both non-null)
135  private T value;
136  private string url;
137 
138  public override Type Type
139  {
140  get { return typeof(T); }
141  }
142 
143  /// <summary>
144  /// Gets or sets the value.
145  /// </summary>
146  /// <value>
147  /// The value.
148  /// </value>
149  /// <exception cref="System.InvalidOperationException">Value can't be read in this state.</exception>
150  public T Value
151  {
152  get
153  {
154  //if (State == ContentReferenceState.NeverLoad)
155  // throw new InvalidOperationException("Value can't be read in this state.");
156  //lock (assetManager)
157  //{
158  // if (State == ContentReferenceState.LoadFirstAccess)
159  // {
160  // value = assetManager.Load<T>(Location);
161  // State = ContentReferenceState.Loaded;
162  // }
163  // else if (State == ContentReferenceState.LoadEverytime)
164  // {
165  // return assetManager.Load<T>(Location);
166  // }
167  //}
168  return value;
169  }
170  set
171  {
172  State = ContentReferenceState.Modified;
173  this.value = value;
174  this.url = null;
175  }
176  }
177 
178  public override string Location
179  {
180  get
181  {
182  // TODO: Should we return value.Location if value is not null, or just reference Location?
183  if (value == null)
184  return url;
185 
186  return UrlServices.GetUrl(value);
187  }
188  set
189  {
190  if (this.value == null)
191  {
192  url = value;
193  }
194  else
195  {
196  UrlServices.SetUrl(this.value, value);
197  }
198  }
199  }
200 
201  public override object ObjectValue
202  {
203  get { return Value; }
204  set { Value = (T)value; }
205  }
206 
208  {
209  Value = null;
210  }
211 
212  public ContentReference(Guid id, string location)
213  {
214  Id = id;
215  Location = location;
216  }
217 
218  public static explicit operator T (ContentReference<T> contentReference)
219  {
220  if (contentReference == null)
221  return null;
222  return contentReference.Value;
223  }
224 
225  public static implicit operator ContentReference<T>(T value)
226  {
227  return new ContentReference<T>() { Value = value };
228  }
229 
230 
231  }
232 }
static void SetUrl(object obj, string url)
DataSerializerGenericMode
Defines what generic parameters to pass to the serializer.
static string GetUrl(IContentData contentData)
The type of the serialized type will be passed as a generic arguments of the serializer. Example: serializer of A becomes instantiated as Serializer{A}.
abstract string Location
Gets or sets the URL of the referenced data.
static void SetUrl(IContentData contentData, string url)
A content data storing its own Location.
Definition: IContentData.cs:8