diff --git a/BallanceTasEditor/BallanceTasEditor/BallanceTasEditor.csproj b/BallanceTasEditor/BallanceTasEditor/BallanceTasEditor.csproj
index 8051128..be52488 100644
--- a/BallanceTasEditor/BallanceTasEditor/BallanceTasEditor.csproj
+++ b/BallanceTasEditor/BallanceTasEditor/BallanceTasEditor.csproj
@@ -15,13 +15,9 @@
-
+
-
-
-
-
diff --git a/BallanceTasEditor/BallanceTasEditor/Frontend/Models/TasFile.cs b/BallanceTasEditor/BallanceTasEditor/Frontend/Models/TasFile.cs
new file mode 100644
index 0000000..076528d
--- /dev/null
+++ b/BallanceTasEditor/BallanceTasEditor/Frontend/Models/TasFile.cs
@@ -0,0 +1,84 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BallanceTasEditor.Frontend.Models {
+ public partial class TasFile : ObservableObject {
+ public TasFile() {
+ FileBody = null;
+ }
+
+ #region File Load and Save
+
+ [ObservableProperty]
+ [NotifyPropertyChangedFor(nameof(IsFileLoaded))]
+ [NotifyPropertyChangedFor(nameof(IsFileNotLoaded))]
+ private Backend.ITasSequence? fileBody;
+
+ [MemberNotNullWhen(true, nameof(FileBody))]
+ public bool IsFileLoaded {
+ get => FileBody is not null;
+ }
+
+ [MemberNotNullWhen(false, nameof(FileBody))]
+ public bool IsFileNotLoaded {
+ get => FileBody is null;
+ }
+
+ public void NewFile(TasSequenceKind kind, int count, uint fps) {
+ // Check status
+ if (IsFileLoaded) {
+ throw new InvalidOperationException();
+ }
+
+ // Initialize sequence
+ var seq = TasSequenceKindHelper.CreateSequenceByKind(kind);
+ // Initialize items
+ Backend.TasStorage.Init(seq, count, fps);
+ // Set members
+ FileBody = seq;
+ }
+
+ public void LoadFile(TasSequenceKind kind, string path) {
+ // Check status
+ if (IsFileLoaded) {
+ throw new InvalidOperationException();
+ }
+
+ // Initialize sequence
+ var seq = TasSequenceKindHelper.CreateSequenceByKind(kind);
+ // Load into sequence
+ Backend.TasStorage.Load(path, seq);
+ // Set members
+ FileBody = seq;
+ }
+
+ public void SaveFile(string path) {
+ // Check status
+ if (IsFileNotLoaded) {
+ throw new InvalidOperationException();
+ }
+
+ // Save sequence
+ Backend.TasStorage.Save(path, FileBody);
+ }
+
+ public void CloseFile() {
+ // Check status
+ if (IsFileNotLoaded) {
+ throw new InvalidOperationException();
+ }
+
+ // Set member
+ FileBody = null;
+ }
+
+ #endregion
+
+ }
+}
diff --git a/BallanceTasEditor/BallanceTasEditor/Frontend/Models/TasSequenceKind.cs b/BallanceTasEditor/BallanceTasEditor/Frontend/Models/TasSequenceKind.cs
new file mode 100644
index 0000000..2618773
--- /dev/null
+++ b/BallanceTasEditor/BallanceTasEditor/Frontend/Models/TasSequenceKind.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+namespace BallanceTasEditor.Frontend.Models {
+ public enum TasSequenceKind {
+ Array,
+ DoubleLinkedList
+ }
+
+ public static class TasSequenceKindHelper {
+ public static Backend.ITasSequence CreateSequenceByKind(TasSequenceKind kind) {
+ return kind switch {
+ TasSequenceKind.Array => new Backend.ListTasSequence(),
+ TasSequenceKind.DoubleLinkedList => new Backend.LegacyTasSequence(),
+ _ => throw new UnreachableException(),
+ };
+ }
+ }
+
+}
diff --git a/BallanceTasEditor/BallanceTasEditor/Frontend/ViewModels/MainWindow.cs b/BallanceTasEditor/BallanceTasEditor/Frontend/ViewModels/MainWindow.cs
index 6427345..e9e5f54 100644
--- a/BallanceTasEditor/BallanceTasEditor/Frontend/ViewModels/MainWindow.cs
+++ b/BallanceTasEditor/BallanceTasEditor/Frontend/ViewModels/MainWindow.cs
@@ -15,8 +15,9 @@ namespace BallanceTasEditor.Frontend.ViewModels {
public MainWindow(Shared.IDialogService dialogService) {
m_DialogService = dialogService;
- this.TasFile = null;
- this.TasFilePath = null;
+ TasFile = new Models.TasFile();
+ TasFile.PropertyChanged += TasFile_PropertyChanged;
+ TasFilePath = null;
this.StatusMessage = "";
m_StatusMessageDimmer = new DispatcherTimer();
@@ -33,34 +34,38 @@ namespace BallanceTasEditor.Frontend.ViewModels {
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(WindowTitle))]
- [NotifyCanExecuteChangedFor(nameof(NewFileCommand))]
- [NotifyCanExecuteChangedFor(nameof(OpenFileCommand))]
- [NotifyCanExecuteChangedFor(nameof(SaveFileCommand))]
- [NotifyCanExecuteChangedFor(nameof(SaveFileAsCommand))]
- [NotifyCanExecuteChangedFor(nameof(CloseFileCommand))]
- private Backend.ITasSequence? tasFile;
+ private Models.TasFile tasFile;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(WindowTitle))]
private string? tasFilePath;
+ private void TasFile_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e) {
+ // YYC MARK:
+ // Due to the shitty limit of MVVM Toolkit,
+ // I was forced trigger these command manually.
+ NewFileCommand.NotifyCanExecuteChanged();
+ OpenFileCommand.NotifyCanExecuteChanged();
+ SaveFileCommand.NotifyCanExecuteChanged();
+ SaveFileAsCommand.NotifyCanExecuteChanged();
+ CloseFileCommand.NotifyCanExecuteChanged();
+ }
+
[RelayCommand(CanExecute = nameof(CanNewFile))]
private void NewFile() {
// Request new file properties
var dialog = m_DialogService.ShowNewFileDialog();
if (dialog is null) return;
- // Initialize sequence
- var seq = new Backend.ListTasSequence();
- // Initialize items
- Backend.TasStorage.Init(seq, dialog.Count, dialog.Fps);
+ // Create new file
+ TasFile.NewFile(Models.TasSequenceKind.Array, dialog.Count, dialog.Fps);
// Set members
- this.TasFile = seq;
- this.TasFilePath = null;
+ TasFilePath = null;
+ // Send notification
UpdateStatusMessage($"New TAS file is created.");
}
private bool CanNewFile() {
- return this.TasFile is null;
+ return TasFile.IsFileNotLoaded;
}
[RelayCommand(CanExecute = nameof(CanOpenFile))]
@@ -69,23 +74,21 @@ namespace BallanceTasEditor.Frontend.ViewModels {
var dialog = m_DialogService.ShowOpenFileDialog();
if (dialog is null) return;
- // Initialize sequence
- var seq = new Backend.ListTasSequence();
- // Load into sequence
+ // Load file
try {
- Backend.TasStorage.Load(dialog.Path, seq);
+ TasFile.LoadFile(Models.TasSequenceKind.Array, dialog.Path);
} catch (Exception e) {
m_DialogService.ShowOpenFileFailedDialog(e);
return;
}
// Set members
- this.TasFile = seq;
- this.TasFilePath = dialog.Path;
+ TasFilePath = dialog.Path;
+ // Send notification
UpdateStatusMessage($"TAS file {this.TasFilePath} is loaded.");
}
private bool CanOpenFile() {
- return this.TasFile is null;
+ return TasFile.IsFileNotLoaded;
}
[RelayCommand(CanExecute = nameof(CanSaveFile))]
@@ -102,18 +105,19 @@ namespace BallanceTasEditor.Frontend.ViewModels {
// Save file
try {
- Backend.TasStorage.Save(filePath, this.TasFile.Unwrap());
+ TasFile.SaveFile(filePath);
} catch (Exception e) {
m_DialogService.ShowSaveFileFailedDialog(e);
return;
}
// Update member
- this.TasFilePath = filePath;
+ TasFilePath = filePath;
+ // Send notification
UpdateStatusMessage($"TAS file {this.TasFilePath} is saved.");
}
private bool CanSaveFile() {
- return this.TasFile is not null;
+ return TasFile.IsFileLoaded;
}
[RelayCommand(CanExecute = nameof(CanSaveFileAs))]
@@ -124,29 +128,33 @@ namespace BallanceTasEditor.Frontend.ViewModels {
// Save file
try {
- Backend.TasStorage.Save(dialog.Path, this.TasFile.Unwrap());
+ TasFile.SaveFile(dialog.Path);
} catch (Exception e) {
m_DialogService.ShowSaveFileFailedDialog(e);
return;
}
// Set file path
TasFilePath = dialog.Path;
+ // Send notification
UpdateStatusMessage($"TAS file {this.TasFilePath} is saved.");
}
private bool CanSaveFileAs() {
- return this.TasFile is not null;
+ return TasFile.IsFileLoaded;
}
[RelayCommand(CanExecute = nameof(CanCloseFile))]
private void CloseFile() {
- this.TasFile = null;
- this.TasFilePath = null;
+ // Close file
+ TasFile.CloseFile();
+ // Set members
+ TasFilePath = null;
+ // Send notification
UpdateStatusMessage($"TAS file is closed.");
}
private bool CanCloseFile() {
- return this.TasFile is not null;
+ return TasFile.IsFileLoaded;
}
#endregion
@@ -228,7 +236,7 @@ namespace BallanceTasEditor.Frontend.ViewModels {
public string WindowTitle {
get {
- if (TasFile is null) {
+ if (TasFile.IsFileNotLoaded) {
return "Ballance TAS Editor";
} else {
if (TasFilePath is null) {