コード例 #1
0
 /// <summary>
 /// Serializes the data in the specified object to the stream.
 /// </summary>
 /// <param name="obj">The object to be serialized.</param>
 /// <param name="writer">The location where the data will be written.</param>
 public void SerializeData(object obj, BinaryWriter writer)
 {
     onSerializing?.Invoke(obj, null);
     foreach (var pair in serializableFields)
     {
         var sfield = pair.Value;
         try {
             FastSerializationManager.WriteValue(writer, sfield.targetType, sfield.
                                                 GetValue(obj));
         } catch (Exception e) {
             Debug.LogErrorFormat("Error while serializing field {0} on template {1}: {2}",
                                  sfield.field.Name, targetType.Name, e.ToString());
             throw;
         }
     }
     foreach (var pair in serializableProperties)
     {
         var sprop = pair.Value;
         try {
             FastSerializationManager.WriteValue(writer, sprop.targetType, sprop.
                                                 GetValue(obj));
         } catch (Exception e) {
             Debug.LogErrorFormat("Error while serializing property {0} on template {1}: {2}",
                                  sprop.property.Name, targetType.Name, e.ToString());
             throw;
         }
     }
     customSerialize?.Invoke(obj, new object[] { writer });
     onSerialized?.Invoke(obj, null);
 }
コード例 #2
0
        /// <summary>
        /// Reads an array, which is encoded the same way for lists and plain old arrays.
        /// </summary>
        /// <param name="typeInfo">The array type to read.</param>
        /// <param name="reader">The stream containing serialized data.</param>
        /// <param name="optimizePOD">If true, plain-old-data (POD) arrays will be deserialized
        /// using a faster method. Only can be used if they were serialized using the fast method.</param>
        /// <returns>The deserialized array, or null if it was empty.</returns>
        private static Array ReadArray(TypeInfo typeInfo, IReader reader, bool optimizePOD)
        {
            int   n     = reader.ReadInt32();
            Array array = null;

            if (n >= 0)
            {
                var elementType = typeInfo.subTypes[0];
                array = Array.CreateInstance(elementType.type, n);
                if (Helper.IsPOD(elementType.info) && optimizePOD)
                {
                    ReadArrayFast(array, elementType, reader);
                }
                else if (Helper.IsValueType(elementType.info))
                {
                    var template = FastSerializationManager.GetFastDeserializationMapping(
                        elementType.type);
                    object element = template.CreateInstance();
                    for (int i = 0; i < n; i++)
                    {
                        template.Deserialize(element, reader);
                        array.SetValue(element, i);
                    }
                }
                else
                {
                    for (int i = 0; i < n; i++)
                    {
                        array.SetValue(ReadValue(elementType, reader, null), i);
                    }
                }
            }
            return(array);
        }
コード例 #3
0
            /// <summary>
            /// Applied before SerializeTypeless runs.
            /// </summary>
            internal static bool Prefix(object obj, BinaryWriter writer)
            {
                var type     = obj.GetType();
                var template = FastSerializationManager.GetFastSerializationTemplate(type);

                template.SerializeData(obj, writer);
                return(false);
            }
コード例 #4
0
 /// <summary>
 /// Saves the game to disk in the background.
 /// </summary>
 /// <param name="data">The uncompressed save data.</param>
 private void DoSave(BackgroundSaveData data)
 {
     try {
         var stream = data.Stream;
         PUtil.LogDebug("Background save to: " + data.FileName);
         stream.Seek(0L, SeekOrigin.Begin);
         CleanAutosaves();
         // Write the file header
         using (var writer = new BinaryWriter(File.Open(data.FileName, FileMode.
                                                        Create))) {
             var saveHeader = SaveGame.Instance.GetSaveHeader(true, data.Compress,
                                                              out SaveGame.Header header);
             writer.Write(header.buildVersion);
             writer.Write(header.headerSize);
             writer.Write(header.headerVersion);
             writer.Write(header.compression);
             writer.Write(saveHeader);
             if (FastSaveOptions.Instance.DelegateSave)
             {
                 FastSerializationManager.SerializeDirectory(writer);
             }
             else
             {
                 KSerialization.Manager.SerializeDirectory(writer);
             }
             writer.Flush();
             if (data.Compress)
             {
                 COMPRESS_CONTENTS.Invoke(writer, stream.GetBuffer(), (int)stream.
                                          Length);
             }
             else
             {
                 stream.CopyTo(writer.BaseStream);
             }
         }
         stream.Dispose();
         status = SaveStatus.Done;
         PUtil.LogDebug("Background save complete");
     } catch (IOException e) {
         // Autosave error!
         PUtil.LogExcWarn(e);
         status = SaveStatus.IOError;
     } catch (Exception e) {
         // Allowing it to continue here will crash with a simdll error
         PUtil.LogException(e);
         status = SaveStatus.Failed;
     } finally {
         try {
             // Cannot throw during a finally, or it will discard the original exception
             data.Dispose();
         } catch { }
     }
 }
コード例 #5
0
            /// <summary>
            /// Applied before DeserializeTypeless runs.
            /// </summary>
            internal static bool Prefix(Type type, object obj, IReader reader,
                                        ref bool __result)
            {
                var mapping = FastSerializationManager.GetFastDeserializationMapping(type);

                try {
                    mapping.Deserialize(obj, reader);
                } catch (Exception e) {
                    Debug.LogErrorFormat("Exception occurred while attempting to deserialize object {0}({1}).\n{2}",
                                         obj, obj.GetType(), e.ToString());
                    throw;
                }
                __result = true;
                return(false);
            }
コード例 #6
0
            /// <summary>
            /// Applied before Deserialize runs.
            /// </summary>
            internal static bool Prefix(Type type, IReader reader, out object result,
                                        ref bool __result)
            {
                var mapping = FastSerializationManager.GetFastDeserializationMapping(type);

                try {
                    object obj = mapping.CreateInstance();
                    mapping.Deserialize(obj, reader);
                    result = obj;
                } catch (Exception e) {
                    Debug.LogErrorFormat("Exception occurred while attempting to deserialize into object of type {0}.\n{1}",
                                         type.ToString(), e.ToString());
                    throw;
                }
                __result = true;
                return(false);
            }
コード例 #7
0
        /// <summary>
        /// Starts saving the game in the background. This function is not reentrant!
        /// </summary>
        /// <param name="filename">The file name where the save should be stored.</param>
        public void StartSave(string filename)
        {
            var  buffer = new MemoryStream(BUFFER_SIZE);
            var  inst   = SaveLoader.Instance;
            bool save   = true;

            if (inst != null)
            {
                if (FastSaveOptions.Instance.DelegateSave)
                {
                    FastSerializationManager.ClearSmart();
                }
                else
                {
                    KSerialization.Manager.Clear();
                }
#if DEBUG
                PUtil.LogDebug("Starting serialization of save");
#endif
                bool compress = true;
                // This field is currently always true
                if (COMPRESS_SAVE_DATA != null)
                {
                    try {
                        compress = COMPRESS_SAVE_DATA.Get(inst);
                    } catch { }
                }
                // Keep this part on the foreground
                try {
                    SAVE.Invoke(inst, new BinaryWriter(buffer));
                } catch (Exception e) {
                    buffer.Dispose();
                    PUtil.LogError("Error when saving game:");
                    PUtil.LogException(e);
                    save = false;
                }
                // In Unity 4 GetComponent no longer works on background threads
                if (save)
                {
                    StartSave(new BackgroundSaveData(buffer, compress, filename));
                }
            }
        }
コード例 #8
0
        /// <summary>
        /// Reads a basic value from the stream.
        /// </summary>
        /// <param name="typeInfo">The type to be deserialized.</param>
        /// <param name="reader">The stream containing serialized data.</param>
        /// <param name="baseValue">The default value for this field.</param>
        /// <returns>The deserialized value.</returns>
        internal static object ReadValue(TypeInfo typeInfo, IReader reader, object baseValue)
        {
            object result = null;
            int    n;
            var    info = typeInfo.info & SerializationTypeInfo.VALUE_MASK;

            switch (info)
            {
            case SerializationTypeInfo.UserDefined:
                n = reader.ReadInt32();
                if (n >= 0)
                {
                    var itemType = typeInfo.type;
                    if (baseValue == null)
                    {
                        result = ConstructorDelegator.CreateInstance(itemType);
                    }
                    else
                    {
                        result = baseValue;
                    }
                    FastSerializationManager.GetFastDeserializationMapping(itemType).
                    Deserialize(result, reader);
                }
                break;

            case SerializationTypeInfo.SByte:
                result = reader.ReadSByte();
                break;

            case SerializationTypeInfo.Byte:
                result = reader.ReadByte();
                break;

            case SerializationTypeInfo.Boolean:
                result = reader.ReadByte() == 1;
                break;

            case SerializationTypeInfo.Int16:
                result = reader.ReadInt16();
                break;

            case SerializationTypeInfo.UInt16:
                result = reader.ReadUInt16();
                break;

            case SerializationTypeInfo.Int32:
                result = reader.ReadInt32();
                break;

            case SerializationTypeInfo.UInt32:
                result = reader.ReadUInt32();
                break;

            case SerializationTypeInfo.Int64:
                result = reader.ReadInt64();
                break;

            case SerializationTypeInfo.UInt64:
                result = reader.ReadUInt64();
                break;

            case SerializationTypeInfo.Single:
                result = reader.ReadSingle();
                break;

            case SerializationTypeInfo.Double:
                result = reader.ReadDouble();
                break;

            case SerializationTypeInfo.String:
                result = reader.ReadKleiString();
                break;

            case SerializationTypeInfo.Enumeration:
                result = Enum.ToObject(typeInfo.type, reader.ReadInt32());
                break;

            case SerializationTypeInfo.Vector2I:
                result = reader.ReadVector2I();
                break;

            case SerializationTypeInfo.Vector2:
                result = reader.ReadVector2();
                break;

            case SerializationTypeInfo.Vector3:
                result = reader.ReadVector3();
                break;

            case SerializationTypeInfo.Array:
                reader.ReadInt32();
                result = ReadArray(typeInfo, reader, true);
                break;

            case SerializationTypeInfo.Pair:
                n = reader.ReadInt32();
                if (n >= 0)
                {
                    TypeInfo keyType = typeInfo.subTypes[0], valueType = typeInfo.subTypes[1];
                    object   key   = ReadValue(keyType, reader, null);
                    object   value = ReadValue(valueType, reader, null);
                    result = KeyValuePairDelegator.GetDelegates(keyType.type, valueType.type).
                             CreateInstance(key, value);
                }
                break;

            case SerializationTypeInfo.Dictionary:
                reader.ReadInt32();
                n = reader.ReadInt32();
                if (n >= 0)
                {
                    // Preallocate dictionary to correct size
                    result = DictionaryDelegator.CreateInstance(typeInfo.
                                                                genericInstantiationType, n);
                    var dict      = result as System.Collections.IDictionary;
                    var keyType   = typeInfo.subTypes[0];
                    var valueType = typeInfo.subTypes[1];
                    var values    = ListPool <object, FastDeserializationMapping> .Allocate();

                    for (int i = 0; i < n; i++)
                    {
                        values.Add(ReadValue(valueType, reader, null));
                    }
                    for (int i = 0; i < n; i++)
                    {
                        dict.Add(ReadValue(keyType, reader, null), values[i]);
                    }
                    values.Recycle();
                }
                break;

            case SerializationTypeInfo.HashSet:
                reader.ReadInt32();
                result = ReadArray(typeInfo, reader, false);
                if (result != null)
                {
                    result = CollectionDelegator.CreateInstance(typeInfo.
                                                                genericInstantiationType, result);
                }
                break;

            case SerializationTypeInfo.List:
            case SerializationTypeInfo.Queue:
                reader.ReadInt32();
                result = ReadArray(typeInfo, reader, true);
                if (result != null)
                {
                    // Due to how POD lists/queues are encoded, must go through a temporary
                    // array to make best usage of ReadArrayFast, sorry memory usage
                    result = CollectionDelegator.CreateInstance(typeInfo.
                                                                genericInstantiationType, result);
                }
                break;

            case SerializationTypeInfo.Colour:
                result = reader.ReadColour();
                break;

            default:
                throw new ArgumentException("Unknown type " + info);
            }
            return(result);
        }
コード例 #9
0
 /// <summary>
 /// Applied before SerializeDirectory runs.
 /// </summary>
 internal static bool Prefix(BinaryWriter writer)
 {
     FastSerializationManager.SerializeDirectory(writer);
     return(false);
 }
コード例 #10
0
 /// <summary>
 /// Applied before HasDeserializationMapping runs.
 /// </summary>
 internal static bool Prefix(Type type, ref bool __result)
 {
     __result = FastSerializationManager.HasDeserializationMapping(type);
     return(false);
 }
コード例 #11
0
 /// <summary>
 /// Applied before GetSerializationTemplate runs.
 /// </summary>
 internal static bool Prefix(Type type, ref SerializationTemplate __result)
 {
     __result = FastSerializationManager.GetKleiSerializationTemplate(type);
     return(false);
 }
コード例 #12
0
 /// <summary>
 /// Applied before DeserializeDirectory runs.
 /// </summary>
 internal static bool Prefix(IReader reader)
 {
     FastSerializationManager.DeserializeDirectory(reader);
     return(false);
 }
コード例 #13
0
 /// <summary>
 /// Applied before Clear runs.
 /// </summary>
 internal static bool Prefix()
 {
     FastSerializationManager.ClearSmart();
     return(false);
 }
コード例 #14
0
 /// <summary>
 /// Applied before WriteValue runs.
 /// </summary>
 internal static bool Prefix(BinaryWriter writer, TypeInfo type_info, object value)
 {
     FastSerializationManager.WriteValue(writer, type_info, value);
     return(false);
 }