diff --git a/BizHawk.Client.Common/movie/tasproj/StateManagerState.cs b/BizHawk.Client.Common/movie/tasproj/StateManagerState.cs
index c1a6801f47..d0f23013aa 100644
--- a/BizHawk.Client.Common/movie/tasproj/StateManagerState.cs
+++ b/BizHawk.Client.Common/movie/tasproj/StateManagerState.cs
@@ -4,24 +4,17 @@ using System.IO;
namespace BizHawk.Client.Common
{
///
- /// Represents a savestate in the TasStateManager
+ /// Represents a savestate in the
///
internal class StateManagerState : IDisposable
{
private static long _stateId = 0;
- private TasStateManager _manager;
+ private readonly TasStateManager _manager;
+ private readonly long _id;
private byte[] _state;
- private long _id;
- public int Frame { get; set; }
-
- public void Write(BinaryWriter w)
- {
- w.Write(Frame);
- w.Write(_state.Length);
- w.Write(_state);
- }
+ public int Frame { get; }
public static StateManagerState Read(BinaryReader r, TasStateManager m)
{
@@ -30,6 +23,13 @@ namespace BizHawk.Client.Common
return new StateManagerState(m, data, frame);
}
+ public void Write(BinaryWriter w)
+ {
+ w.Write(Frame);
+ w.Write(_state.Length);
+ w.Write(_state);
+ }
+
public byte[] State
{
get
@@ -41,6 +41,7 @@ namespace BizHawk.Client.Common
return _manager.ndbdatabase.FetchAll(_id.ToString());
}
+
set
{
if (_state != null)
@@ -54,17 +55,11 @@ namespace BizHawk.Client.Common
}
}
- public int Length
- {
- get { return State.Length; }
- }
+ public int Length => State.Length;
- public bool IsOnDisk
- {
- get { return _state == null; }
- }
+ public bool IsOnDisk => _state == null;
- public StateManagerState(TasStateManager manager, byte[] state, int frame)
+ public StateManagerState(TasStateManager manager, byte[] state, int frame)
{
_manager = manager;
_state = state;
@@ -104,7 +99,9 @@ namespace BizHawk.Client.Common
public void Dispose()
{
if (!IsOnDisk)
+ {
return;
+ }
_manager.ndbdatabase.Release(_id.ToString());
}
diff --git a/BizHawk.Client.Common/movie/tasproj/TasBranch.cs b/BizHawk.Client.Common/movie/tasproj/TasBranch.cs
index 30db681acf..13faf2d0f8 100644
--- a/BizHawk.Client.Common/movie/tasproj/TasBranch.cs
+++ b/BizHawk.Client.Common/movie/tasproj/TasBranch.cs
@@ -34,7 +34,10 @@ namespace BizHawk.Client.Common
{
var currentHashes = this.Select(b => b.UniqueIdentifier.GetHashCode()).ToList();
- do item.UniqueIdentifier = Guid.NewGuid();
+ do
+ {
+ item.UniqueIdentifier = Guid.NewGuid();
+ }
while (currentHashes.Contains(item.UniqueIdentifier.GetHashCode()));
}
@@ -57,9 +60,9 @@ namespace BizHawk.Client.Common
// if this header needs more stuff in it, handle it sensibly
tw.WriteLine(JsonConvert.SerializeObject(new
{
- Frame = b.Frame,
- TimeStamp = b.TimeStamp,
- UniqueIdentifier = b.UniqueIdentifier
+ b.Frame,
+ b.TimeStamp,
+ b.UniqueIdentifier
}));
});
@@ -72,7 +75,9 @@ namespace BizHawk.Client.Common
{
int todo = b.InputLog.Count;
for (int i = 0; i < todo; i++)
+ {
tw.WriteLine(b.InputLog[i]);
+ }
});
bs.PutLump(nframebuffer, delegate(Stream s)
diff --git a/BizHawk.Client.Common/movie/tasproj/TasLagLog.cs b/BizHawk.Client.Common/movie/tasproj/TasLagLog.cs
index 9582b662d8..03514f5fa6 100644
--- a/BizHawk.Client.Common/movie/tasproj/TasLagLog.cs
+++ b/BizHawk.Client.Common/movie/tasproj/TasLagLog.cs
@@ -20,11 +20,14 @@ namespace BizHawk.Client.Common
if (frame < LagLog.Count)
{
if (frame < 0)
+ {
return null;
- else
- return LagLog[frame];
+ }
+
+ return LagLog[frame];
}
- else if (frame == Global.Emulator.Frame && frame == LagLog.Count)
+
+ if (frame == Global.Emulator.Frame && frame == LagLog.Count)
{
// LagLog[frame] = Global.Emulator.AsInputPollable().IsLagFrame; // Note: Side effects!
return Global.Emulator.AsInputPollable().IsLagFrame;
@@ -40,7 +43,8 @@ namespace BizHawk.Client.Common
LagLog.RemoveAt(frame);
return;
}
- else if (frame < 0)
+
+ if (frame < 0)
{
return; // Nothing to do
}
@@ -85,6 +89,7 @@ namespace BizHawk.Client.Common
LagLog.RemoveRange(frame + 1, LagLog.Count - frame - 1);
return true;
}
+
return false;
}
@@ -92,10 +97,15 @@ namespace BizHawk.Client.Common
{
WasLag.RemoveAt(frame);
}
+
public void InsertHistoryAt(int frame, bool isLag)
- { // LagLog was invalidated when the frame was inserted
+ {
+ // LagLog was invalidated when the frame was inserted
if (frame <= LagLog.Count)
+ {
LagLog.Insert(frame, isLag);
+ }
+
WasLag.Insert(frame, isLag);
}
@@ -109,8 +119,11 @@ namespace BizHawk.Client.Common
bw.Write(LagLog[i]);
bw.Write(WasLag[i]);
}
+
for (int i = LagLog.Count; i < WasLag.Count; i++)
+ {
bw.Write(WasLag[i]);
+ }
}
public void Load(BinaryReader br)
diff --git a/BizHawk.Client.Common/movie/tasproj/TasMovie.History.cs b/BizHawk.Client.Common/movie/tasproj/TasMovie.History.cs
index 9a6a73badd..498ece9dd2 100644
--- a/BizHawk.Client.Common/movie/tasproj/TasMovie.History.cs
+++ b/BizHawk.Client.Common/movie/tasproj/TasMovie.History.cs
@@ -6,7 +6,7 @@ namespace BizHawk.Client.Common
{
public class TasMovieChangeLog
{
- List> History;
+ private readonly List> History;
public List Names;
public int UndoIndex = -1;
int _maxSteps = 100;
@@ -173,17 +173,19 @@ namespace BizHawk.Client.Common
return PreviousRedoFrame;
}
- public bool CanUndo { get { return UndoIndex > -1; } }
- public bool CanRedo { get { return UndoIndex < History.Count - 1; } }
+ public bool CanUndo => UndoIndex > -1;
+ public bool CanRedo => UndoIndex < History.Count - 1;
public string NextUndoStepName
{
get
{
if (Names.Count == 0 || UndoIndex < 0)
+ {
return null;
- else
- return Names[UndoIndex];
+ }
+
+ return Names[UndoIndex];
}
}
@@ -192,10 +194,14 @@ namespace BizHawk.Client.Common
get
{
if (UndoIndex == History.Count - 1)
+ {
return Movie.InputLogLength;
+ }
if (History[UndoIndex + 1].Count == 0)
+ {
return Movie.InputLogLength;
+ }
return History[UndoIndex + 1].Min(a => a.FirstFrame);
}
@@ -206,24 +212,32 @@ namespace BizHawk.Client.Common
get
{
if (UndoIndex == -1)
+ {
return Movie.InputLogLength;
+ }
if (History[UndoIndex].Count == 0)
+ {
return Movie.InputLogLength;
+ }
return History[UndoIndex].Min(a => a.FirstFrame);
}
}
- #region "Change History"
+ #region Change History
private bool AddMovieAction(string name)
{
if (UndoIndex + 1 != History.Count)
+ {
TruncateLog(UndoIndex + 1);
+ }
if (name == "")
+ {
name = "Undo step " + _totalSteps;
+ }
bool ret = false;
if (!RecordingBatch)
@@ -234,7 +248,9 @@ namespace BizHawk.Client.Common
_totalSteps += 1;
if (History.Count <= MaxSteps)
+ {
UndoIndex += 1;
+ }
else
{
History.RemoveAt(0);
@@ -312,10 +328,11 @@ namespace BizHawk.Client.Common
History.Last().Add(new MovieActionBindInput(Movie, frame, isDelete));
}
}
+
#endregion
}
- #region "Classes"
+ #region Classes
public interface IMovieAction
{
@@ -328,12 +345,14 @@ namespace BizHawk.Client.Common
public class MovieAction : IMovieAction
{
- public int FirstFrame { get; private set; }
- public int LastFrame { get; private set; }
+ public int FirstFrame { get; }
+ public int LastFrame { get; }
+
private int undoLength;
private int redoLength;
- private int length
- { get { return LastFrame - FirstFrame + 1; } }
+
+ private int length => LastFrame - FirstFrame + 1;
+
private List oldLog;
private List newLog;
private bool bindMarkers;
@@ -346,7 +365,9 @@ namespace BizHawk.Client.Common
undoLength = Math.Min(LastFrame + 1, movie.InputLogLength) - FirstFrame;
for (int i = 0; i < undoLength; i++)
+ {
oldLog.Add(movie.GetLogEntries()[FirstFrame + i]);
+ }
bindMarkers = movie.BindMarkersToInput;
}
@@ -356,7 +377,9 @@ namespace BizHawk.Client.Common
redoLength = Math.Min(LastFrame + 1, movie.InputLogLength) - FirstFrame;
newLog = new List();
for (int i = 0; i < redoLength; i++)
+ {
newLog.Add(movie.GetLogEntries()[FirstFrame + i]);
+ }
}
public void Undo(TasMovie movie)
@@ -400,8 +423,8 @@ namespace BizHawk.Client.Common
public class MovieActionMarker : IMovieAction
{
- public int FirstFrame { get; private set; }
- public int LastFrame { get; private set; }
+ public int FirstFrame { get; }
+ public int LastFrame { get; }
private string oldMessage;
private string newMessage;
diff --git a/BizHawk.Client.Common/movie/tasproj/TasMovie.cs b/BizHawk.Client.Common/movie/tasproj/TasMovie.cs
index dd2fc88cda..205f2c7e7a 100644
--- a/BizHawk.Client.Common/movie/tasproj/TasMovie.cs
+++ b/BizHawk.Client.Common/movie/tasproj/TasMovie.cs
@@ -30,26 +30,22 @@ namespace BizHawk.Client.Common
public bool BindMarkersToInput { get; set; }
public bool UseInputCache { get; set; }
public int CurrentBranch { get; set; }
- public int BranchCount { get { return Branches.Count; } }
- public int LastValidFrame { get { return LagLog.LastValidFrame; } }
- public override string PreferredExtension { get { return Extension; } }
- public TasStateManager TasStateManager { get { return StateManager; } }
- public TasMovieRecord this[int index]
- {
- get
- {
- return new TasMovieRecord
- {
- // State = StateManager[index],
- HasState = StateManager.HasState(index),
- LogEntry = GetInputLogEntry(index),
- Lagged = LagLog[index + 1],
- WasLagged = LagLog.History(index + 1)
- };
- }
- }
- public TasMovie(string path, bool startsFromSavestate = false, BackgroundWorker progressReportWorker = null)
+ public int BranchCount => Branches.Count;
+ public int LastValidFrame => LagLog.LastValidFrame;
+ public override string PreferredExtension => Extension;
+ public TasStateManager TasStateManager => StateManager;
+
+ public TasMovieRecord this[int index] => new TasMovieRecord
+ {
+ // State = StateManager[index],
+ HasState = StateManager.HasState(index),
+ LogEntry = GetInputLogEntry(index),
+ Lagged = LagLog[index + 1],
+ WasLagged = LagLog.History(index + 1)
+ };
+
+ 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() ?
@@ -71,7 +67,6 @@ namespace BizHawk.Client.Common
}
public TasMovie(bool startsFromSavestate = false, BackgroundWorker progressReportWorker = null)
- : base()
{
_progressReportWorker = progressReportWorker;
if (!Global.Emulator.HasSavestates())
@@ -98,11 +93,11 @@ namespace BizHawk.Client.Common
public void ReportProgress(double percent)
{
if (percent > 100d)
- return;
- if (_progressReportWorker != null)
{
- _progressReportWorker.ReportProgress((int)percent);
+ return;
}
+
+ _progressReportWorker?.ReportProgress((int)percent);
}
// TODO: use LogGenerators rather than string comparisons
@@ -156,7 +151,7 @@ namespace BizHawk.Client.Common
if (anyInvalidated && Global.MovieSession.Movie.IsCountingRerecords)
{
- base.Rerecords++;
+ Rerecords++;
}
}
@@ -190,9 +185,9 @@ namespace BizHawk.Client.Common
{
if (adapter.Definition.BoolButtons.Contains(buttonName))
{
- return adapter.IsPressed(buttonName) ?
- Mnemonics[buttonName].ToString() :
- "";
+ return adapter.IsPressed(buttonName)
+ ? Mnemonics[buttonName].ToString()
+ : "";
}
if (adapter.Definition.FloatControls.Contains(buttonName))
@@ -284,6 +279,7 @@ namespace BizHawk.Client.Common
int? stateFrame = null;
var newLog = new List();
+
// We are in record mode so replace the movie log with the one from the savestate
if (!Global.MovieSession.MultiTrack.IsActive)
{
@@ -303,7 +299,8 @@ namespace BizHawk.Client.Common
{
break;
}
- else if (line.Contains("Frame 0x")) // NES stores frame count in hex, yay
+
+ if (line.Contains("Frame 0x")) // NES stores frame count in hex, yay
{
var strs = line.Split('x');
try
@@ -340,6 +337,7 @@ namespace BizHawk.Client.Common
{
TimelineBranchFrame = counter;
}
+
counter++;
}
}
@@ -440,42 +438,51 @@ namespace BizHawk.Client.Common
public TasBranch GetBranch(int index)
{
if (index >= Branches.Count || index < 0)
+ {
return null;
- else
- return Branches[index];
+ }
+
+ return Branches[index];
}
public TasBranch GetBranch(Guid id)
{
- TasBranch branch = Branches.SingleOrDefault(b => b.UniqueIdentifier == id);
- if (branch != null)
- return branch;
- else
- return null;
+ return Branches.SingleOrDefault(b => b.UniqueIdentifier == id);
}
public int BranchHashByIndex(int index)
{
if (index >= Branches.Count)
+ {
return -1;
- else
- return Branches[index].UniqueIdentifier.GetHashCode();
+ }
+
+ return Branches[index].UniqueIdentifier.GetHashCode();
}
public int BranchIndexByHash(int hash)
{
TasBranch branch = Branches.SingleOrDefault(b => b.UniqueIdentifier.GetHashCode() == hash);
if (branch == null)
+ {
return -1;
+ }
+
return Branches.IndexOf(branch);
}
public int BranchIndexByFrame(int frame)
{
- TasBranch branch = Branches.Where(b => b.Frame == frame)
- .OrderByDescending(b => b.TimeStamp).FirstOrDefault();
+ TasBranch branch = Branches
+ .Where(b => b.Frame == frame)
+ .OrderByDescending(b => b.TimeStamp)
+ .FirstOrDefault();
+
if (branch == null)
+ {
return -1;
+ }
+
return Branches.IndexOf(branch);
}
@@ -497,7 +504,7 @@ namespace BizHawk.Client.Common
{
int? divergentPoint = DivergentPoint(_log, branch.InputLog);
- if (_log != null) _log.Dispose();
+ _log?.Dispose();
_log = branch.InputLog.Clone();
////_changes = true;
@@ -509,14 +516,18 @@ namespace BizHawk.Client.Common
LagLog.FromLagLog(branch.LagLog); // don't truncate LagLog if the branch's one is shorter, but input is the same
}
else
+ {
StateManager.Invalidate(branch.InputLog.Count);
+ }
StateManager.LoadBranch(Branches.IndexOf(branch));
StateManager.SetState(branch.Frame, branch.CoreData);
////ChangeLog = branch.ChangeLog;
if (BindMarkersToInput) // pretty critical not to erase them
+ {
Markers = branch.Markers;
+ }
Changes = true;
}
@@ -526,7 +537,10 @@ namespace BizHawk.Client.Common
int index = Branches.IndexOf(old);
newBranch.UniqueIdentifier = old.UniqueIdentifier;
if (newBranch.UserText == "")
+ {
newBranch.UserText = old.UserText;
+ }
+
Branches[index] = newBranch;
TasStateManager.UpdateBranch(index);
Changes = true;
@@ -537,7 +551,9 @@ namespace BizHawk.Client.Common
TasBranch branch = Branches[b1];
if (b2 >= Branches.Count)
+ {
b2 = Branches.Count - 1;
+ }
Branches.Remove(branch);
Branches.Insert(b2, branch);
@@ -553,7 +569,11 @@ namespace BizHawk.Client.Common
private bool _changes;
public override bool Changes
{
- get { return _changes; }
+ get
+ {
+ return _changes;
+ }
+
protected set
{
if (_changes != value)
@@ -567,14 +587,11 @@ namespace BizHawk.Client.Common
// This event is Raised only when Changes is TOGGLED.
private void OnPropertyChanged(string propertyName)
{
- if (PropertyChanged != null)
- {
- // Raising the event when FirstName or LastName property value changed
- PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
+ // Raising the event when FirstName or LastName property value changed
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
- void Markers_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
+ private void Markers_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
Changes = true;
}
diff --git a/BizHawk.Client.Common/movie/tasproj/TasMovieMarker.cs b/BizHawk.Client.Common/movie/tasproj/TasMovieMarker.cs
index 7e089d298f..044ddeea54 100644
--- a/BizHawk.Client.Common/movie/tasproj/TasMovieMarker.cs
+++ b/BizHawk.Client.Common/movie/tasproj/TasMovieMarker.cs
@@ -28,7 +28,7 @@ namespace BizHawk.Client.Common
Message = split[1];
}
- public virtual int Frame { get; private set; }
+ public virtual int Frame { get; }
public virtual string Message { get; set; }
@@ -48,23 +48,24 @@ namespace BizHawk.Client.Common
{
return false;
}
- else if (obj is TasMovieMarker)
+
+ if (obj is TasMovieMarker)
{
return Frame == (obj as TasMovieMarker).Frame;
}
- else
- {
- return false;
- }
+
+ return false;
}
public static bool operator ==(TasMovieMarker marker, int frame)
{
+ // TODO: account for null marker
return marker.Frame == frame;
}
public static bool operator !=(TasMovieMarker marker, int frame)
{
+ // TODO: account for null marker
return marker.Frame != frame;
}
}
@@ -80,9 +81,11 @@ namespace BizHawk.Client.Common
public TasMovieMarkerList DeepClone()
{
- TasMovieMarkerList ret = new TasMovieMarkerList(_movie);
+ var ret = new TasMovieMarkerList(_movie);
for (int i = 0; i < Count; i++)
+ {
ret.Add(new TasMovieMarker(this[i].Frame, this[i].Message));
+ }
return ret;
}
@@ -91,11 +94,8 @@ namespace BizHawk.Client.Common
private void OnListChanged(NotifyCollectionChangedAction action)
{
- if (CollectionChanged != null)
- {
- // TODO Allow different types
- CollectionChanged.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
- }
+ // TODO Allow different types
+ CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
public override string ToString()
@@ -123,7 +123,10 @@ namespace BizHawk.Client.Common
if (existingItem.Message != item.Message)
{
if (!fromHistory)
+ {
_movie.ChangeLog.AddMarkerChange(item, item.Frame, existingItem.Message);
+ }
+
existingItem.Message = item.Message;
OnListChanged(NotifyCollectionChangedAction.Replace);
}
@@ -131,7 +134,10 @@ namespace BizHawk.Client.Common
else
{
if (!fromHistory)
+ {
_movie.ChangeLog.AddMarkerChange(item);
+ }
+
base.Add(item);
Sort((m1, m2) => m1.Frame.CompareTo(m2.Frame));
OnListChanged(NotifyCollectionChangedAction.Add);
@@ -150,8 +156,11 @@ namespace BizHawk.Client.Common
{
Add(m);
}
+
if (endBatch)
+ {
_movie.ChangeLog.EndBatch();
+ }
}
// the inherited one
@@ -163,7 +172,10 @@ namespace BizHawk.Client.Common
public void Insert(int index, TasMovieMarker item, bool fromHistory)
{
if (!fromHistory)
+ {
_movie.ChangeLog.AddMarkerChange(item);
+ }
+
base.Insert(index, item);
Sort((m1, m2) => m1.Frame.CompareTo(m2.Frame));
OnListChanged(NotifyCollectionChangedAction.Add);
@@ -173,9 +185,14 @@ namespace BizHawk.Client.Common
{
bool endBatch = _movie.ChangeLog.BeginNewBatch("Add Markers", true);
foreach (TasMovieMarker m in collection)
+ {
_movie.ChangeLog.AddMarkerChange(m);
+ }
+
if (endBatch)
+ {
_movie.ChangeLog.EndBatch();
+ }
base.InsertRange(index, collection);
Sort((m1, m2) => m1.Frame.CompareTo(m2.Frame));
@@ -191,9 +208,15 @@ namespace BizHawk.Client.Common
public void Remove(TasMovieMarker item, bool fromHistory)
{
if (item == null || item.Frame == 0) // TODO: Don't do this.
+ {
return;
+ }
+
if (!fromHistory)
+ {
_movie.ChangeLog.AddMarkerChange(null, item.Frame, item.Message);
+ }
+
base.Remove(item);
OnListChanged(NotifyCollectionChangedAction.Remove);
}
@@ -204,10 +227,15 @@ namespace BizHawk.Client.Common
foreach (TasMovieMarker m in this)
{
if (match.Invoke(m))
+ {
_movie.ChangeLog.AddMarkerChange(null, m.Frame, m.Message);
+ }
}
+
if (endBatch)
+ {
_movie.ChangeLog.EndBatch();
+ }
int removeCount = base.RemoveAll(match);
if (removeCount > 0)
@@ -220,10 +248,16 @@ namespace BizHawk.Client.Common
public void Move(int fromFrame, int toFrame, bool fromHistory = false)
{
if (fromFrame == 0) // no thanks!
+ {
return;
+ }
+
TasMovieMarker m = Get(fromFrame);
if (m == null) // TODO: Don't do this.
+ {
return;
+ }
+
_movie.ChangeLog.AddMarkerChange(m, m.Frame);
Insert(0, new TasMovieMarker(toFrame, m.Message), fromHistory);
Remove(m, fromHistory);
@@ -243,18 +277,26 @@ namespace BizHawk.Client.Common
if (this[i].Frame >= startFrame)
{
if (i == 0)
+ {
continue;
+ }
+
_movie.ChangeLog.AddMarkerChange(null, this[i].Frame, this[i].Message);
RemoveAt(i);
deletedCount++;
}
}
+
if (endBatch)
+ {
_movie.ChangeLog.EndBatch();
+ }
+
if (deletedCount > 0)
{
OnListChanged(NotifyCollectionChangedAction.Remove);
}
+
return deletedCount;
}
diff --git a/BizHawk.Client.Common/movie/tasproj/TasSession.cs b/BizHawk.Client.Common/movie/tasproj/TasSession.cs
index 89ae7957e7..4e1bc173ae 100644
--- a/BizHawk.Client.Common/movie/tasproj/TasSession.cs
+++ b/BizHawk.Client.Common/movie/tasproj/TasSession.cs
@@ -5,9 +5,9 @@ namespace BizHawk.Client.Common
{
public class TasSession
{
- private TasMovie _movie;
- public int CurrentFrame { get; set; }
- public int CurrentBranch { get; set; }
+ private readonly TasMovie _movie;
+ public int CurrentFrame { get; private set; }
+ public int CurrentBranch { get; private set; }
public TasSession(TasMovie movie)
{
@@ -23,10 +23,10 @@ namespace BizHawk.Client.Common
}
public override string ToString()
- {
- StringBuilder sb = new StringBuilder();
-
- UpdateValues();
+ {
+ UpdateValues();
+
+ var sb = new StringBuilder();
sb.AppendLine(CurrentFrame.ToString());
sb.AppendLine(CurrentBranch.ToString());
@@ -37,17 +37,18 @@ namespace BizHawk.Client.Common
{
if (!string.IsNullOrWhiteSpace(session))
{
- string[] lines = session.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
+ string[] lines = session.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
- if (lines.Length > 0)
- CurrentFrame = int.Parse(lines[0]);
- else
- CurrentFrame = 0;
+ CurrentFrame = lines.Length > 0 ? int.Parse(lines[0]) : 0;
if (lines.Length > 1)
+ {
CurrentBranch = int.Parse(lines[1]);
+ }
else
+ {
CurrentBranch = -1;
+ }
}
}
}
diff --git a/BizHawk.Client.Common/movie/tasproj/TasStateManager.cs b/BizHawk.Client.Common/movie/tasproj/TasStateManager.cs
index 2aa9268846..1ac6d0dec0 100644
--- a/BizHawk.Client.Common/movie/tasproj/TasStateManager.cs
+++ b/BizHawk.Client.Common/movie/tasproj/TasStateManager.cs
@@ -17,25 +17,16 @@ namespace BizHawk.Client.Common
public class TasStateManager : IDisposable
{
// TODO: pass this in, and find a solution to a stale reference (this is instantiated BEFORE a new core instance is made, making this one stale if it is simply set in the constructor
- private IStatable Core
- {
- get
- {
- return Global.Emulator.AsStatable();
- }
- }
+ private IStatable Core => Global.Emulator.AsStatable();
public Action InvalidateCallback { get; set; }
private void CallInvalidateCallback(int index)
{
- if (InvalidateCallback != null)
- {
- InvalidateCallback(index);
- }
+ InvalidateCallback?.Invoke(index);
}
- private List lowPriorityStates = new List();
+ private readonly List lowPriorityStates = new List();
internal NDBDatabase ndbdatabase;
private Guid guid = Guid.NewGuid();
private SortedList States = new SortedList();
@@ -53,7 +44,7 @@ namespace BizHawk.Client.Common
private readonly TasMovie _movie;
private ulong _expectedStateSize = 0;
- private int _minFrequency = VersionInfo.DeveloperBuild ? 2 : 1;
+ private readonly int _minFrequency = VersionInfo.DeveloperBuild ? 2 : 1;
private const int _maxFrequency = 16;
private int StateFrequency
@@ -101,8 +92,7 @@ namespace BizHawk.Client.Common
public void Dispose()
{
// States and BranchStates don't need cleaning because they would only contain an ndbdatabase entry which was demolished by the below
- if (ndbdatabase != null)
- ndbdatabase.Dispose();
+ ndbdatabase?.Dispose();
}
///
@@ -111,7 +101,9 @@ namespace BizHawk.Client.Common
public void MountWriteAccess()
{
if (_isMountedForWrite)
+ {
return;
+ }
_isMountedForWrite = true;
@@ -127,7 +119,10 @@ namespace BizHawk.Client.Common
States = new SortedList(limit);
if (_expectedStateSize > int.MaxValue)
+ {
throw new InvalidOperationException();
+ }
+
ndbdatabase = new NDBDatabase(statePath, Settings.DiskCapacitymb * 1024 * 1024, (int)_expectedStateSize);
}
@@ -157,7 +152,7 @@ namespace BizHawk.Client.Common
}
}
- private List accessed;
+ private readonly List accessed;
public byte[] InitialState
{
@@ -244,18 +239,26 @@ namespace BizHawk.Client.Common
int i = 0;
int markerSkips = maxStates / 2;
+
// lowPrioritySates (e.g. states with only lag frames between them)
do
{
if (lowPriorityStates.Count > i)
+ {
shouldRemove = findState(lowPriorityStates[i]);
+ }
else
+ {
break;
+ }
// Keep marker states
markerSkips--;
if (markerSkips < 0)
+ {
shouldRemove.X = -1;
+ }
+
i++;
} while (StateIsMarker(shouldRemove.X, shouldRemove.Y) && markerSkips > -1 || shouldRemove.X == 0);
@@ -267,14 +270,21 @@ namespace BizHawk.Client.Common
do
{
if (accessed.Count > i)
+ {
shouldRemove = findState(accessed[i]);
+ }
else
+ {
break;
+ }
// Keep marker states
markerSkips--;
if (markerSkips < 0)
+ {
shouldRemove.X = -1;
+ }
+
i++;
} while (StateIsMarker(shouldRemove.X, shouldRemove.Y) && markerSkips > -1 || shouldRemove.X == 0);
}
@@ -283,7 +293,7 @@ namespace BizHawk.Client.Common
{
if (BranchStates.Any() && !Settings.EraseBranchStatesFirst)
{
- var kvp = BranchStates.Count() > 1 ? BranchStates.ElementAt(1) : BranchStates.ElementAt(0);
+ var kvp = BranchStates.Count > 1 ? BranchStates.ElementAt(1) : BranchStates.ElementAt(0);
shouldRemove.X = kvp.Key;
shouldRemove.Y = kvp.Value.Keys[0];
}
@@ -301,17 +311,21 @@ namespace BizHawk.Client.Common
private bool StateIsMarker(int frame, int branch)
{
if (frame == -1)
+ {
return false;
+ }
if (branch == -1)
- return _movie.Markers.IsMarker(States[frame].Frame + 1);
- else
{
- if (_movie.GetBranch(_movie.BranchIndexByHash(branch)).Markers == null)
- return _movie.Markers.IsMarker(States[frame].Frame + 1);
- else
- return _movie.GetBranch(branch).Markers.Any(m => m.Frame + 1 == frame);
+ return _movie.Markers.IsMarker(States[frame].Frame + 1);
}
+
+ if (_movie.GetBranch(_movie.BranchIndexByHash(branch)).Markers == null)
+ {
+ return _movie.Markers.IsMarker(States[frame].Frame + 1);
+ }
+
+ return _movie.GetBranch(branch).Markers.Any(m => m.Frame + 1 == frame);
}
private bool AllLag(int from, int upTo)
@@ -320,13 +334,17 @@ namespace BizHawk.Client.Common
{
upTo = Global.Emulator.Frame - 1;
if (!Global.Emulator.AsInputPollable().IsLagFrame)
+ {
return false;
+ }
}
for (int i = from; i < upTo; i++)
{
if (_movie[i].Lagged == false)
+ {
return false;
+ }
}
return true;
@@ -347,12 +365,17 @@ namespace BizHawk.Client.Common
internal void SetState(int frame, byte[] state, bool skipRemoval = true)
{
if (!skipRemoval) // skipRemoval: false only when capturing new states
+ {
MaybeRemoveStates(); // Remove before adding so this state won't be removed.
+ }
if (States.ContainsKey(frame))
{
if (stateHasDuplicate(frame, -1) != -2)
+ {
Used += (ulong)state.Length;
+ }
+
States[frame].State = state;
}
else
@@ -373,9 +396,13 @@ namespace BizHawk.Client.Common
private void RemoveState(int frame, int branch = -1)
{
if (branch == -1)
+ {
accessed.Remove(States[frame]);
+ }
else if (accessed.Contains(BranchStates[frame][branch]) && !Settings.EraseBranchStatesFirst)
+ {
accessed.Remove(BranchStates[frame][branch]);
+ }
StateManagerState state;
bool hasDuplicate = stateHasDuplicate(frame, branch) != -2;
@@ -383,14 +410,20 @@ namespace BizHawk.Client.Common
{
state = States[frame];
if (States[frame].IsOnDisk)
+ {
States[frame].Dispose();
+ }
else
+ {
Used -= (ulong)States[frame].Length;
+ }
+
States.RemoveAt(States.IndexOfKey(frame));
}
else
{
state = BranchStates[frame][branch];
+
if (BranchStates[frame][branch].IsOnDisk)
BranchStates[frame][branch].Dispose();
else
@@ -398,17 +431,23 @@ namespace BizHawk.Client.Common
BranchStates[frame].RemoveAt(BranchStates[frame].IndexOfKey(branch));
if (BranchStates[frame].Count == 0)
+ {
BranchStates.Remove(frame);
+ }
}
if (!hasDuplicate)
+ {
lowPriorityStates.Remove(state);
+ }
}
private void StateAccessed(int frame)
{
if (frame == 0 && _movie.StartsFromSavestate)
+ {
return;
+ }
StateManagerState state = States[frame];
bool removed = accessed.Remove(state);
@@ -417,12 +456,17 @@ namespace BizHawk.Client.Common
if (States[frame].IsOnDisk)
{
if (!States[accessed[0].Frame].IsOnDisk)
+ {
MoveStateToDisk(accessed[0].Frame);
+ }
+
MoveStateToMemory(frame);
}
if (!removed && accessed.Count > maxStates)
+ {
accessed.RemoveAt(0);
+ }
}
public bool HasState(int frame)
@@ -454,8 +498,10 @@ namespace BizHawk.Client.Common
anyInvalidated = statesToRemove.Any();
- foreach (KeyValuePair state in statesToRemove)
+ foreach (var state in statesToRemove)
+ {
RemoveState(state.Key);
+ }
CallInvalidateCallback(frame);
}
@@ -466,13 +512,12 @@ namespace BizHawk.Client.Common
///
/// Clears all state information
///
- ///
public void Clear()
{
States.Clear();
accessed.Clear();
Used = 0;
- clearDiskStates();
+ ClearDiskStates();
}
public void ClearStateHistory()
@@ -488,14 +533,13 @@ namespace BizHawk.Client.Common
SetState(0, power.State);
Used = (ulong)power.State.Length;
- clearDiskStates();
+ ClearDiskStates();
}
}
- private void clearDiskStates()
+ private void ClearDiskStates()
{
- if (ndbdatabase != null)
- ndbdatabase.Clear();
+ ndbdatabase?.Clear();
}
///
@@ -518,7 +562,9 @@ namespace BizHawk.Client.Common
}
if (Used > Settings.Cap)
+ {
MaybeRemoveStates();
+ }
}
private List ExcludeStates()
@@ -656,11 +702,12 @@ namespace BizHawk.Client.Common
list.Add(key2, state);
c2--;
}
+
BranchStates.Add(key, list);
c--;
}
}
- catch (EndOfStreamException) { }
+ catch (EndOfStreamException) { } // Bad!
}
@@ -684,12 +731,18 @@ namespace BizHawk.Client.Common
{
return _used;
}
+
set
{
+ // TODO: Shouldn't we throw an exception? Debug.Fail only runs in debug mode?
if (value > 0xf000000000000000)
+ {
System.Diagnostics.Debug.Fail("ulong Used underfow!");
+ }
else
+ {
_used = value;
+ }
}
}
@@ -697,18 +750,16 @@ namespace BizHawk.Client.Common
{
get
{
- if (ndbdatabase == null) return 0;
- else return (ulong)ndbdatabase.Consumed;
+ if (ndbdatabase == null)
+ {
+ return 0;
+ }
+
+ return (ulong)ndbdatabase.Consumed;
}
}
- public int StateCount
- {
- get
- {
- return States.Count;
- }
- }
+ public int StateCount => States.Count;
public bool Any()
{
@@ -746,7 +797,7 @@ namespace BizHawk.Client.Common
}
}
- #region "Branches"
+ #region Branches
private SortedList> BranchStates = new SortedList>();
@@ -764,16 +815,24 @@ namespace BizHawk.Client.Common
else
{
if (!BranchStates[frame].ContainsKey(branchHash))
+ {
return -2;
+ }
+
stateToMatch = BranchStates[frame][branchHash];
+
// Check the current branch for duplicate.
if (States.ContainsKey(frame) && States[frame] == stateToMatch)
+ {
return -1;
+ }
}
// Check if there are any branch states for the given frame.
if (!BranchStates.ContainsKey(frame) || BranchStates[frame] == null || branchHash == -1)
+ {
return -2;
+ }
// Loop through branch states for the given frame.
SortedList stateList = BranchStates[frame];
@@ -781,10 +840,14 @@ namespace BizHawk.Client.Common
{
// Don't check the branch containing the state to match.
if (i == _movie.BranchIndexByHash(branchHash))
+ {
continue;
+ }
if (stateList.Values[i] == stateToMatch)
+ {
return i;
+ }
}
return -2; // No match.
@@ -801,8 +864,11 @@ namespace BizHawk.Client.Common
int index = BranchStates[s.Frame].Values.IndexOf(s);
ret.Y = BranchStates[s.Frame].Keys.ElementAt(index);
}
+
if (ret.Y == -1)
+ {
return new Point(-1, -2);
+ }
}
return ret;
@@ -815,7 +881,9 @@ namespace BizHawk.Client.Common
foreach (KeyValuePair kvp in States)
{
if (!BranchStates.ContainsKey(kvp.Key))
+ {
BranchStates.Add(kvp.Key, new SortedList());
+ }
SortedList stateList = BranchStates[kvp.Key];
@@ -824,6 +892,7 @@ namespace BizHawk.Client.Common
stateList = new SortedList();
BranchStates[kvp.Key] = stateList;
}
+
stateList.Add(branchHash, kvp.Value);
// We aren't creating any new states, just adding a reference to an already-existing one; so Used doesn't need to be updated.
}
@@ -837,7 +906,10 @@ namespace BizHawk.Client.Common
{
SortedList stateList = kvp.Value;
if (stateList == null)
+ {
continue;
+ }
+
/*
if (stateList.ContainsKey(branchHash))
{
@@ -850,14 +922,18 @@ namespace BizHawk.Client.Common
*/
stateList.Remove(branchHash);
if (stateList.Count == 0)
+ {
BranchStates.Remove(kvp.Key);
+ }
}
}
public void UpdateBranch(int index)
{
if (index == -1) // backup branch is outsider
+ {
return;
+ }
int branchHash = _movie.BranchHashByIndex(index);
@@ -866,7 +942,10 @@ namespace BizHawk.Client.Common
{
SortedList stateList = kvp.Value;
if (stateList == null)
+ {
continue;
+ }
+
/*
if (stateList.ContainsKey(branchHash))
{
@@ -879,14 +958,18 @@ namespace BizHawk.Client.Common
*/
stateList.Remove(branchHash);
if (stateList.Count == 0)
+ {
BranchStates.Remove(kvp.Key);
+ }
}
// AddBranch
foreach (KeyValuePair kvp in States)
{
if (!BranchStates.ContainsKey(kvp.Key))
+ {
BranchStates.Add(kvp.Key, new SortedList());
+ }
SortedList stateList = BranchStates[kvp.Key];
@@ -895,6 +978,7 @@ namespace BizHawk.Client.Common
stateList = new SortedList();
BranchStates[kvp.Key] = stateList;
}
+
stateList.Add(branchHash, kvp.Value);
}
}
@@ -902,7 +986,9 @@ namespace BizHawk.Client.Common
public void LoadBranch(int index)
{
if (index == -1) // backup branch is outsider
+ {
return;
+ }
int branchHash = _movie.BranchHashByIndex(index);
@@ -911,10 +997,14 @@ namespace BizHawk.Client.Common
foreach (KeyValuePair> kvp in BranchStates)
{
if (kvp.Key == 0 && States.ContainsKey(0))
+ {
continue; // TODO: It might be a better idea to just not put state 0 in BranchStates.
+ }
if (kvp.Value.ContainsKey(branchHash))
+ {
SetState(kvp.Key, kvp.Value[branchHash].State);
+ }
}
}
diff --git a/BizHawk.Client.Common/movie/tasproj/TasStateManagerSettings.cs b/BizHawk.Client.Common/movie/tasproj/TasStateManagerSettings.cs
index 8e2be48434..d0f39ed204 100644
--- a/BizHawk.Client.Common/movie/tasproj/TasStateManagerSettings.cs
+++ b/BizHawk.Client.Common/movie/tasproj/TasStateManagerSettings.cs
@@ -81,24 +81,18 @@ namespace BizHawk.Client.Common
///
[JsonIgnore]
[Browsable(false)]
- public ulong CapTotal
- {
- get { return (ulong)(Capacitymb + DiskCapacitymb) * 1024UL * 1024UL; }
- }
+ public ulong CapTotal => (ulong)(Capacitymb + DiskCapacitymb) * 1024UL * 1024UL;
///
/// The memory state capacity in bytes.
///
[JsonIgnore]
[Browsable(false)]
- public ulong Cap
- {
- get { return (ulong)Capacitymb * 1024UL * 1024UL; }
- }
+ public ulong Cap => (ulong)Capacitymb * 1024UL * 1024UL;
public override string ToString()
{
- StringBuilder sb = new StringBuilder();
+ var sb = new StringBuilder();
sb.AppendLine(DiskSaveCapacitymb.ToString());
sb.AppendLine(Capacitymb.ToString());
@@ -116,7 +110,7 @@ namespace BizHawk.Client.Common
{
try
{
- string[] lines = settings.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
+ string[] lines = settings.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
Capacitymb = int.Parse(lines[1]);
int refCapacity;
@@ -150,7 +144,7 @@ namespace BizHawk.Client.Common
else
StateGap = 4;
}
- catch (Exception)
+ catch (Exception) // TODO: this is bad
{
// "GreenZoneSettings inconsistent, ignoring"
// if we don't catch it, the project won't load