refactor Bk2LogEntryGenerator to be stateless, refactor some IMovieSession shenangians

This commit is contained in:
adelikat 2020-04-14 20:50:21 -05:00
parent cdfeda8b71
commit 0d2f014621
16 changed files with 63 additions and 98 deletions

View File

@ -28,7 +28,7 @@ namespace BizHawk.Client.Common
public void SetFromMnemonicStr(string inputLogEntry) public void SetFromMnemonicStr(string inputLogEntry)
{ {
var lg = Global.MovieSession.MovieControllerInstance(); var lg = Global.MovieSession.GenerateMovieController(Global.Emulator.ControllerDefinition);
try try
{ {
lg.SetFromMnemonic(inputLogEntry); lg.SetFromMnemonic(inputLogEntry);

View File

@ -27,7 +27,7 @@ namespace BizHawk.Client.Common
public bool MovieIsQueued => QueuedMovie != null; public bool MovieIsQueued => QueuedMovie != null;
public MultitrackRecorder MultiTrack { get; } = new MultitrackRecorder(); public MultitrackRecorder MultiTrack { get; } = new MultitrackRecorder();
public IMovieController MovieController { get; set; } = MovieService.DefaultInstance.LogGeneratorInstance().MovieControllerAdapter; public IMovieController MovieController { get; set; } = new Bk2Controller("", NullController.Instance.Definition);
public IMovie Movie { get; set; } public IMovie Movie { get; set; }
public bool ReadOnly { get; set; } = true; public bool ReadOnly { get; set; } = true;
@ -52,19 +52,18 @@ namespace BizHawk.Client.Common
MovieController = new Bk2Controller(definition); MovieController = new Bk2Controller(definition);
} }
public IMovieController GenerateMovieController(ControllerDefinition definition)
{
// TODO: expose Movie.LogKey and pass in here
return new Bk2Controller("", definition);
}
/// <summary> /// <summary>
/// Simply shortens the verbosity necessary otherwise /// Simply shortens the verbosity necessary otherwise
/// </summary> /// </summary>
public ILogEntryGenerator LogGeneratorInstance(IController source) public ILogEntryGenerator LogGeneratorInstance(IController source)
{ {
var lg = Movie.LogGeneratorInstance(); return Movie.LogGeneratorInstance(source);
lg.SetSource(source);
return lg;
}
public IMovieController MovieControllerInstance()
{
return Movie.LogGeneratorInstance().MovieControllerAdapter;
} }
// Convenience property that gets the controller state from the movie for the most recent frame // Convenience property that gets the controller state from the movie for the most recent frame
@ -277,8 +276,7 @@ namespace BizHawk.Client.Common
else if (Global.Config.MoviePlaybackPokeMode) else if (Global.Config.MoviePlaybackPokeMode)
{ {
LatchInputFromPlayer(Global.InputManager.MovieInputSourceAdapter); LatchInputFromPlayer(Global.InputManager.MovieInputSourceAdapter);
var lg = Movie.LogGeneratorInstance(); var lg = Movie.LogGeneratorInstance(Global.InputManager.MovieOutputHardpoint);
lg.SetSource(Global.InputManager.MovieOutputHardpoint);
if (!lg.IsEmpty) if (!lg.IsEmpty)
{ {
LatchInputFromPlayer(Global.InputManager.MovieInputSourceAdapter); LatchInputFromPlayer(Global.InputManager.MovieInputSourceAdapter);

View File

@ -6,20 +6,17 @@ using BizHawk.Emulation.Common;
namespace BizHawk.Client.Common namespace BizHawk.Client.Common
{ {
public class Bk2LogEntryGenerator : ILogEntryGenerator internal class Bk2LogEntryGenerator : ILogEntryGenerator
{ {
private readonly string _logKey; private readonly string _systemId;
private IController _source = NullController.Instance; private readonly IController _source;
public Bk2LogEntryGenerator(string logKey) public Bk2LogEntryGenerator(string systemId, IController source)
{ {
_logKey = logKey; _systemId = systemId;
_source = source;
} }
public IMovieController MovieControllerAdapter => new Bk2Controller(_logKey, _source.Definition);
public void SetSource(IController source) => _source = source;
public string GenerateInputDisplay() => CreateLogEntry(forInputDisplay: true); public string GenerateInputDisplay() => CreateLogEntry(forInputDisplay: true);
public bool IsEmpty => EmptyEntry == GenerateLogEntry(); public bool IsEmpty => EmptyEntry == GenerateLogEntry();
@ -38,9 +35,7 @@ namespace BizHawk.Client.Common
sb.Append("#"); sb.Append("#");
foreach (var button in group) foreach (var button in group)
{ {
sb sb.Append(button).Append('|');
.Append(button)
.Append('|');
} }
} }
@ -56,11 +51,11 @@ namespace BizHawk.Client.Common
{ {
if (_source.Definition.BoolButtons.Contains(button)) if (_source.Definition.BoolButtons.Contains(button))
{ {
dict.Add(button, Bk2MnemonicLookup.Lookup(button, Global.Emulator.SystemId).ToString()); dict.Add(button, Bk2MnemonicLookup.Lookup(button, _systemId).ToString());
} }
else if (_source.Definition.AxisControls.Contains(button)) else if (_source.Definition.AxisControls.Contains(button))
{ {
dict.Add(button, Bk2MnemonicLookup.LookupAxis(button, Global.Emulator.SystemId)); dict.Add(button, Bk2MnemonicLookup.LookupAxis(button, _systemId));
} }
} }
} }
@ -115,7 +110,9 @@ namespace BizHawk.Client.Common
} }
else else
{ {
sb.Append(_source.IsPressed(button) ? Bk2MnemonicLookup.Lookup(button, Global.Emulator.SystemId) : forInputDisplay ? ' ' : '.'); sb.Append(_source.IsPressed(button)
? Bk2MnemonicLookup.Lookup(button, _systemId)
: forInputDisplay ? ' ' : '.');
} }
} }
} }

View File

@ -288,9 +288,7 @@ namespace BizHawk.Client.Common
protected void WriteRawInputLog(TextWriter writer) protected void WriteRawInputLog(TextWriter writer)
{ {
var lg = new Bk2LogEntryGenerator(LogKey); var lg = new Bk2LogEntryGenerator(LogKey, Global.InputManager.MovieOutputHardpoint);
lg.SetSource(Global.InputManager.MovieOutputHardpoint);
writer.WriteLine(lg.GenerateLogKey()); writer.WriteLine(lg.GenerateLogKey());
foreach (var record in Log) foreach (var record in Log)

View File

@ -38,9 +38,10 @@ namespace BizHawk.Client.Common
public virtual bool Changes { get; protected set; } public virtual bool Changes { get; protected set; }
public bool IsCountingRerecords { get; set; } = true; public bool IsCountingRerecords { get; set; } = true;
public ILogEntryGenerator LogGeneratorInstance() public ILogEntryGenerator LogGeneratorInstance(IController source)
{ {
return new Bk2LogEntryGenerator(LogKey); // TODO: when Bk2 movies have an instance of the core, use that
return new Bk2LogEntryGenerator(Global.Emulator.SystemId, source);
} }
public double FrameCount public double FrameCount
@ -84,8 +85,7 @@ namespace BizHawk.Client.Common
public void AppendFrame(IController source) public void AppendFrame(IController source)
{ {
var lg = LogGeneratorInstance(); var lg = LogGeneratorInstance(source);
lg.SetSource(source);
Log.Add(lg.GenerateLogEntry()); Log.Add(lg.GenerateLogEntry());
Changes = true; Changes = true;
} }
@ -100,8 +100,7 @@ namespace BizHawk.Client.Common
} }
} }
var lg = LogGeneratorInstance(); var lg = LogGeneratorInstance(source);
lg.SetSource(source);
SetFrameAt(frame, lg.GenerateLogEntry()); SetFrameAt(frame, lg.GenerateLogEntry());
Changes = true; Changes = true;
@ -154,17 +153,14 @@ namespace BizHawk.Client.Common
public virtual void PokeFrame(int frame, IController source) public virtual void PokeFrame(int frame, IController source)
{ {
var lg = LogGeneratorInstance(); var lg = LogGeneratorInstance(source);
lg.SetSource(source);
Changes = true;
SetFrameAt(frame, lg.GenerateLogEntry()); SetFrameAt(frame, lg.GenerateLogEntry());
Changes = true;
} }
public virtual void ClearFrame(int frame) public virtual void ClearFrame(int frame)
{ {
var lg = LogGeneratorInstance(); var lg = LogGeneratorInstance(Global.MovieSession.MovieController);
lg.SetSource(Global.MovieSession.MovieControllerInstance());
SetFrameAt(frame, lg.EmptyEntry); SetFrameAt(frame, lg.EmptyEntry);
Changes = true; Changes = true;
} }

View File

@ -1,15 +1,12 @@
using System.Collections.Generic; using System.Collections.Generic;
using BizHawk.Emulation.Common;
namespace BizHawk.Client.Common namespace BizHawk.Client.Common
{ {
/// <summary>
/// Specifies a class that can take an input source and generate a movie input log entry
/// </summary>
public interface ILogEntryGenerator public interface ILogEntryGenerator
{ {
/// <summary>
/// Sets the controller source used to generate an input log entry
/// </summary>
void SetSource(IController source);
/// <summary> /// <summary>
/// Generates an input log entry for the current state of Source /// Generates an input log entry for the current state of Source
/// </summary> /// </summary>
@ -42,11 +39,5 @@ namespace BizHawk.Client.Common
/// Gets an input log entry that is considered empty. (booleans will be false, floats will be 0) /// Gets an input log entry that is considered empty. (booleans will be false, floats will be 0)
/// </summary> /// </summary>
string EmptyEntry { get; } string EmptyEntry { get; }
/// <summary>
/// Gets a movie controller adapter in the same state as the log entry
/// </summary>
/// <seealso cref="IMovieController"/>
IMovieController MovieControllerAdapter { get; }
} }
} }

View File

@ -114,9 +114,9 @@ namespace BizHawk.Client.Common
void SaveBackup(); void SaveBackup();
/// <summary> /// <summary>
/// Creates an instance of the Input log entry used to generate the input log /// Creates a log generator using the given input source
/// </summary> /// </summary>
ILogEntryGenerator LogGeneratorInstance(); ILogEntryGenerator LogGeneratorInstance(IController source);
#endregion #endregion

View File

@ -8,7 +8,6 @@ namespace BizHawk.Client.Common
IMovie Movie { get; set; } IMovie Movie { get; set; }
IMovie QueuedMovie { get; } IMovie QueuedMovie { get; }
IMovieController MovieController { get; } IMovieController MovieController { get; }
IMovieController MovieControllerInstance();
MultitrackRecorder MultiTrack { get; } MultitrackRecorder MultiTrack { get; }
IController PreviousFrame { get; } IController PreviousFrame { get; }
@ -16,6 +15,8 @@ namespace BizHawk.Client.Common
void CreateMovieController(ControllerDefinition definition); void CreateMovieController(ControllerDefinition definition);
IMovieController GenerateMovieController(ControllerDefinition definition);
bool ReadOnly { get; set; } bool ReadOnly { get; set; }
bool MovieIsQueued { get; } bool MovieIsQueued { get; }

View File

@ -290,13 +290,11 @@ namespace BizHawk.Client.Common
public void InsertInput(int frame, IEnumerable<IController> inputStates) public void InsertInput(int frame, IEnumerable<IController> inputStates)
{ {
// ChangeLog is done in the InsertInput call. // ChangeLog is done in the InsertInput call.
var lg = LogGeneratorInstance();
var inputLog = new List<string>(); var inputLog = new List<string>();
foreach (var input in inputStates) foreach (var input in inputStates)
{ {
lg.SetSource(input); var lg = LogGeneratorInstance(input);
inputLog.Add(lg.GenerateLogEntry()); inputLog.Add(lg.GenerateLogEntry());
} }
@ -307,7 +305,7 @@ namespace BizHawk.Client.Common
{ {
int firstChangedFrame = -1; int firstChangedFrame = -1;
ChangeLog.BeginNewBatch($"Copy Over Input: {frame}"); ChangeLog.BeginNewBatch($"Copy Over Input: {frame}");
var lg = LogGeneratorInstance();
var states = inputStates.ToList(); var states = inputStates.ToList();
if (Log.Count < states.Count + frame) if (Log.Count < states.Count + frame)
@ -324,7 +322,7 @@ namespace BizHawk.Client.Common
break; break;
} }
lg.SetSource(states[i]); var lg = LogGeneratorInstance(states[i]);
var entry = lg.GenerateLogEntry(); var entry = lg.GenerateLogEntry();
if (firstChangedFrame == -1 && Log[frame + i] != entry) if (firstChangedFrame == -1 && Log[frame + i] != entry)
{ {
@ -347,8 +345,7 @@ namespace BizHawk.Client.Common
bool endBatch = ChangeLog.BeginNewBatch($"Insert Empty Frame: {frame}", true); bool endBatch = ChangeLog.BeginNewBatch($"Insert Empty Frame: {frame}", true);
ChangeLog.AddGeneralUndo(frame, InputLogLength + count - 1); ChangeLog.AddGeneralUndo(frame, InputLogLength + count - 1);
var lg = LogGeneratorInstance(); var lg = LogGeneratorInstance(Global.MovieSession.MovieController);
lg.SetSource(Global.MovieSession.MovieControllerInstance());
if (frame > Log.Count()) if (frame > Log.Count())
{ {
@ -395,8 +392,8 @@ namespace BizHawk.Client.Common
Global.MovieSession.MovieController.SetFromSticky(Global.InputManager.AutofireStickyXorAdapter); Global.MovieSession.MovieController.SetFromSticky(Global.InputManager.AutofireStickyXorAdapter);
var lg = LogGeneratorInstance(); // account for autohold. needs autohold pattern to be already recorded in the current frame
lg.SetSource(Global.InputManager.MovieOutputHardpoint); // account for autohold. needs autohold pattern to be already recorded in the current frame var lg = LogGeneratorInstance(Global.InputManager.MovieOutputHardpoint);
for (int i = 0; i < numFrames; i++) for (int i = 0; i < numFrames; i++)
{ {
@ -422,8 +419,7 @@ namespace BizHawk.Client.Common
var adapter = GetInputState(frame); var adapter = GetInputState(frame);
adapter.SetBool(buttonName, !adapter.IsPressed(buttonName)); adapter.SetBool(buttonName, !adapter.IsPressed(buttonName));
var lg = LogGeneratorInstance(); var lg = LogGeneratorInstance(adapter);
lg.SetSource(adapter);
Log[frame] = lg.GenerateLogEntry(); Log[frame] = lg.GenerateLogEntry();
Changes = true; Changes = true;
InvalidateAfter(frame); InvalidateAfter(frame);
@ -442,8 +438,7 @@ namespace BizHawk.Client.Common
var old = adapter.IsPressed(buttonName); var old = adapter.IsPressed(buttonName);
adapter.SetBool(buttonName, val); adapter.SetBool(buttonName, val);
var lg = LogGeneratorInstance(); var lg = LogGeneratorInstance(adapter);
lg.SetSource(adapter);
Log[frame] = lg.GenerateLogEntry(); Log[frame] = lg.GenerateLogEntry();
if (old != val) if (old != val)
@ -470,8 +465,7 @@ namespace BizHawk.Client.Common
bool old = adapter.IsPressed(buttonName); bool old = adapter.IsPressed(buttonName);
adapter.SetBool(buttonName, val); adapter.SetBool(buttonName, val);
var lg = LogGeneratorInstance(); var lg = LogGeneratorInstance(adapter);
lg.SetSource(adapter);
Log[frame + i] = lg.GenerateLogEntry(); Log[frame + i] = lg.GenerateLogEntry();
if (changed == -1 && old != val) if (changed == -1 && old != val)
@ -500,8 +494,7 @@ namespace BizHawk.Client.Common
var old = adapter.AxisValue(buttonName); var old = adapter.AxisValue(buttonName);
adapter.SetAxis(buttonName, val); adapter.SetAxis(buttonName, val);
var lg = LogGeneratorInstance(); var lg = LogGeneratorInstance(adapter);
lg.SetSource(adapter);
Log[frame] = lg.GenerateLogEntry(); Log[frame] = lg.GenerateLogEntry();
if (old != val) if (old != val)
@ -528,8 +521,7 @@ namespace BizHawk.Client.Common
float old = adapter.AxisValue(buttonName); float old = adapter.AxisValue(buttonName);
adapter.SetAxis(buttonName, val); adapter.SetAxis(buttonName, val);
var lg = LogGeneratorInstance(); var lg = LogGeneratorInstance(adapter);
lg.SetSource(adapter);
Log[frame + i] = lg.GenerateLogEntry(); Log[frame + i] = lg.GenerateLogEntry();
if (changed == -1 && old != val) if (changed == -1 && old != val)

View File

@ -233,7 +233,7 @@ namespace BizHawk.Client.EmuHawk
{ {
var m = Global.MovieSession.Movie.IsPlayingOrRecording() var m = Global.MovieSession.Movie.IsPlayingOrRecording()
? Global.MovieSession.Movie.GetInputState(Global.Emulator.Frame - 1) ? Global.MovieSession.Movie.GetInputState(Global.Emulator.Frame - 1)
: Global.MovieSession.MovieControllerInstance(); : Global.MovieSession.MovieController;
return MakeStringFor(Global.InputManager.AutofireStickyXorAdapter.And(m)); return MakeStringFor(Global.InputManager.AutofireStickyXorAdapter.And(m));
} }

View File

@ -210,7 +210,6 @@ namespace BizHawk.Client.EmuHawk
MovieSession = new MovieSession MovieSession = new MovieSession
{ {
Movie = MovieService.DefaultInstance, Movie = MovieService.DefaultInstance,
MovieController = MovieService.DefaultInstance.LogGeneratorInstance().MovieControllerAdapter,
MessageCallback = AddOnScreenMessage, MessageCallback = AddOnScreenMessage,
PopupCallback = ShowMessageCoreComm, PopupCallback = ShowMessageCoreComm,
AskYesNoCallback = StateErrorAskUser, AskYesNoCallback = StateErrorAskUser,

View File

@ -779,7 +779,7 @@ namespace BizHawk.Client.EmuHawk
if (index < _bestBotAttempt.Log.Count) if (index < _bestBotAttempt.Log.Count)
{ {
var logEntry = _bestBotAttempt.Log[index]; var logEntry = _bestBotAttempt.Log[index];
var lg = Global.MovieSession.MovieControllerInstance(); var lg = Global.MovieSession.GenerateMovieController(Emulator.ControllerDefinition);
lg.SetFromMnemonic(logEntry); lg.SetFromMnemonic(logEntry);
foreach (var button in lg.Definition.BoolButtons) foreach (var button in lg.Definition.BoolButtons)

View File

@ -20,8 +20,7 @@ namespace BizHawk.Client.EmuHawk
{ {
_emulator = emulator; _emulator = emulator;
_tools = tools; _tools = tools;
var lg = movie.LogGeneratorInstance(); var lg = movie.LogGeneratorInstance(Global.MovieSession.MovieController);
lg.SetSource(Global.MovieSession.MovieController);
_targetController = new Bk2Controller(_emulator.ControllerDefinition); _targetController = new Bk2Controller(_emulator.ControllerDefinition);
_targetController.SetFrom(_targetController); // Reference and create all buttons _targetController.SetFrom(_targetController); // Reference and create all buttons
@ -55,8 +54,7 @@ namespace BizHawk.Client.EmuHawk
} }
_controller = new Bk2Controller(d); _controller = new Bk2Controller(d);
var logGenerator = new Bk2LogEntryGenerator(""); var logGenerator = Global.MovieSession.LogGeneratorInstance(_controller);
logGenerator.SetSource(_controller);
logGenerator.GenerateLogEntry(); // Reference and create all buttons. logGenerator.GenerateLogEntry(); // Reference and create all buttons.
string movieKey = logGenerator.GenerateLogKey().Replace("LogKey:", "").Replace("#", ""); string movieKey = logGenerator.GenerateLogKey().Replace("LogKey:", "").Replace("#", "");
@ -109,14 +107,11 @@ namespace BizHawk.Client.EmuHawk
} }
var newController = new Bk2Controller(d); var newController = new Bk2Controller(d);
var logGenerator = new Bk2LogEntryGenerator(""); var logGenerator = Global.MovieSession.LogGeneratorInstance(newController);
logGenerator.SetSource(newController);
logGenerator.GenerateLogEntry(); // Reference and create all buttons. logGenerator.GenerateLogEntry(); // Reference and create all buttons.
// Reset all buttons in targetController (it may still have buttons that aren't being set here set true) // Reset all buttons in targetController (it may still have buttons that aren't being set here set true)
var tC = new Bk2LogEntryGenerator(""); var tC = Global.MovieSession.LogGeneratorInstance(_targetController);
tC.SetSource(_targetController);
_targetController.SetFromMnemonic(tC.EmptyEntry); _targetController.SetFromMnemonic(tC.EmptyEntry);
for (int i = 0; i < Length; i++) for (int i = 0; i < Length; i++)
{ {

View File

@ -450,8 +450,7 @@ namespace BizHawk.Client.EmuHawk
} }
_tasClipboard.Add(new TasClipboardEntry(index, input)); _tasClipboard.Add(new TasClipboardEntry(index, input));
var lg = CurrentTasMovie.LogGeneratorInstance(); var lg = CurrentTasMovie.LogGeneratorInstance(input);
lg.SetSource(input);
sb.AppendLine(lg.GenerateLogEntry()); sb.AppendLine(lg.GenerateLogEntry());
} }
@ -568,8 +567,7 @@ namespace BizHawk.Client.EmuHawk
} }
_tasClipboard.Add(new TasClipboardEntry(index, input)); _tasClipboard.Add(new TasClipboardEntry(index, input));
var lg = CurrentTasMovie.LogGeneratorInstance(); var lg = CurrentTasMovie.LogGeneratorInstance(input);
lg.SetSource(input);
sb.AppendLine(lg.GenerateLogEntry()); sb.AppendLine(lg.GenerateLogEntry());
} }

View File

@ -580,12 +580,10 @@ namespace BizHawk.Client.EmuHawk
{ {
get get
{ {
var lg = CurrentTasMovie.LogGeneratorInstance(); var lg = CurrentTasMovie.LogGeneratorInstance(Global.MovieSession.MovieController);
lg.SetSource(Global.MovieSession.MovieControllerInstance());
var empty = lg.EmptyEntry; var empty = lg.EmptyEntry;
foreach (var row in TasView.SelectedRows) foreach (var row in TasView.SelectedRows)
{ {
if (CurrentTasMovie[row].LogEntry != empty) if (CurrentTasMovie[row].LogEntry != empty)
{ {
return row; return row;
@ -599,8 +597,10 @@ namespace BizHawk.Client.EmuHawk
private void AddColumn(RollColumn column) private void AddColumn(RollColumn column)
{ {
if (TasView.AllColumns[column.Name] == null) if (TasView.AllColumns[column.Name] == null)
{
TasView.AllColumns.Add(column); TasView.AllColumns.Add(column);
} }
}
private void EngageTastudio() private void EngageTastudio()
{ {

View File

@ -19,7 +19,7 @@ namespace BizHawk.Client.EmuHawk
public override string ToString() public override string ToString()
{ {
var lg = Global.MovieSession.Movie.LogGeneratorInstance(); var lg = Global.MovieSession.Movie.LogGeneratorInstance(ControllerState);
return lg.GenerateLogEntry(); return lg.GenerateLogEntry();
} }
@ -27,7 +27,7 @@ namespace BizHawk.Client.EmuHawk
{ {
try try
{ {
var lg = Global.MovieSession.MovieControllerInstance(); var lg = Global.MovieSession.GenerateMovieController(Global.Emulator.ControllerDefinition);
lg.SetFromMnemonic(inputLogEntry); lg.SetFromMnemonic(inputLogEntry);
foreach (var button in lg.Definition.BoolButtons) foreach (var button in lg.Definition.BoolButtons)