object DeserializeGameObject(TypeInfo typeInfo, int id)
{
var type = typeInfo.Type;
object ob;
bool created;
if (m_reader.TokenType == JsonToken.PropertyName && (string)m_reader.Value == "$sid")
{
Read();
Trace.Assert(m_reader.TokenType == JsonToken.Integer);
var sid = (int)(long)m_reader.Value;
Read();
var resolver = m_globalResolvers.GetGlobalResolver(type);
ob = resolver.FromRef(sid);
created = false;
}
else
{
ob = FormatterServices.GetUninitializedObject(type);
created = true;
}
var deserializingMethods = typeInfo.OnDeserializingMethods;
foreach (var method in deserializingMethods)
{
method.Invoke(ob, null);
}
if (id != -1)
{
m_referenceResolver.Add(id, ob);
}
var entries = typeInfo.GameMemberEntries;
while (true)
{
if (m_reader.TokenType == JsonToken.EndObject)
{
break;
}
Trace.Assert(m_reader.TokenType == JsonToken.PropertyName);
string propName = (string)m_reader.Value;
Read();
var idx = Array.FindIndex(entries, fi => fi.Name == propName);
if (idx == -1 && typeInfo.HasDelegate && propName == "$del")
{
var data = DeserializeObject(typeof(object));
((ISaveGameDelegate)ob).RestoreSaveData(data);
}
else if (idx == -1)
{
throw new Exception();
}
else
{
var entry = entries[idx];
object value;
if (entry.ReaderWriter != null)
{
value = entry.ReaderWriter.Read(m_reader);
}
else
{
var memberType = entry.MemberType;
value = DeserializeObject(memberType);
if (entry.Converter != null)
{
value = entry.Converter.ConvertFromSerializable(value);
}
}
entry.SetValue(ob, value);
}
Read();
}
if (created)
{
typeInfo.DeserializeConstructor.Invoke(ob, new object[] { new SaveGameContext() });
}
var deserializedMethods = typeInfo.OnDeserializedMethods;
foreach (var method in deserializedMethods)
{
method.Invoke(ob, null);
}
var postDeserMethods = typeInfo.OnGamePostDeserializationMethods;
foreach (var method in postDeserMethods)
{
var dele = (PostDeserializationDelegate)Delegate.CreateDelegate(typeof(PostDeserializationDelegate), ob, method);
m_postDeserMethods.Add(dele);
}
return(ob);
}