Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Offload project loading, add loading bar modal #31

Merged
merged 1 commit into from
Feb 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 34 additions & 3 deletions src/SerialLoops.Lib/Project.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using HaruhiChokuretsuLib.Util;
using NAudio.MediaFoundation;
using SerialLoops.Lib.Items;
using SerialLoops.Lib.Util;
using System;
using System.Collections.Generic;
using System.IO;
Expand Down Expand Up @@ -59,15 +60,26 @@ public Project(string name, string langCode, Config config, ILogger log)
}
}

public void LoadArchives(ILogger log)
public void LoadArchives(ILogger log, IProgressTracker tracker)
{
tracker.Focus("dat.bin", 3);
Dat = ArchiveFile<DataFile>.FromFile(Path.Combine(IterativeDirectory, "original", "archives", "dat.bin"), log);
tracker.Loaded++;

tracker.CurrentlyLoading = "grp.bin";
Grp = ArchiveFile<GraphicsFile>.FromFile(Path.Combine(IterativeDirectory, "original", "archives", "grp.bin"), log);
tracker.Loaded++;

tracker.CurrentlyLoading = "evt.bin";
Evt = ArchiveFile<EventFile>.FromFile(Path.Combine(IterativeDirectory, "original", "archives", "evt.bin"), log);
tracker.Loaded++;

tracker.Focus("Extras", 1);
ExtraFile extras = Dat.Files.First(f => f.Name == "EXTRAS").CastTo<ExtraFile>();
tracker.Loaded++;

BgTableFile bgTable = Dat.Files.First(f => f.Name == "BGTBLS").CastTo<BgTableFile>();
tracker.Focus("Backgrounds", bgTable.BgTableEntries.Count);
for (int i = 0; i < bgTable.BgTableEntries.Count; i++)
{
BgTableEntry entry = bgTable.BgTableEntries[i];
Expand All @@ -82,55 +94,74 @@ public void LoadArchives(ILogger log)
}
Items.Add(new BackgroundItem(name, i, entry, Evt, Grp, extras));
}
tracker.Loaded++;
}

string[] bgmFiles = Directory.GetFiles(Path.Combine(IterativeDirectory, "original", "bgm")).OrderBy(s => s).ToArray();
tracker.Focus("BGM Tracks", bgmFiles.Length);
for (int i = 0; i < bgmFiles.Length; i++)
{
Items.Add(new BackgroundMusicItem(bgmFiles[i], i, extras, this));
tracker.Loaded++;
}

string[] voiceFiles = Directory.GetFiles(Path.Combine(IterativeDirectory, "original", "vce")).OrderBy(s => s).ToArray();
tracker.Focus("Voiced Lines", voiceFiles.Length);
for (int i = 0; i < voiceFiles.Length; i++)
{
Items.Add(new VoicedLineItem(voiceFiles[i], i + 1, this));
tracker.Loaded++;
}

tracker.Focus("Character Sprites", 1);
CharacterDataFile chrdata = Dat.Files.First(d => d.Name == "CHRDATAS").CastTo<CharacterDataFile>();
Items.AddRange(chrdata.Sprites.Where(s => (int)s.Character > 0).Select(s => new CharacterSpriteItem(s, chrdata, this)));
tracker.Loaded++;

tracker.Focus("Chibis", 1);
Items.AddRange(Dat.Files.First(d => d.Name == "CHIBIS").CastTo<ChibiFile>()
.Chibis.Select(c => new ChibiItem(c, this)));
tracker.Loaded++;

tracker.Focus("Event Files", 1);
Items.AddRange(Evt.Files
.Where(e => !new string[] { "CHESSS", "EVTTBLS", "TOPICS", "SCENARIOS", "TUTORIALS", "VOICEMAPS" }.Contains(e.Name))
.Select(e => new ScriptItem(e)));
tracker.Loaded++;

tracker.Focus("Maps", 1);
QMapFile qmap = Dat.Files.First(f => f.Name == "QMAPS").CastTo<QMapFile>();
Items.AddRange(Dat.Files
.Where(d => qmap.QMaps.Select(q => q.Name.Replace(".", "")).Contains(d.Name))
.Select(m => new MapItem(m.CastTo<MapFile>(), qmap.QMaps.FindIndex(q => q.Name.Replace(".", "") == m.Name))));
tracker.Loaded++;

tracker.Focus("Puzzles", 1);
Items.AddRange(Dat.Files
.Where(d => d.Name.StartsWith("SLG"))
.Select(d => new PuzzleItem(d.CastTo<PuzzleFile>(), this)));
tracker.Loaded++;

// Scenario item must be created after script and puzzle items are constructed
tracker.Focus("Scenario", 1);
EventFile scenarioFile = Evt.Files.First(f => f.Name == "SCENARIOS");
scenarioFile.InitializeScenarioFile();
Items.Add(new ScenarioItem(scenarioFile.Scenario, this));
tracker.Loaded++;
}

public ItemDescription FindItem(string name)
{
return Items.FirstOrDefault(i => i.Name == name);
}

public static Project OpenProject(string projFile, Config config, ILogger log)
public static Project OpenProject(string projFile, Config config, ILogger log, IProgressTracker tracker)
{
log.Log($"Loading project from '{projFile}'...");
tracker.Focus($"{Path.GetFileNameWithoutExtension(projFile)} Project Data", 1);
Project project = JsonSerializer.Deserialize<Project>(File.ReadAllText(projFile));
project.LoadArchives(log);
tracker.Loaded++;
project.LoadArchives(log, tracker);
return project;
}
}
Expand Down
18 changes: 18 additions & 0 deletions src/SerialLoops.Lib/Util/IProgressTracker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;

namespace SerialLoops.Lib.Util
{
public interface IProgressTracker
{
public int Loaded { get; set; }
public int Total { get; set; }
public string CurrentlyLoading { get; set; }

public void Focus(string item, int count)
{
Total += count;
CurrentlyLoading = item;
}

}
}
49 changes: 49 additions & 0 deletions src/SerialLoops/LoadingDialog.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using Eto.Drawing;
using Eto.Forms;
using SerialLoops.Controls;
using SerialLoops.Lib.Util;
using SerialLoops.Utility;
using System;
using System.Threading.Tasks;

namespace SerialLoops
{
public class LoadingDialog : Dialog
{

private readonly Action _loadingTask;
private readonly LoopyProgressTracker _tracker;
private readonly Action _onComplete;

public LoadingDialog(Action loadingTask, Action onComplete, LoopyProgressTracker tracker)
{
_loadingTask = loadingTask;
_tracker = tracker;
_onComplete = onComplete;

Title = "Loading";
ShowInTaskbar = false;
Closeable = false;
Resizable = false;
MinimumSize = new Size(300, 100);
Content = tracker;

ShowModal();
}

protected async override void OnShown(EventArgs e)
{
base.OnShown(e);
await Task.Run(() =>
{
_loadingTask();
Application.Instance.Invoke(() =>
{
_onComplete();
});
});
Close();
}

}
}
20 changes: 15 additions & 5 deletions src/SerialLoops/MainForm.eto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
using SerialLoops.Editors;
using SerialLoops.Lib;
using SerialLoops.Lib.Items;
using SerialLoops.Lib.Util;
using SerialLoops.Utility;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace SerialLoops
{
Expand Down Expand Up @@ -162,20 +164,28 @@ private void OpenProject_Executed(object sender, EventArgs e)
openFileDialog.Filters.Add(new("Serial Loops Project", $".{Project.PROJECT_FORMAT}"));
if (openFileDialog.ShowAndReportIfFileSelected(this))
{
OpenProject = Project.OpenProject(openFileDialog.FileName, CurrentConfig, _log);
OpenProjectView(OpenProject);
OpenProjectFromPath(openFileDialog.FileName);
}
}

private void OpenRecentProject_Executed(object sender, EventArgs e)
{
Command command = (Command)sender;
OpenProject = Project.OpenProject(command.ToolTip, CurrentConfig, _log);
OpenProjectView(OpenProject);
OpenProjectFromPath(((Command)sender).ToolTip);
}

private void OpenProjectFromPath(string path)
{
LoopyProgressTracker tracker = new ();
new LoadingDialog(() => OpenProject = Project.OpenProject(path, CurrentConfig, _log, tracker), () => OpenProjectView(OpenProject), tracker);
}

private void SaveProject_Executed(object sender, EventArgs e)
{
if (OpenProject == null)
{
return;
}

IEnumerable<ItemDescription> unsavedItems = OpenProject.Items.Where(i => i.UnsavedChanges);
foreach (ItemDescription item in unsavedItems)
{
Expand Down
2 changes: 1 addition & 1 deletion src/SerialLoops/ProjectCreationDialog.eto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ private void CreateCommand_Executed(object sender, EventArgs e)
}
}
IO.OpenRom(NewProject, _romPath.Text, includeFontHack);
NewProject.LoadArchives(Log);
NewProject.LoadArchives(Log, new LoopyProgressTracker());
Close();
}
}
Expand Down
58 changes: 58 additions & 0 deletions src/SerialLoops/Utility/LoopyProgressTracker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using Eto.Forms;
using SerialLoops.Lib.Util;
using System;

namespace SerialLoops.Utility
{
public class LoopyProgressTracker : StackLayout, IProgressTracker
{

private readonly ProgressBar _loadingProgress;
private readonly Label _loadingItem;

public LoopyProgressTracker()
{
_loadingProgress = new() { Width = 390 };
_loadingItem = new();

Padding = 10;
Spacing = 10;
HorizontalContentAlignment = HorizontalAlignment.Center;
Items.Add(_loadingItem);
Items.Add(_loadingProgress);
}


private int _current;
public int Loaded {
get => _current;
set
{
_current = value;
Application.Instance.Invoke(() => _loadingProgress.Value = _current);
}
}

private int _total;
public int Total
{
get => _total;
set
{
_total = value;
Application.Instance.Invoke(() => _loadingProgress.MaxValue = _total);
}
}

private string _currentlyLoading;
public string CurrentlyLoading {
get => _currentlyLoading;
set
{
_currentlyLoading = $"Loading {value}...";
Application.Instance.Invoke(() => _loadingItem.Text = _currentlyLoading);
}
}

}
}