2017-05-10 18:27:10 +00:00
|
|
|
|
using System.Collections.Generic;
|
2014-11-15 14:31:18 +00:00
|
|
|
|
using System.IO;
|
2014-11-02 00:22:04 +00:00
|
|
|
|
using System.Linq;
|
2019-06-15 17:11:52 +00:00
|
|
|
|
using Newtonsoft.Json;
|
2014-12-05 00:59:00 +00:00
|
|
|
|
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
2014-11-30 20:29:30 +00:00
|
|
|
|
|
2014-11-02 00:22:04 +00:00
|
|
|
|
namespace BizHawk.Client.Common
|
|
|
|
|
{
|
2014-11-15 14:31:18 +00:00
|
|
|
|
public class TasLagLog
|
2014-11-02 00:22:04 +00:00
|
|
|
|
{
|
2019-06-15 17:11:52 +00:00
|
|
|
|
private Dictionary<int, bool> _lagLog = new Dictionary<int, bool>();
|
|
|
|
|
private Dictionary<int, bool> _wasLag = new Dictionary<int, bool>();
|
2015-02-24 21:23:16 +00:00
|
|
|
|
|
2014-11-15 14:31:18 +00:00
|
|
|
|
public bool? this[int frame]
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2019-06-15 17:11:52 +00:00
|
|
|
|
bool lag;
|
|
|
|
|
var result = _lagLog.TryGetValue(frame, out lag);
|
|
|
|
|
if (result)
|
2014-11-15 14:31:18 +00:00
|
|
|
|
{
|
2019-06-15 17:11:52 +00:00
|
|
|
|
return lag;
|
2014-11-15 14:31:18 +00:00
|
|
|
|
}
|
2017-05-10 19:19:46 +00:00
|
|
|
|
|
2019-06-15 17:11:52 +00:00
|
|
|
|
// TODO: don't do this here, the calling code should decide if showing the current emulator state is the right decision
|
|
|
|
|
if (frame == Global.Emulator.Frame)
|
2014-11-15 14:55:44 +00:00
|
|
|
|
{
|
2014-12-05 00:59:00 +00:00
|
|
|
|
return Global.Emulator.AsInputPollable().IsLagFrame;
|
2014-11-15 14:55:44 +00:00
|
|
|
|
}
|
2014-11-15 14:31:18 +00:00
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (!value.HasValue)
|
|
|
|
|
{
|
2019-06-15 18:10:31 +00:00
|
|
|
|
RemoveLagEntry(frame);
|
2015-03-10 17:11:29 +00:00
|
|
|
|
return;
|
2014-11-15 14:31:18 +00:00
|
|
|
|
}
|
2017-05-10 19:19:46 +00:00
|
|
|
|
|
2019-06-15 17:11:52 +00:00
|
|
|
|
_lagLog[frame] = value.Value;
|
2014-11-15 14:31:18 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Clear()
|
|
|
|
|
{
|
2019-06-15 18:27:10 +00:00
|
|
|
|
_wasLag.Clear();
|
2017-05-19 18:17:07 +00:00
|
|
|
|
_lagLog.Clear();
|
2014-11-15 14:31:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-04-18 15:52:02 +00:00
|
|
|
|
public bool RemoveFrom(int frame)
|
2014-11-02 00:22:04 +00:00
|
|
|
|
{
|
2019-06-15 17:11:52 +00:00
|
|
|
|
var frames = _lagLog.Keys.Where(k => k > frame).ToList();
|
|
|
|
|
foreach (var f in frames)
|
2016-04-18 15:52:02 +00:00
|
|
|
|
{
|
2019-06-15 18:10:31 +00:00
|
|
|
|
RemoveLagEntry(frame);
|
2016-04-18 15:52:02 +00:00
|
|
|
|
}
|
2017-05-10 19:19:46 +00:00
|
|
|
|
|
2019-06-15 17:11:52 +00:00
|
|
|
|
return frames.Any();
|
2015-03-10 17:11:29 +00:00
|
|
|
|
}
|
2014-11-15 14:31:18 +00:00
|
|
|
|
|
2015-03-10 17:11:29 +00:00
|
|
|
|
public void RemoveHistoryAt(int frame)
|
|
|
|
|
{
|
2019-06-15 17:11:52 +00:00
|
|
|
|
_wasLag.Remove(frame);
|
2015-03-10 17:11:29 +00:00
|
|
|
|
}
|
2017-05-10 19:19:46 +00:00
|
|
|
|
|
2015-03-10 17:11:29 +00:00
|
|
|
|
public void InsertHistoryAt(int frame, bool isLag)
|
2017-05-10 19:19:46 +00:00
|
|
|
|
{
|
2019-06-15 17:11:52 +00:00
|
|
|
|
_lagLog[frame] = isLag;
|
|
|
|
|
_wasLag[frame] = isLag;
|
2014-11-02 00:22:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-06-15 17:11:52 +00:00
|
|
|
|
public void Save(TextWriter tw)
|
2014-11-02 00:22:04 +00:00
|
|
|
|
{
|
2019-06-15 17:11:52 +00:00
|
|
|
|
tw.WriteLine(JsonConvert.SerializeObject(_lagLog));
|
|
|
|
|
tw.WriteLine(JsonConvert.SerializeObject(_wasLag));
|
2014-11-15 14:31:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-06-15 17:11:52 +00:00
|
|
|
|
public void Load(TextReader tr)
|
2014-11-15 14:31:18 +00:00
|
|
|
|
{
|
2019-06-15 17:11:52 +00:00
|
|
|
|
// TODO: support legacy lag logs that were List<bool>
|
|
|
|
|
_lagLog = JsonConvert.DeserializeObject<Dictionary<int, bool>>(tr.ReadLine());
|
|
|
|
|
_wasLag = JsonConvert.DeserializeObject<Dictionary<int, bool>>(tr.ReadLine());
|
2014-11-02 00:22:04 +00:00
|
|
|
|
}
|
2015-02-24 21:23:16 +00:00
|
|
|
|
|
|
|
|
|
public bool? History(int frame)
|
|
|
|
|
{
|
2019-06-15 17:11:52 +00:00
|
|
|
|
bool wasLag;
|
|
|
|
|
var result = _wasLag.TryGetValue(frame, out wasLag);
|
|
|
|
|
if (result)
|
2015-02-24 21:23:16 +00:00
|
|
|
|
{
|
2019-06-15 17:11:52 +00:00
|
|
|
|
return wasLag;
|
2015-02-24 21:23:16 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2015-07-19 14:37:53 +00:00
|
|
|
|
|
2015-07-22 19:14:33 +00:00
|
|
|
|
public void FromLagLog(TasLagLog log)
|
|
|
|
|
{
|
2019-06-15 17:11:52 +00:00
|
|
|
|
_lagLog = log._lagLog.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
|
|
|
|
|
_wasLag = log._wasLag.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
|
2015-07-22 19:14:33 +00:00
|
|
|
|
}
|
2015-07-23 17:55:22 +00:00
|
|
|
|
|
|
|
|
|
public void StartFromFrame(int index)
|
|
|
|
|
{
|
2019-06-15 17:11:52 +00:00
|
|
|
|
for (int i = 0; i < index; i++)
|
|
|
|
|
{
|
|
|
|
|
_lagLog.Remove(i);
|
|
|
|
|
_wasLag.Remove(i);
|
|
|
|
|
}
|
2015-07-23 17:55:22 +00:00
|
|
|
|
}
|
2019-06-15 18:10:31 +00:00
|
|
|
|
|
|
|
|
|
private void RemoveLagEntry(int frame)
|
|
|
|
|
{
|
|
|
|
|
bool lag;
|
|
|
|
|
var result = _lagLog.TryGetValue(frame, out lag);
|
|
|
|
|
if (result)
|
|
|
|
|
{
|
|
|
|
|
_wasLag[frame] = lag;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_lagLog.Remove(frame);
|
|
|
|
|
}
|
2014-11-02 00:22:04 +00:00
|
|
|
|
}
|
|
|
|
|
}
|