Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
OverrideKeyMappingTransform.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 SharpYaml.Serialization;
5 using SharpYaml.Serialization.Serializers;
6 using SiliconStudio.Core.Reflection;
9 
10 namespace SiliconStudio.Core.Yaml
11 {
12  /// <summary>
13  /// Internal class used when serializing/deserializing an object.
14  /// </summary>
15  internal class OverrideKeyMappingTransform : DefaultObjectSerializerBackend
16  {
17  private readonly ITypeDescriptorFactory typeDescriptorFactory;
18  private readonly bool keepOnlySealedOverrides;
19  private ITypeDescriptor cachedDescriptor;
20 
21  private const char PostFixSealed = '!';
22 
23  private const char PostFixNew = '*';
24 
25  private const string PostFixNewSealed = "*!";
26 
27  private const string PostFixNewSealedAlt = "!*";
28 
29 
30  public OverrideKeyMappingTransform(ITypeDescriptorFactory typeDescriptorFactory, bool keepOnlySealedOverrides)
31  {
32  if (typeDescriptorFactory == null) throw new ArgumentNullException("typeDescriptorFactory");
33  this.typeDescriptorFactory = typeDescriptorFactory;
34  this.keepOnlySealedOverrides = keepOnlySealedOverrides;
35  }
36 
37  public override void WriteMemberName(ref ObjectContext objectContext, SharpYaml.Serialization.IMemberDescriptor member, string memberName)
38  {
39  // Replace the key with SiliconStudio.Core.Reflection IMemberDescriptor
40  // Cache previous
41  if (member != null)
42  {
43  var customDescriptor = (IMemberDescriptor)member.Tag;
44  if (customDescriptor == null)
45  {
46  customDescriptor = typeDescriptorFactory.Find(objectContext.Instance.GetType())[memberName];
47  member.Tag = customDescriptor;
48  }
49 
50  if (customDescriptor != null)
51  {
52  var overrideType = objectContext.Instance.GetOverride(customDescriptor);
53  if (!keepOnlySealedOverrides && (overrideType & OverrideType.New) != 0)
54  {
55  memberName += PostFixNew;
56  }
57  if ((overrideType & OverrideType.Sealed) != 0)
58  {
59  memberName += PostFixSealed;
60  }
61  }
62  }
63 
64  base.WriteMemberName(ref objectContext, member, memberName);
65  }
66 
67  public override string ReadMemberName(ref ObjectContext objectContext, string memberName)
68  {
69  var newMemberName = memberName.Trim(PostFixSealed, PostFixNew);
70 
71  if (newMemberName.Length != memberName.Length)
72  {
73  var overrideType = OverrideType.Base;
74  if (memberName.Contains(PostFixNewSealed) || memberName.EndsWith(PostFixNewSealedAlt))
75  {
76  overrideType = OverrideType.New | OverrideType.Sealed;
77  }
78  else if (memberName.EndsWith(PostFixNew))
79  {
80  overrideType = OverrideType.New;
81  }
82  else if (memberName.EndsWith(PostFixSealed))
83  {
84  overrideType = OverrideType.Sealed;
85  }
86 
87  if (overrideType != OverrideType.Base)
88  {
89  // With keepOnlySealedOverrides, we can serialize only Base or Base+Sealed
90  if (keepOnlySealedOverrides && overrideType.IsSealed())
91  {
92  overrideType = OverrideType.Base | OverrideType.Sealed;
93  }
94 
95  var objectType = objectContext.Instance.GetType();
96  if (cachedDescriptor == null || cachedDescriptor.Type != objectType)
97  {
98  cachedDescriptor = typeDescriptorFactory.Find(objectType);
99  }
100  var memberDescriptor = cachedDescriptor[newMemberName];
101  objectContext.Instance.SetOverride(memberDescriptor, overrideType);
102  }
103  }
104 
105  return base.ReadMemberName(ref objectContext, newMemberName);
106  }
107  }
108 }
SiliconStudio.Core.Reflection.ITypeDescriptor ITypeDescriptor
SiliconStudio.Core.Reflection.IMemberDescriptor IMemberDescriptor
Provides access members of a type.
OverrideType
A Type of override used on a member value.
Definition: OverrideType.cs:11
A factory to create an instance of a ITypeDescriptor