private void ReadVariableRecursive(ES2AutoSave autoSave, ES2AutoSaveVariableInfo variable, ES2Reader reader, object obj) { string variableID = reader.reader.ReadString(); int endPosition = (int)reader.stream.Position; int length = reader.reader.ReadInt32(); endPosition += length; // Read Type data ES2Keys.Key collectionType = (ES2Keys.Key)reader.reader.ReadByte(); int typeHash = reader.reader.ReadInt32(); int dictValueHash = 0; if (collectionType == ES2Keys.Key._Dictionary) { dictValueHash = reader.reader.ReadInt32(); } ES2AutoSaveVariableInfo info = autoSave.GetCachedVariableInfo(variableID); if (info == null) { reader.stream.Position = endPosition; return; } string dataType = reader.reader.ReadString(); if (dataType == "data") { // Get ES2Types. ES2Type type = ES2TypeManager.GetES2Type(typeHash); ES2Type dictValueType = null; if (collectionType == ES2Keys.Key._Dictionary) { dictValueType = ES2TypeManager.GetES2Type(dictValueHash); } // If the type of data we're loading isn't supported, skip it. if (type == null || (collectionType == ES2Keys.Key._Dictionary && dictValueType == null)) { reader.stream.Position = endPosition; return; } bool valueWasSet = false; if (collectionType == ES2Keys.Key._Null) { valueWasSet = ES2Reflection.SetValue(obj, info.name, reader.Read <System.Object>(type), info.isProperty); } else if (collectionType == ES2Keys.Key._NativeArray) { valueWasSet = ES2Reflection.SetValue(obj, info.name, reader.ReadSystemArray(type), info.isProperty); } else if (collectionType == ES2Keys.Key._List) { valueWasSet = ES2Reflection.SetValue(obj, info.name, reader.ReadICollection(typeof(List <>), type), info.isProperty); } else if (collectionType == ES2Keys.Key._Queue) { valueWasSet = ES2Reflection.SetValue(obj, info.name, reader.ReadICollection(typeof(Queue <>), type), info.isProperty); } else if (collectionType == ES2Keys.Key._Stack) { valueWasSet = ES2Reflection.SetValue(obj, info.name, reader.ReadICollection(typeof(Stack <>), type), info.isProperty); } else if (collectionType == ES2Keys.Key._HashSet) { valueWasSet = ES2Reflection.SetValue(obj, info.name, reader.ReadICollection(typeof(HashSet <>), type), info.isProperty); } else if (collectionType == ES2Keys.Key._Dictionary) { valueWasSet = ES2Reflection.SetValue(obj, info.name, reader.ReadIDictionary(typeof(Dictionary <,>), type, dictValueType), info.isProperty); } if (!valueWasSet) { reader.stream.Position = endPosition; return; } } // Else, we have variables to load. else if (dataType == "vars") { object thisObj = ES2Reflection.GetValue(obj, info.name, info.isProperty); if (thisObj == null) { reader.stream.Position = endPosition; } ReadVariableRecursive(autoSave, info, reader, thisObj); } else { reader.stream.Position = endPosition; return; } }
private void WriteVariableRecursive(ES2AutoSave autoSave, ES2AutoSaveVariableInfo variable, ES2Writer writer, object obj) { // Get the Type data for this variable, or return if a type is not supported. ES2Type es2Type = null; ES2Type dictValueType = null; ES2Keys.Key collectionType = ES2Keys.GetCollectionType(variable.type); // If it's not a collection type, just get the basic ES2Type. if (collectionType == ES2Keys.Key._Null) { es2Type = ES2TypeManager.GetES2Type(variable.type); } // Otherwise, get the collection element types. else { if (collectionType == ES2Keys.Key._NativeArray) // Get Array Element Type. { es2Type = ES2TypeManager.GetES2Type(variable.type.GetElementType()); } else { // Get ES2Types for generic type arguments. Type[] genericArgs = ES2Reflection.GetGenericArguments(variable.type); if (genericArgs.Length > 0) { es2Type = ES2TypeManager.GetES2Type(genericArgs[0]); if (genericArgs.Length > 1) { dictValueType = ES2TypeManager.GetES2Type(genericArgs[1]); if (dictValueType == null) { return; } } } } } // Skip if unsupported. Enums are not supported unless they have an explicit ES2Type. if (es2Type == null || es2Type.GetType() == typeof(ES2_Enum)) { return; } writer.writer.Write(variable.id); int startPosition = writer.WritePropertyPrefix(); // Write the Type data for this variable. writer.writer.Write((byte)collectionType); writer.writer.Write(es2Type.hash); // If Dictionary, also write the Dictionary value type. if (dictValueType != null) { writer.writer.Write(dictValueType.hash); } int variableCount = 0; foreach (string variableID in variable.variableIDs) { ES2AutoSaveVariableInfo variableInfo = autoSave.GetCachedVariableInfo(variableID); if (variableInfo.buttonSelected) { variableCount++; if (variableCount == 1) { writer.writer.Write("vars"); } object variableObj = ES2Reflection.GetValue(obj, variableInfo.name, variableInfo.isProperty); WriteVariableRecursive(autoSave, variableInfo, writer, variableObj); } } // If no variables were written, we want to save this variable. if (variableCount == 0) { writer.writer.Write("data"); if (collectionType == ES2Keys.Key._Null) { writer.Write(obj, es2Type); } else if (collectionType == ES2Keys.Key._NativeArray) { writer.WriteSystemArray((Array)obj, es2Type); } else if (collectionType == ES2Keys.Key._List) { writer.WriteICollection((ICollection)obj, es2Type); } else if (collectionType == ES2Keys.Key._Queue) { writer.WriteICollection((ICollection)obj, es2Type); } else if (collectionType == ES2Keys.Key._Stack) { writer.WriteICollection((ICollection)obj, es2Type); } else if (collectionType == ES2Keys.Key._HashSet) { writer.WriteICollection((ICollection)obj, es2Type); } else if (collectionType == ES2Keys.Key._Dictionary) { writer.WriteIDictionary((IDictionary)obj, es2Type, dictValueType); } } writer.WritePropertyLength(startPosition); }