TasMovie Branch internals

This commit is contained in:
nattthebear 2015-07-19 15:57:40 -04:00
parent f5f4ded789
commit e280e4f55c
3 changed files with 214 additions and 73 deletions

View File

@ -2,82 +2,134 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using ICSharpCode.SharpZipLib.Zip;
//using Ionic.Zip;
namespace BizHawk.Client.Common
{
public enum BinaryStateLump
public class BinaryStateLump
{
Versiontag,
Corestate,
Framebuffer,
Input,
CorestateText,
[Name("BizState 1.0")]
public static BinaryStateLump Versiontag { get; private set; }
[Name("Core")]
public static BinaryStateLump Corestate { get; private set; }
[Name("Framebuffer.bmp")]
public static BinaryStateLump Framebuffer { get; private set; }
[Name("Input Log.txt")]
public static BinaryStateLump Input { get; private set; }
[Name("CoreText.txt")]
public static BinaryStateLump CorestateText { get; private set; }
// Only for movies they probably shoudln't be leaching this stuff
Movieheader,
Comments,
Subtitles,
SyncSettings,
[Name("Header.txt")]
public static BinaryStateLump Movieheader { get; private set; }
[Name("Comments.txt")]
public static BinaryStateLump Comments { get; private set; }
[Name("Subtitles.txt")]
public static BinaryStateLump Subtitles { get; private set; }
[Name("SyncSettings.json")]
public static BinaryStateLump SyncSettings { get; private set; }
// TasMovie
LagLog,
StateHistory,
StateHistorySettings,
Markers,
ClientSettings,
VerificationLog,
Branches,
[Name("LagLog")]
public static BinaryStateLump LagLog { get; private set; }
[Name("GreenZone")]
public static BinaryStateLump StateHistory { get; private set; }
[Name("GreenZoneSettings.txt")]
public static BinaryStateLump StateHistorySettings { get; private set; }
[Name("Markers.txt")]
public static BinaryStateLump Markers { get; private set; }
[Name("ClientSettings.json")]
public static BinaryStateLump ClientSettings { get; private set; }
[Name("VerificationLog.txt")]
public static BinaryStateLump VerificationLog { get; private set; }
UserData
[Name("UserData.txt")]
public static BinaryStateLump UserData { get; private set; }
// branchstuff
[Name("Branches\\CoreData.bin")]
public static BinaryStateLump BranchCoreData { get; private set; }
[Name("Branches\\InputLog.txt")]
public static BinaryStateLump BranchInputLog { get; private set; }
[Name("Branches\\FrameBuffer.bmp")]
public static BinaryStateLump BranchFrameBuffer { get; private set; }
[Name("Branches\\LagLog.bin")]
public static BinaryStateLump BranchLagLog { get; private set; }
[Name("Branches\\Header.json")]
public static BinaryStateLump BranchHeader { get; private set; }
[AttributeUsage(AttributeTargets.Property)]
private class NameAttribute : Attribute
{
public string Name { get; private set; }
public NameAttribute(string name)
{
Name = name;
}
}
public virtual string ReadName { get; private set; }
public virtual string WriteName { get; private set; }
private BinaryStateLump(string name)
{
WriteName = name;
// for reading, all extensions are stripped
ReadName = Path.GetFileNameWithoutExtension(name);
}
protected BinaryStateLump() { }
static BinaryStateLump()
{
foreach (var prop in typeof(BinaryStateLump).GetProperties(BindingFlags.Public | BindingFlags.Static))
{
string name = prop.GetCustomAttributes(false).OfType<NameAttribute>().Single().Name;
object value = new BinaryStateLump(name);
prop.SetValue(null, value, null);
}
}
}
public static class BinaryStateFileNames
/// <summary>
/// describes a BinaryStateLump virtual name that has a numerical index
/// </summary>
public class IndexedStateLump : BinaryStateLump
{
private static readonly Dictionary<BinaryStateLump, string> ReadNames;
private static readonly Dictionary<BinaryStateLump, string> WriteNames;
static void AddLumpName(BinaryStateLump token, string name)
private BinaryStateLump _root;
private int _idx;
public IndexedStateLump(BinaryStateLump root)
{
ReadNames[token] = Path.GetFileNameWithoutExtension(name);
WriteNames[token] = name;
}
static BinaryStateFileNames()
{
ReadNames = new Dictionary<BinaryStateLump, string>();
WriteNames = new Dictionary<BinaryStateLump, string>();
AddLumpName(BinaryStateLump.Versiontag, "BizState 1.0");
AddLumpName(BinaryStateLump.Corestate, "Core");
AddLumpName(BinaryStateLump.Framebuffer, "Framebuffer.bmp");
AddLumpName(BinaryStateLump.Input, "Input Log.txt");
AddLumpName(BinaryStateLump.CorestateText, "CoreText.txt");
AddLumpName(BinaryStateLump.Movieheader, "Header.txt");
// Only for movies they probably shoudln't be leaching this stuff
AddLumpName(BinaryStateLump.Comments, "Comments.txt");
AddLumpName(BinaryStateLump.Subtitles, "Subtitles.txt");
AddLumpName(BinaryStateLump.SyncSettings, "SyncSettings.json");
// TasMovie
AddLumpName(BinaryStateLump.LagLog, "LagLog");
AddLumpName(BinaryStateLump.StateHistory, "GreenZone");
AddLumpName(BinaryStateLump.StateHistorySettings, "GreenZoneSettings.txt");
AddLumpName(BinaryStateLump.Markers, "Markers.txt");
AddLumpName(BinaryStateLump.ClientSettings, "ClientSettings.json");
AddLumpName(BinaryStateLump.VerificationLog, "VerificationLog.txt");
AddLumpName(BinaryStateLump.UserData, "UserData.txt");
AddLumpName(BinaryStateLump.Branches, "Branches");
_root = root;
}
public static string GetReadName(BinaryStateLump lump)
public void Increment()
{
return ReadNames[lump];
_idx++;
}
public static string GetWriteName(BinaryStateLump lump)
public override string ReadName
{
return WriteNames[lump];
get
{
return base.ReadName + _idx;
}
}
public override string WriteName
{
get
{
string fn = Path.GetFileNameWithoutExtension(base.WriteName);
string ext = Path.GetExtension(base.WriteName);
if (!string.IsNullOrEmpty(ext))
ext = ext.Substring(1);
return string.Format("{0}{1}.{2}", fn, _idx, ext);
}
}
}
@ -171,9 +223,8 @@ namespace BizHawk.Client.Common
public bool HasLump(BinaryStateLump lump)
{
string name = BinaryStateFileNames.GetReadName(lump);
ZipEntry e;
return _entriesbyname.TryGetValue(name, out e);
return _entriesbyname.TryGetValue(lump.ReadName, out e);
}
/// <summary>
@ -185,9 +236,8 @@ namespace BizHawk.Client.Common
/// <returns>true if callback was called and stream was loaded</returns>
public bool GetLump(BinaryStateLump lump, bool abort, Action<Stream, long> callback)
{
string name = BinaryStateFileNames.GetReadName(lump);
ZipEntry e;
if (_entriesbyname.TryGetValue(name, out e))
if (_entriesbyname.TryGetValue(lump.ReadName, out e))
{
using (var zs = _zip.GetInputStream(e))
{
@ -199,7 +249,7 @@ namespace BizHawk.Client.Common
if (abort)
{
throw new Exception("Essential zip section not found: " + name);
throw new Exception("Essential zip section not found: " + lump.ReadName);
}
return false;
@ -279,8 +329,7 @@ namespace BizHawk.Client.Common
public void PutLump(BinaryStateLump lump, Action<Stream> callback)
{
var name = BinaryStateFileNames.GetWriteName(lump);
_zip.WriteItem(name, callback);
_zip.WriteItem(lump.WriteName, callback);
}
public void PutLump(BinaryStateLump lump, Action<BinaryWriter> callback)

View File

@ -1,6 +1,8 @@
using System.Collections;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
namespace BizHawk.Client.Common
{
@ -17,14 +19,110 @@ namespace BizHawk.Client.Common
{
private List<TasBranch> Branches = new List<TasBranch>();
public void Save(BinaryWriter bw)
public void Save(BinaryStateSaver bs)
{
var nheader = new IndexedStateLump(BinaryStateLump.BranchHeader);
var ncore = new IndexedStateLump(BinaryStateLump.BranchCoreData);
var ninput = new IndexedStateLump(BinaryStateLump.BranchInputLog);
var nframebuffer = new IndexedStateLump(BinaryStateLump.BranchFrameBuffer);
var nlaglog = new IndexedStateLump(BinaryStateLump.BranchLagLog);
foreach (var b in Branches)
{
bs.PutLump(nheader, delegate(TextWriter tw)
{
// if this header needs more stuff in it, handle it sensibly
tw.WriteLine(JsonConvert.SerializeObject(new { Frame = b.Frame }));
});
bs.PutLump(ncore, delegate(Stream s)
{
s.Write(b.CoreData, 0, b.CoreData.Length);
});
bs.PutLump(ninput, delegate(TextWriter tw)
{
foreach (var line in b.InputLog)
tw.WriteLine(line);
});
bs.PutLump(nframebuffer, delegate(Stream s)
{
// todo: do we want to do something more clever here?
byte[] buff = new byte[2048];
var src = b.OSDFrameBuffer;
for (int i = 0; i < src.Length; i += 512)
{
int n = Math.Min(512, src.Length - i);
Buffer.BlockCopy(src, i * 4, buff, 0, n * 4);
s.Write(buff, 0, n * 4);
}
});
bs.PutLump(nframebuffer, delegate(BinaryWriter bw)
{
b.LagLog.Save(bw);
});
nheader.Increment();
ncore.Increment();
ninput.Increment();
nframebuffer.Increment();
nlaglog.Increment();
}
}
public void Load(BinaryReader br, long length)
public void Load(BinaryStateLoader bl)
{
var nheader = new IndexedStateLump(BinaryStateLump.BranchHeader);
var ncore = new IndexedStateLump(BinaryStateLump.BranchCoreData);
var ninput = new IndexedStateLump(BinaryStateLump.BranchInputLog);
var nframebuffer = new IndexedStateLump(BinaryStateLump.BranchFrameBuffer);
var nlaglog = new IndexedStateLump(BinaryStateLump.BranchLagLog);
Branches.Clear();
while (true)
{
var b = new TasBranch();
if (!bl.GetLump(nheader, false, delegate(TextReader tr)
{
b.Frame = (int)((dynamic)JsonConvert.DeserializeObject(tr.ReadLine())).Frame;
}))
{
return;
}
bl.GetLump(ncore, true, delegate(Stream s, long length)
{
b.CoreData = new byte[length];
s.Read(b.CoreData, 0, b.CoreData.Length);
});
bl.GetLump(ninput, true, delegate(TextReader tr)
{
b.InputLog = new List<string>();
string line;
while ((line = tr.ReadLine()) != null)
b.InputLog.Add(line);
});
bl.GetLump(nframebuffer, true, delegate(Stream s, long length)
{
int[] dst = new int[length / 4];
byte[] buff = new byte[2048];
for (int i = 0; i < dst.Length; i++)
{
int n = Math.Min(512, dst.Length - i);
s.Read(buff, 0, n * 4);
Buffer.BlockCopy(buff, 0, dst, i * 4, n * 4);
}
});
bl.GetLump(nlaglog, true, delegate(BinaryReader br)
{
b.LagLog = new TasLagLog();
b.LagLog.Load(br);
});
Branches.Add(b);
}
}
}
}

View File

@ -93,7 +93,7 @@ namespace BizHawk.Client.Common
if (Branches.Any())
{
bs.PutLump(BinaryStateLump.Branches, (BinaryWriter bw) => Branches.Save(bw));
Branches.Save(bs);
}
ReportProgress(PROGRESS_STEP);
@ -270,13 +270,7 @@ namespace BizHawk.Client.Common
});
}
if (bl.HasLump(BinaryStateLump.Branches))
{
bl.GetLump(BinaryStateLump.Branches, true, delegate(BinaryReader br, long length)
{
Branches.Load(br, length);
});
}
Branches.Load(bl);
}
Changes = false;