예제 #1
0
 /// <summary>
 /// Saves the game to disk in the background.
 /// </summary>
 /// <param name="data">The uncompressed save data.</param>
 private void DoSave(BackgroundSaveData data)
 {
     byte[] buffer;
     try {
         var  stream = data.Stream;
         long len    = stream.Length;
         // Uh oh
         if (len >= int.MaxValue)
         {
             PUtil.LogError("Save file is too big, game will not save correctly!");
         }
         else
         {
             PUtil.LogDebug("Background save to: " + data.FileName);
         }
         if (data.Compress)
         {
             buffer = SaveLoader.CompressContents(stream.GetBuffer(), (int)len);
         }
         else
         {
             buffer = stream.ToArray();
         }
         CleanAutosaves(data.FileName);
         // 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);
             KSerialization.Manager.SerializeDirectory(writer);
             writer.Write(buffer);
             writer.Flush();
         }
         buffer = null;
         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 (Exception e) {
             PUtil.LogException(e);
         }
     }
 }
예제 #2
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 { }
     }
 }
예제 #3
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(data.FileName);
         // 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);
             KSerialization.Manager.SerializeDirectory(writer);
             writer.Flush();
             if (data.Compress)
             {
                 // SaveLoader.CompressContents is now private
                 using (var compressor = new ZlibStream(writer.BaseStream,
                                                        CompressionMode.Compress, CompressionLevel.BestSpeed)) {
                     stream.CopyTo(compressor);
                     compressor.Flush();
                 }
             }
             else
             {
                 stream.CopyTo(writer.BaseStream);
             }
         }
         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 (Exception e) {
             PUtil.LogException(e);
         }
     }
 }
예제 #4
0
        /// <summary>
        /// Starts saving the game in the background.
        /// </summary>
        /// <param name="data">The uncompressed save data.</param>
        private void StartSave(BackgroundSaveData data)
        {
            // Wait until current save is complete (best effort)
            while (true)
            {
                lock (startLock) {
                    if (status != SaveStatus.InProgress)
                    {
#if DEBUG
                        PUtil.LogDebug("Switching save to background task");
#endif
                        var task = new Thread(() => DoSave(data));
                        status = SaveStatus.InProgress;
                        Util.ApplyInvariantCultureToThread(task);
                        task.Priority = System.Threading.ThreadPriority.BelowNormal;
                        task.Name     = "Background Autosave";
                        Thread.MemoryBarrier();
                        task.Start();
                        break;
                    }
                }
            }
        }