Add stuff that didn't work (commented out) to speed up Apple II savestates

This commit is contained in:
goyuken 2015-05-18 02:33:18 +00:00
parent 0cb912cfb2
commit 6710b60788
3 changed files with 223 additions and 1 deletions

View File

@ -135,6 +135,7 @@
<Compile Include="Computers\AppleII\AppleII.IVideoProvider.cs">
<DependentUpon>AppleII.cs</DependentUpon>
</Compile>
<Compile Include="Computers\AppleII\LBSON.cs" />
<Compile Include="Computers\Commodore64\C64.cs" />
<Compile Include="Computers\Commodore64\C64.IDebuggable.cs">
<DependentUpon>C64.cs</DependentUpon>

View File

@ -103,7 +103,7 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII
DeserializeEverything(new BsonReader(reader));
}
*/
public void SaveStateBinary(BinaryWriter writer)
{
var tw = new StreamWriter(writer.BaseStream, new System.Text.UTF8Encoding(false));
@ -117,6 +117,22 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII
LoadStateText(tr);
}
/*
* This naive attempt at making my own kind of BSON writer/reader is slow, probably because
* everything has to be popped out to a full JToken graph to use it. A real competing solution
* would inherit JsonWriter\JsonReader, if that's even possible
public void SaveStateBinary(BinaryWriter writer)
{
var j = new JTokenWriter();
SerializeEverything(j);
new LBSONWriter(writer).Write(j.Token);
}
public void LoadStateBinary(BinaryReader reader)
{
DeserializeEverything(new JTokenReader(new LBSONReader(reader).Read()));
}*/
public byte[] SaveStateBinary()
{
// our savestate array can be of varying sizes, so this can't be too clever

View File

@ -0,0 +1,205 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System.IO;
using Newtonsoft.Json.Linq;
namespace BizHawk.Emulation.Cores.Computers.AppleII
{
// test classes to see if our own lightweight BSON can be fast
// these don't derive JsonReader and JsonWriter because those classes are difficult to derive from,
// so unfortunately everything has to be loaded into memory.
public class LBSONReader
{
private enum LToken : byte
{
Null,
Array,
Object,
S8,
U8,
S16,
U16,
S32,
U32,
S64,
U64,
False,
True,
String,
F32,
F64
}
private LToken ReadToken()
{
return (LToken)r.ReadByte();
}
public LBSONReader(BinaryReader r)
{
this.r = r;
}
private BinaryReader r;
public JToken Read()
{
var t = ReadToken();
switch (t)
{
case LToken.Null: return JValue.CreateNull();
case LToken.Array: return ReadArray();
case LToken.Object: return ReadObject();
case LToken.S8: return new JValue(r.ReadSByte());
case LToken.U8: return new JValue(r.ReadByte());
case LToken.S16: return new JValue(r.ReadInt16());
case LToken.U16: return new JValue(r.ReadUInt16());
case LToken.S32: return new JValue(r.ReadInt32());
case LToken.U32: return new JValue(r.ReadUInt32());
case LToken.S64: return new JValue(r.ReadInt64());
case LToken.U64: return new JValue(r.ReadUInt64());
case LToken.False: return new JValue(false);
case LToken.True: return new JValue(true);
case LToken.String: return new JValue(r.ReadString());
case LToken.F32: return new JValue(r.ReadSingle());
case LToken.F64: return new JValue(r.ReadDouble());
default: throw new InvalidOperationException();
}
}
private JArray ReadArray()
{
int l = r.ReadInt32();
var ret = new JArray();
for (int i = 0; i < l; i++)
{
ret.Add(Read());
}
return ret;
}
private JObject ReadObject()
{
int l = r.ReadInt32();
var ret = new JObject();
for (int i = 0; i < l; i++)
{
ret.Add(r.ReadString(), Read());
}
return ret;
}
}
public class LBSONWriter
{
private enum LToken : byte
{
Null,
Array,
Object,
S8,
U8,
S16,
U16,
S32,
U32,
S64,
U64,
False,
True,
String,
F32,
F64
}
private void WriteToken(LToken t)
{
w.Write((byte)t);
}
public LBSONWriter(BinaryWriter w)
{
this.w = w;
}
private BinaryWriter w;
private void WriteArray(JArray j)
{
WriteToken(LToken.Array);
w.Write(j.Count);
foreach (var jj in j)
{
Write(jj);
}
}
private void WriteObject(JObject j)
{
WriteToken(LToken.Object);
w.Write(j.Count);
foreach (var jj in j)
{
w.Write(jj.Key);
Write(jj.Value);
}
}
private void WriteValue(object o)
{
switch (o.GetType().ToString())
{
case "System.SByte": WriteToken(LToken.S8); w.Write((sbyte)o); return;
case "System.Byte": WriteToken(LToken.U8); w.Write((byte)o); return;
case "System.Int16": WriteToken(LToken.S16); w.Write((short)o); return;
case "System.UInt16": WriteToken(LToken.U16); w.Write((ushort)o); return;
case "System.Int32": WriteToken(LToken.S32); w.Write((int)o); return;
case "System.UInt32": WriteToken(LToken.U32); w.Write((uint)o); return;
case "System.Int64": WriteToken(LToken.S64); w.Write((long)o); return;
case "System.UInt64": WriteToken(LToken.U64); w.Write((ulong)o); return;
case "System.Boolean": WriteToken((bool)o ? LToken.True : LToken.False); return;
case "System.Single": WriteToken(LToken.F32); w.Write((float)o); return;
case "System.Double": WriteToken(LToken.F64); w.Write((double)o); return;
case "System.String": WriteToken(LToken.String); w.Write((string)o); return;
default:
throw new NotImplementedException();
}
}
public void Write(JToken j)
{
switch (j.Type)
{
case JTokenType.Array:
WriteArray((JArray)j);
return;
case JTokenType.Object:
WriteObject((JObject)j);
return;
case JTokenType.Boolean:
case JTokenType.Bytes:
case JTokenType.Date:
case JTokenType.Float:
case JTokenType.Guid:
case JTokenType.Integer:
case JTokenType.String:
WriteValue(((JValue)j).Value);
return;
case JTokenType.Null:
WriteToken(LToken.Null);
return;
default:
throw new NotImplementedException();
}
}
}
}