Last active
April 13, 2020 03:53
-
-
Save pCYSl5EDgo/fc3847f4c4a3b58c0dbc47d2c960620d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using System.Threading.Tasks; | |
class SaveData | |
{ | |
// 中身は適切に書いてね | |
} | |
class SaveDataSerializer | |
{ | |
public byte[] Serialize(SaveData data, int turnCount, DateTime savindTime) | |
{ | |
// 中身は適切に書いてね | |
return Array.Empty<byte>(); | |
} | |
} | |
class Saver | |
{ | |
private const int backupInterval = 12; | |
private readonly FileInfo normalSaveFile; | |
private readonly FileInfo backupSaveFile; | |
private readonly SaveData data; | |
private readonly SaveDataSerializer serializer; | |
private Task previousNormalSavingTask; | |
private FileStream normalFileStream; | |
public Saver(SaveData data, string normalSaveFilePath, string backupSaveFilePath, SaveDataSerializer serializer) | |
{ | |
normalSaveFile = new FileInfo(normalSaveFilePath); | |
backupSaveFile = new FileInfo(backupSaveFilePath); | |
previousNormalSavingTask = Task.CompletedTask; | |
this.data = data; | |
this.serializer = serializer; | |
} | |
public void Save(int currentTurnCount) | |
{ | |
if (currentTurnCount <= 0 || (currentTurnCount / backupInterval) * backupInterval != currentTurnCount) | |
{ | |
SaveWithoutBackup(currentTurnCount); | |
} | |
else | |
{ | |
SaveWithBackup(currentTurnCount); | |
} | |
} | |
private void SaveWithBackup(int turnCount) | |
{ | |
var isPreviousTaskEnded = previousNormalSavingTask.IsCompleted || previousNormalSavingTask.IsCanceled || previousNormalSavingTask.IsFaulted; | |
if (isPreviousTaskEnded) | |
{ | |
SaveWithBackupInternal(turnCount); | |
} | |
else | |
{ | |
previousNormalSavingTask.ContinueWith(SaveWithBackUpInternalContinuation, (this, turnCount)); | |
} | |
} | |
private static void SaveWithBackUpInternalContinuation(Task _, object obj) | |
{ | |
var (@this, turnCount) = (ValueTuple<Saver, int>)obj; | |
@this.SaveWithBackupInternal(turnCount); | |
} | |
private void SaveWithBackupInternal(int turnCount) | |
{ | |
normalFileStream = normalSaveFile.OpenWrite(); | |
var bytes = serializer.Serialize(data, turnCount, DateTime.Now); | |
previousNormalSavingTask = normalFileStream.WriteAsync(bytes, 0, bytes.Length) | |
.ContinueWith(FileStreamDisposingContinuation, normalFileStream) | |
.ContinueWith(CopyContinuation, (normalSaveFile.FullName, backupSaveFile.FullName)); | |
} | |
private static void FileStreamDisposingContinuation(Task _, object obj) | |
{ | |
var fileStream = (FileStream)obj; | |
fileStream.Dispose(); | |
} | |
private static void CopyContinuation(Task _, object obj) | |
{ | |
var (normal, backup) = (ValueTuple<string, string>)obj; | |
File.Copy(normal, backup, overwrite: true); | |
} | |
private void SaveWithoutBackup(int turnCount) | |
{ | |
var isPreviousTaskEnded = previousNormalSavingTask.IsCompleted || previousNormalSavingTask.IsCanceled || previousNormalSavingTask.IsFaulted; | |
if (isPreviousTaskEnded) | |
{ | |
SaveWithoutBackupInternal(turnCount); | |
} | |
else | |
{ | |
previousNormalSavingTask.ContinueWith(SaveWithoutBackUpInternalContinuation, (this, turnCount)); | |
} | |
} | |
private static void SaveWithoutBackUpInternalContinuation(Task _, object obj) | |
{ | |
var (@this, turnCount) = (ValueTuple<Saver, int>)obj; | |
@this.SaveWithoutBackupInternal(turnCount); | |
} | |
private void SaveWithoutBackupInternal(int turnCount) | |
{ | |
normalFileStream = normalSaveFile.OpenWrite(); | |
var bytes = serializer.Serialize(data, turnCount, DateTime.Now); | |
previousNormalSavingTask = normalFileStream.WriteAsync(bytes, 0, bytes.Length) | |
.ContinueWith(FileStreamDisposingContinuation, normalFileStream); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment