Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
ObjectReference.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 
5 namespace SiliconStudio.Quantum.References
6 {
7  /// <summary>
8  /// A class representing a reference to another object that has a different model.
9  /// </summary>
10  public sealed class ObjectReference : IReference
11  {
12  private object orphanObject;
13 
14  /// <summary>
15  /// Initialize a new instance of the <see cref="ObjectReference"/> class using a data object. The model node can be retrieved later using <see cref="UpdateTarget"/>.
16  /// </summary>
17  /// <remarks>This constructor should be used when the given <see cref="objectValue"/> has no mode node yet existing.</remarks>
18  /// <param name="objectValue">A data object to reference. Can be null.</param>
19  /// <param name="objectType">The type of data object to reference.</param>
20  /// <param name="index">The index of this reference in its parent reference, if it is a <see cref="ReferenceEnumerable"/>.</param>
21  internal ObjectReference(object objectValue, Type objectType, object index)
22  {
23  Reference.CheckReferenceCreationSafeGuard();
24  if (objectType == null) throw new ArgumentNullException("objectType");
25  if (objectValue != null && !objectType.IsInstanceOfType(objectValue)) throw new ArgumentException(@"The given type does not match the given object.", "objectValue");
26  orphanObject = objectValue;
27  Type = objectType;
28  Index = index;
29  }
30 
31  /// <summary>
32  /// Gets the model node targeted by this reference, if available.
33  /// </summary>
34  public IModelNode TargetNode { get; private set; }
35 
36  /// <inheritdoc/>
37  public object ObjectValue { get { return TargetNode != null ? TargetNode.Content.Value : orphanObject; } }
38 
39  /// <inheritdoc/>
40  public Type Type { get; private set; }
41 
42  /// <inheritdoc/>
43  public object Index { get; private set; }
44 
45  /// <summary>
46  /// Gets the <see cref="Guid"/> of the model node targeted by this reference, if available.
47  /// </summary>
48  public Guid TargetGuid { get; private set; }
49 
50  /// <inheritdoc/>
51  public void Clear()
52  {
53  TargetNode = null;
54  TargetGuid = Guid.Empty;
55  orphanObject = null;
56  }
57 
58  /// <inheritdoc/>
59  public void Refresh(object newObjectValue)
60  {
61  Clear();
62  orphanObject = newObjectValue;
63  }
64 
65  /// <summary>
66  /// Set the <see cref="TargetNode"/> and <see cref="TargetGuid"/> to the given object.
67  /// </summary>
68  /// <param name="targetNode">The <see cref="IModelNode"/> this reference should point on.</param>
69  public void SetTarget(IModelNode targetNode)
70  {
71  if (targetNode.Content.Value != null && !Type.IsInstanceOfType(targetNode.Content.Value)) throw new ArgumentException(@"The type of the node content does not match the type of this reference", "targetNode");
72 
73  if (TargetNode != null || TargetGuid != Guid.Empty)
74  throw new InvalidOperationException("TargetNode has already been set.");
75  if (targetNode.Content.Value != null && !Type.IsInstanceOfType(targetNode.Content.Value))
76  throw new InvalidOperationException("TargetNode type does not match the reference type.");
77  TargetNode = targetNode;
78  TargetGuid = targetNode.Guid;
79  }
80 
81  /// <inheritdoc/>
82  public bool UpdateTarget(ModelContainer modelContainer)
83  {
84  if (TargetNode == null)
85  {
86  var guid = modelContainer.GetGuid(ObjectValue, Type);
87  if (TargetGuid != guid)
88  throw new InvalidOperationException("The Guid of the object value is different from the current TargetGuid. The given ModelContainer may be different.");
89 
90  if (TargetGuid != Guid.Empty)
91  {
92  TargetNode = modelContainer.GetModelNode(TargetGuid);
93  if (TargetNode.Content.Value != null && !Type.IsInstanceOfType(TargetNode.Content.Value))
94  throw new InvalidOperationException("The type of the node content does not match the type of this reference");
95 
96  return TargetNode != null;
97  }
98  }
99  return false;
100  }
101 
102  /// <inheritdoc/>
103  public bool Equals(IReference other)
104  {
105  var otherReference = other as ObjectReference;
106  if (otherReference == null)
107  return false;
108 
109  return TargetGuid == otherReference.TargetGuid && TargetNode == otherReference.TargetNode;
110  }
111 
112  /// <inheritdoc/>
113  public override string ToString()
114  {
115  string result = "";
116  if (TargetNode != null)
117  result += "[HasNode] ";
118  else if (TargetGuid != Guid.Empty)
119  result += "[HasGuid] ";
120 
121  result += TargetGuid + " " + (ObjectValue != null ? ObjectValue.ToString() : "null");
122  return result;
123  }
124  }
125 }
A container used to store models and resolve references between them.
IContent Content
Gets the content of the IModelNode.
Definition: IModelNode.cs:41
void Refresh(object newObjectValue)
Refresh this reference and its nested references.
bool UpdateTarget(ModelContainer modelContainer)
Updates the target node of this reference or its nested references from a ModelContainer. A ModelContainer in which the corresponding model node may have been registered.true if the model node was found in the ModelContainer and the target nodes has been updated, false otherwise.
void SetTarget(IModelNode targetNode)
Set the TargetNode and TargetGuid to the given object.
A class representing a reference to another object that has a different model.
The IModelNode interface represents a node in a model object. A model object is represented by a grap...
Definition: IModelNode.cs:16
void Clear()
Clear the reference, making it represent a null or empty object.