Made saving a little more convenient by putting it in its own thread. Might be very buggy still.

Also temporarily disabled reading TAStudio settings in PlaybackBox because of a NullReferenceException
This commit is contained in:
christoph.boehmwalder 2015-01-03 02:29:55 +00:00
parent c10682b147
commit c3f51f8b39
6 changed files with 986 additions and 892 deletions

View File

@ -7,6 +7,8 @@ using System.Text;
using BizHawk.Common;
using BizHawk.Common.CollectionExtensions;
using BizHawk.Common.IOExtensions;
using System.Diagnostics;
using System.ComponentModel;
namespace BizHawk.Client.Common
{
@ -14,9 +16,26 @@ namespace BizHawk.Client.Common
{
public Func<string> ClientSettingsForSave { get; set; }
public Action<string> GetClientSettingsOnLoad { get; set; }
private const double PROGRESS_STEP = 100 / 12; // TODO hardcoded for now, there might be a better way of doing this
private double _totalProgress = 0;
private void ReportProgress(double percent)
{
if (_progressReportWorker != null)
{
_totalProgress += percent;
_progressReportWorker.ReportProgress((int)_totalProgress);
}
}
protected override void Write(string fn)
{
_totalProgress = 0;
var file = new FileInfo(fn);
if (!file.Directory.Exists)
{
@ -26,22 +45,29 @@ namespace BizHawk.Client.Common
using (var bs = new BinaryStateSaver(fn, false))
{
bs.PutLump(BinaryStateLump.Movieheader, tw => tw.WriteLine(Header.ToString()));
bs.PutLump(BinaryStateLump.Comments, tw => tw.WriteLine(CommentsString()));
bs.PutLump(BinaryStateLump.Subtitles, tw => tw.WriteLine(Subtitles.ToString()));
bs.PutLump(BinaryStateLump.SyncSettings, tw => tw.WriteLine(SyncSettingsJson));
bs.PutLump(BinaryStateLump.Input, tw => tw.WriteLine(RawInputLog()));
ReportProgress(PROGRESS_STEP);
bs.PutLump(BinaryStateLump.Comments, tw => tw.WriteLine(CommentsString()));
ReportProgress(PROGRESS_STEP);
bs.PutLump(BinaryStateLump.Subtitles, tw => tw.WriteLine(Subtitles.ToString()));
ReportProgress(PROGRESS_STEP);
bs.PutLump(BinaryStateLump.SyncSettings, tw => tw.WriteLine(SyncSettingsJson));
ReportProgress(PROGRESS_STEP);
bs.PutLump(BinaryStateLump.Input, tw => tw.WriteLine(RawInputLog()));
ReportProgress(PROGRESS_STEP);
// TasProj extras
bs.PutLump(BinaryStateLump.GreenzoneSettings, tw => tw.WriteLine(StateManager.Settings.ToString()));
bs.PutLump(BinaryStateLump.GreenzoneSettings, tw => tw.WriteLine(StateManager.Settings.ToString()));
ReportProgress(PROGRESS_STEP);
if (StateManager.Settings.SaveGreenzone)
{
bs.PutLump(BinaryStateLump.Greenzone, (BinaryWriter bw) => StateManager.Save(bw));
}
}
ReportProgress(PROGRESS_STEP);
bs.PutLump(BinaryStateLump.LagLog, (BinaryWriter bw) => LagLog.Save(bw));
bs.PutLump(BinaryStateLump.Markers, tw => tw.WriteLine(Markers.ToString()));
bs.PutLump(BinaryStateLump.LagLog, (BinaryWriter bw) => LagLog.Save(bw));
ReportProgress(PROGRESS_STEP);
bs.PutLump(BinaryStateLump.Markers, tw => tw.WriteLine(Markers.ToString()));
ReportProgress(PROGRESS_STEP);
if (StartsFromSavestate)
{
@ -53,18 +79,20 @@ namespace BizHawk.Client.Common
{
bs.PutLump(BinaryStateLump.Corestate, (BinaryWriter bw) => bw.Write(BinarySavestate));
}
}
}
ReportProgress(PROGRESS_STEP);
if (ClientSettingsForSave != null)
{
var clientSettingsJson = ClientSettingsForSave();
bs.PutLump(BinaryStateLump.ClientSettings, (TextWriter tw) => tw.Write(clientSettingsJson));
}
}
ReportProgress(PROGRESS_STEP);
if (VerificationLog.Any())
{
bs.PutLump(BinaryStateLump.VerificationLog, tw => tw.WriteLine(InputLogToString(VerificationLog)));
}
}
ReportProgress(PROGRESS_STEP);
}
Changes = false;

View File

@ -22,10 +22,12 @@ namespace BizHawk.Client.Common
private readonly Dictionary<int, IController> InputStateCache = new Dictionary<int, IController>();
private readonly List<string> VerificationLog = new List<string>(); // For movies that do not begin with power-on, this is the input required to get into the initial state
public TasMovie(string path, bool startsFromSavestate = false) : base(path)
private BackgroundWorker _progressReportWorker = null;
public TasMovie(string path, bool startsFromSavestate = false, BackgroundWorker progressReportWorker = null) : base(path)
{
// TODO: how to call the default constructor AND the base(path) constructor? And is base(path) calling base() ?
_progressReportWorker = progressReportWorker;
if (!Global.Emulator.HasSavestates())
{
throw new InvalidOperationException("Cannot create a TasMovie against a core that does not implement IStatable");
@ -38,9 +40,10 @@ namespace BizHawk.Client.Common
Markers.Add(0, startsFromSavestate ? "Savestate" : "Power on");
}
public TasMovie(bool startsFromSavestate = false)
public TasMovie(bool startsFromSavestate = false, BackgroundWorker progressReportWorker = null)
: base()
{
{
_progressReportWorker = progressReportWorker;
if (!Global.Emulator.HasSavestates())
{
throw new InvalidOperationException("Cannot create a TasMovie against a core that does not implement IStatable");

View File

@ -53,12 +53,15 @@ namespace BizHawk.Client.EmuHawk
{
get
{
return Tastudio.Settings.FollowCursor;
return false;
// FIXME
//return Tastudio.Settings.FollowCursor;
}
set
{
FollowCursorCheckbox.Checked = Tastudio.Settings.FollowCursor = value;
// FIXME
//FollowCursorCheckbox.Checked = Tastudio.Settings.FollowCursor = value;
}
}
@ -80,8 +83,9 @@ namespace BizHawk.Client.EmuHawk
if (Tastudio != null) // For the designer
{
AutoRestoreCheckbox.Checked = Tastudio.Settings.AutoRestoreLastPosition;
FollowCursorCheckbox.Checked = Tastudio.Settings.FollowCursor;
// FIXME
//AutoRestoreCheckbox.Checked = Tastudio.Settings.AutoRestoreLastPosition;
//FollowCursorCheckbox.Checked = Tastudio.Settings.FollowCursor;
}
_programmaticallyChangingValue = false;

File diff suppressed because it is too large Load Diff

View File

@ -77,8 +77,9 @@ namespace BizHawk.Client.EmuHawk
}
else
{
CurrentTasMovie.Save();
MessageStatusLabel.Text = Path.GetFileName(CurrentTasMovie.Filename) + " saved.";
//CurrentTasMovie.Save();
//MessageStatusLabel.Text = Path.GetFileName(CurrentTasMovie.Filename) + " saved.";
_saveBackgroundWorker.RunWorkerAsync();
Settings.RecentTas.Add(CurrentTasMovie.Filename);
}
}
@ -95,9 +96,11 @@ namespace BizHawk.Client.EmuHawk
if (file != null)
{
CurrentTasMovie.Filename = file.FullName;
CurrentTasMovie.Save();
//CurrentTasMovie.Save();
_saveBackgroundWorker.RunWorkerAsync();
Settings.RecentTas.Add(CurrentTasMovie.Filename);
MessageStatusLabel.Text = Path.GetFileName(CurrentTasMovie.Filename) + " saved.";
//MessageStatusLabel.Text = Path.GetFileName(CurrentTasMovie.Filename) + " saved.";
SetTextProperty();
}
}

View File

@ -24,6 +24,8 @@ namespace BizHawk.Client.EmuHawk
private readonly List<TasClipboardEntry> _tasClipboard = new List<TasClipboardEntry>();
private BackgroundWorker _saveBackgroundWorker;
private MovieEndAction _originalEndAction; // The movie end behavior selected by the user (that is overridden by TAStudio)
private Dictionary<string, string> GenerateColumnNames()
{
@ -65,6 +67,39 @@ namespace BizHawk.Client.EmuHawk
InitializeComponent();
Settings = new TAStudioSettings();
// TODO: show this at all times or hide it when saving is done?
this.SavingProgressBar.Visible = false;
_saveBackgroundWorker = new BackgroundWorker();
_saveBackgroundWorker.WorkerReportsProgress = true;
_saveBackgroundWorker.DoWork += (s, e) =>
{
this.Invoke(() => this.MessageStatusLabel.Text = "Saving " + Path.GetFileName(CurrentTasMovie.Filename) + "...");
this.Invoke(() => this.SavingProgressBar.Visible = true);
CurrentTasMovie.Save();
};
_saveBackgroundWorker.ProgressChanged += (s, e) =>
{
SavingProgressBar.Value = e.ProgressPercentage;
};
_saveBackgroundWorker.RunWorkerCompleted += (s, e) =>
{
this.Invoke(() => this.MessageStatusLabel.Text = Path.GetFileName(CurrentTasMovie.Filename) + " saved.");
this.Invoke(() => this.SavingProgressBar.Visible = false);
// SUPER HACKY, and i'm not even sure it's necessary
Timer t = new Timer();
t.Tick += (a, b) =>
{
this.Invoke(() => this.MessageStatusLabel.Text = "TAStudio engaged.");
t.Stop();
};
t.Interval = 5000;
t.Start();
};
WantsToControlStopMovie = true;
TasPlaybackBox.Tastudio = this;
MarkerControl.Tastudio = this;
@ -77,6 +112,7 @@ namespace BizHawk.Client.EmuHawk
TasView.MultiSelect = true;
TasView.MaxCharactersInHorizontal = 1;
WantsToControlRestartMovie = true;
}
private void TastudioToStopMovie()
@ -120,7 +156,7 @@ namespace BizHawk.Client.EmuHawk
private void NewTasMovie()
{
Global.MovieSession.Movie = new TasMovie();
Global.MovieSession.Movie = new TasMovie(false, _saveBackgroundWorker);
SetTasMovieCallbacks();
CurrentTasMovie.PropertyChanged += new PropertyChangedEventHandler(this.TasMovie_OnPropertyChanged);
CurrentTasMovie.Filename = DefaultTasProjName(); // TODO don't do this, take over any mainform actions that can crash without a filename
@ -194,14 +230,17 @@ namespace BizHawk.Client.EmuHawk
text += " - " + CurrentTasMovie.Name + (CurrentTasMovie.Changes ? "*" : "");
}
Text = text;
if (this.InvokeRequired)
this.Invoke(() => Text = text);
else
Text = text;
}
public bool LoadProject(string path)
{
if (AskSaveChanges())
{
var movie = new TasMovie
var movie = new TasMovie(false, _saveBackgroundWorker)
{
Filename = path,
ClientSettingsForSave = ClientSettingsForSave,