Client.Common cleanups - mostly using higher language features

This commit is contained in:
adelikat 2020-02-22 12:29:12 -06:00
parent 6bcbe11eae
commit 5386b8b18c
20 changed files with 980 additions and 1040 deletions

View File

@ -1,6 +1,4 @@
using System;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Common;
namespace BizHawk.Client.Common
{

View File

@ -242,8 +242,7 @@ namespace BizHawk.Client.Common
/// <exception cref="Exception">stream not found and <paramref name="abort"/> is <see langword="true"/></exception>
public bool GetLump(BinaryStateLump lump, bool abort, Action<Stream, long> callback)
{
ZipEntry e;
if (_entriesByName.TryGetValue(lump.ReadName, out e))
if (_entriesByName.TryGetValue(lump.ReadName, out var e))
{
using (var zs = _zip.GetInputStream(e))
{

View File

@ -53,14 +53,13 @@ namespace BizHawk.Client.Common
public ResolutionInfo Resolve(FirmwareDatabase.FirmwareRecord record, bool forbidScan = false)
{
// purpose of forbidScan: sometimes this is called from a loop in Scan(). we dont want to repeatedly DoScanAndResolve in that case, its already been done.
// purpose of forbidScan: sometimes this is called from a loop in Scan(). we don't want to repeatedly DoScanAndResolve in that case, its already been done.
bool first = true;
RETRY:
ResolutionInfo resolved;
_resolutionDictionary.TryGetValue(record, out resolved);
_resolutionDictionary.TryGetValue(record, out var resolved);
// couldnt find it! do a scan and resolve to try harder
// couldn't find it! do a scan and resolve to try harder
// NOTE: this could result in bad performance in some cases if the scanning happens repeatedly..
if (resolved == null && first)
{
@ -76,7 +75,7 @@ namespace BizHawk.Client.Common
return resolved;
}
// Requests the spcified firmware. tries really hard to scan and resolve as necessary
// Requests the specified firmware. tries really hard to scan and resolve as necessary
public string Request(string sysId, string firmwareId)
{
var resolved = Resolve(sysId, firmwareId);
@ -138,16 +137,14 @@ namespace BizHawk.Client.Common
return false;
// weed out filesizes first to reduce the unnecessary overhead of a hashing operation
if (FirmwareDatabase.FirmwareFiles.Where(a => a.Size == fi.Length).FirstOrDefault() == null)
if (FirmwareDatabase.FirmwareFiles.FirstOrDefault(a => a.Size == fi.Length) == null)
return false;
// check the hash
using (var reader = new RealFirmwareReader())
{
reader.Read(fi);
if (FirmwareDatabase.FirmwareFiles.Where(a => a.Hash == reader.Dict.FirstOrDefault().Value.Hash).FirstOrDefault() != null)
return true;
}
using var reader = new RealFirmwareReader();
reader.Read(fi);
if (FirmwareDatabase.FirmwareFiles.FirstOrDefault(a => a.Hash == reader.Dict.FirstOrDefault().Value.Hash) != null)
return true;
}
catch { }
@ -157,133 +154,127 @@ namespace BizHawk.Client.Common
public void DoScanAndResolve()
{
// build a list of file sizes. Only those will be checked during scanning
HashSet<long> sizes = new HashSet<long>();
var sizes = new HashSet<long>();
foreach (var ff in FirmwareDatabase.FirmwareFiles)
{
sizes.Add(ff.Size);
}
using (var reader = new RealFirmwareReader())
{
// build a list of files under the global firmwares path, and build a hash for each of them while we're at it
var todo = new Queue<DirectoryInfo>();
todo.Enqueue(new DirectoryInfo(PathManager.MakeAbsolutePath(Global.Config.PathEntries.FirmwaresPathFragment, null)));
using var reader = new RealFirmwareReader();
// build a list of files under the global firmwares path, and build a hash for each of them while we're at it
var todo = new Queue<DirectoryInfo>();
todo.Enqueue(new DirectoryInfo(PathManager.MakeAbsolutePath(Global.Config.PathEntries.FirmwaresPathFragment, null)));
while (todo.Count != 0)
{
var di = todo.Dequeue();
while (todo.Count != 0)
{
var di = todo.Dequeue();
if (!di.Exists)
if (!di.Exists)
{
continue;
}
// we're going to allow recursing into subdirectories, now. its been verified to work OK
foreach (var disub in di.GetDirectories())
{
todo.Enqueue(disub);
}
foreach (var fi in di.GetFiles())
{
if (sizes.Contains(fi.Length))
{
reader.Read(fi);
}
}
}
// now, for each firmware record, try to resolve it
foreach (var fr in FirmwareDatabase.FirmwareRecords)
{
// clear previous resolution results
_resolutionDictionary.Remove(fr);
// get all options for this firmware (in order)
var fr1 = fr;
var options =
from fo in FirmwareDatabase.FirmwareOptions
where fo.SystemId == fr1.SystemId && fo.FirmwareId == fr1.FirmwareId && fo.IsAcceptableOrIdeal
select fo;
// try each option
foreach (var fo in options)
{
var hash = fo.Hash;
// did we find this firmware?
if (reader.Dict.ContainsKey(hash))
{
// rad! then we can use it
var ri = new ResolutionInfo
{
FilePath = reader.Dict[hash].FileInfo.FullName,
KnownFirmwareFile = FirmwareDatabase.FirmwareFilesByHash[hash],
Hash = hash,
Size = fo.Size
};
_resolutionDictionary[fr] = ri;
goto DONE_FIRMWARE;
}
}
DONE_FIRMWARE: ;
}
// apply user overrides
foreach (var fr in FirmwareDatabase.FirmwareRecords)
{
// do we have a user specification for this firmware record?
if (Global.Config.FirmwareUserSpecifications.TryGetValue(fr.ConfigKey, out var userSpec))
{
// flag it as user specified
if (!_resolutionDictionary.TryGetValue(fr, out ResolutionInfo ri))
{
ri = new ResolutionInfo();
_resolutionDictionary[fr] = ri;
}
ri.UserSpecified = true;
ri.KnownFirmwareFile = null;
ri.FilePath = userSpec;
ri.Hash = null;
// check whether it exists
var fi = new FileInfo(userSpec);
if (!fi.Exists)
{
ri.Missing = true;
continue;
}
// we're going to allow recursing into subdirectories, now. its been verified to work OK
foreach (var disub in di.GetDirectories())
// compute its hash
var rff = reader.Read(fi);
ri.Size = fi.Length;
ri.Hash = rff.Hash;
// check whether it was a known file anyway, and go ahead and bind to the known file, as a perk (the firmwares config doesnt really use this information right now)
if (FirmwareDatabase.FirmwareFilesByHash.TryGetValue(rff.Hash, out var ff))
{
todo.Enqueue(disub);
}
foreach (var fi in di.GetFiles())
{
if (sizes.Contains(fi.Length))
ri.KnownFirmwareFile = ff;
// if the known firmware file is for a different firmware, flag it so we can show a warning
var option =
(from fo in FirmwareDatabase.FirmwareOptions
where fo.Hash == rff.Hash && fo.ConfigKey != fr.ConfigKey
select fr).FirstOrDefault();
if (option != null)
{
reader.Read(fi);
ri.KnownMismatching = true;
}
}
}
// now, for each firmware record, try to resolve it
foreach (var fr in FirmwareDatabase.FirmwareRecords)
{
// clear previous resolution results
_resolutionDictionary.Remove(fr);
// get all options for this firmware (in order)
var fr1 = fr;
var options =
from fo in FirmwareDatabase.FirmwareOptions
where fo.SystemId == fr1.SystemId && fo.FirmwareId == fr1.FirmwareId && fo.IsAcceptableOrIdeal
select fo;
// try each option
foreach (var fo in options)
{
var hash = fo.Hash;
// did we find this firmware?
if (reader.Dict.ContainsKey(hash))
{
// rad! then we can use it
var ri = new ResolutionInfo
{
FilePath = reader.Dict[hash].FileInfo.FullName,
KnownFirmwareFile = FirmwareDatabase.FirmwareFilesByHash[hash],
Hash = hash,
Size = fo.Size
};
_resolutionDictionary[fr] = ri;
goto DONE_FIRMWARE;
}
}
DONE_FIRMWARE: ;
}
// apply user overrides
foreach (var fr in FirmwareDatabase.FirmwareRecords)
{
string userSpec;
// do we have a user specification for this firmware record?
if (Global.Config.FirmwareUserSpecifications.TryGetValue(fr.ConfigKey, out userSpec))
{
// flag it as user specified
ResolutionInfo ri;
if (!_resolutionDictionary.TryGetValue(fr, out ri))
{
ri = new ResolutionInfo();
_resolutionDictionary[fr] = ri;
}
ri.UserSpecified = true;
ri.KnownFirmwareFile = null;
ri.FilePath = userSpec;
ri.Hash = null;
// check whether it exists
var fi = new FileInfo(userSpec);
if (!fi.Exists)
{
ri.Missing = true;
continue;
}
// compute its hash
var rff = reader.Read(fi);
ri.Size = fi.Length;
ri.Hash = rff.Hash;
// check whether it was a known file anyway, and go ahead and bind to the known file, as a perk (the firmwares config doesnt really use this information right now)
FirmwareDatabase.FirmwareFile ff;
if (FirmwareDatabase.FirmwareFilesByHash.TryGetValue(rff.Hash, out ff))
{
ri.KnownFirmwareFile = ff;
// if the known firmware file is for a different firmware, flag it so we can show a warning
var option =
(from fo in FirmwareDatabase.FirmwareOptions
where fo.Hash == rff.Hash && fo.ConfigKey != fr.ConfigKey
select fr).FirstOrDefault();
if (option != null)
{
ri.KnownMismatching = true;
}
}
}
} // foreach(firmware record)
} // using(new RealFirmwareReader())
} // foreach(firmware record)
} // DoScanAndResolve()
} // class FirmwareManager
} // namespace

View File

@ -2,9 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BizHawk.Client.Common
{

View File

@ -46,9 +46,8 @@ namespace BizHawk.Client.Common
// maps to|1|6|7|8|H|2|3|4|-|I|J|K|L|A|B|C|D|M|N|O|5|E|F|G|
Value = 0;
Address = 0x8000;
int x;
_gameGenieTable.TryGetValue(_code[0], out x);
_gameGenieTable.TryGetValue(_code[0], out var x);
Value |= x & 0x07;
Value |= (x & 0x08) << 4;
@ -79,9 +78,8 @@ namespace BizHawk.Client.Common
Value = 0;
Address = 0x8000;
Compare = 0;
int x;
_gameGenieTable.TryGetValue(_code[0], out x);
_gameGenieTable.TryGetValue(_code[0], out var x);
Value |= x & 0x07;
Value |= (x & 0x08) << 4;

View File

@ -1,10 +1,5 @@
using System;
using System.Text;
using System.IO;
using System.Collections.Generic;
using BizHawk.Emulation.Cores;
using Newtonsoft.Json;
//this file contains some cumbersome self-"serialization" in order to gain a modicum of control over what the serialized output looks like
@ -47,7 +42,7 @@ namespace BizHawk.Client.Common
{
if (text.StartsWith("*"))
return Deserialize(text.Substring(1));
else return new OpenAdvanced_OpenRom { Path = text };
return new OpenAdvanced_OpenRom { Path = text };
}
private static IOpenAdvanced Deserialize(string text)
@ -106,11 +101,11 @@ namespace BizHawk.Client.Common
{
public string Path, CorePath;
}
public Token token = new Token();
public Token token;
public string TypeName { get { return "Libretro"; } }
public string DisplayName { get { return $"{Path.GetFileNameWithoutExtension(token.CorePath)}: {token.Path}"; } }
public string SimplePath { get { return token.Path; } }
public string TypeName => "Libretro";
public string DisplayName => $"{Path.GetFileNameWithoutExtension(token.CorePath)}: {token.Path}";
public string SimplePath => token.Path;
public void Deserialize(string str)
{
@ -131,27 +126,26 @@ namespace BizHawk.Client.Common
public class OpenAdvanced_LibretroNoGame : IOpenAdvanced, IOpenAdvancedLibretro
{
//you might think ideally we'd fetch the libretro core name from the core info inside it
//but that would involve spinning up excess libretro core instances, which probably isnt good for stability, no matter how much we wish otherwise, not to mention slow.
//moreover it's kind of complicated here,
//and finally, I think the Displayname should really be file-based in all cases, since the user is going to be loading cores by filename and
//this is related to the recent roms filename management.
//so, leave it.
// you might think ideally we'd fetch the libretro core name from the core info inside it
// but that would involve spinning up excess libretro core instances, which probably isn't good for stability, no matter how much we wish otherwise, not to mention slow.
// moreover it's kind of complicated here,
// and finally, I think the DisplayName should really be file-based in all cases, since the user is going to be loading cores by filename and
// this is related to the recent roms filename management.
// so, leave it.
public OpenAdvanced_LibretroNoGame()
{
}
public OpenAdvanced_LibretroNoGame(string corepath)
public OpenAdvanced_LibretroNoGame(string corePath)
{
_corePath = corepath;
_corePath = corePath;
}
string _corePath;
public string TypeName { get { return "LibretroNoGame"; } }
public string DisplayName { get { return Path.GetFileName(_corePath); } } //assume we like the filename of the core
public string SimplePath { get { return ""; } } //effectively a signal to not use a game
public string TypeName => "LibretroNoGame";
public string DisplayName => Path.GetFileName(_corePath); // assume we like the filename of the core
public string SimplePath => ""; // effectively a signal to not use a game
public void Deserialize(string str)
{
@ -177,9 +171,9 @@ namespace BizHawk.Client.Common
public string Path;
public string TypeName { get { return "OpenRom"; } }
public string DisplayName { get { return Path; } }
public string SimplePath { get { return Path; } }
public string TypeName => "OpenRom";
public string DisplayName => Path;
public string SimplePath => Path;
public void Deserialize(string str)
{
@ -199,9 +193,9 @@ namespace BizHawk.Client.Common
public string Path;
public string TypeName { get { return "MAME"; } }
public string DisplayName { get { return $"{TypeName}: {Path}"; } }
public string SimplePath { get { return Path; } }
public string TypeName => "MAME";
public string DisplayName => $"{TypeName}: {Path}";
public string SimplePath => Path;
public void Deserialize(string str)
{

View File

@ -16,10 +16,6 @@ namespace BizHawk.Client.Common
private const int BankSize = 1024;
public RomGame()
{
}
public RomGame(HawkFile file)
: this(file, null)
{
@ -39,7 +35,7 @@ namespace BizHawk.Client.Common
int fileLength = (int)stream.Length;
// read the entire contents of the file into memory.
// unfortunate in the case of large files, but thats what we've got to work with for now.
// unfortunate in the case of large files, but that's what we've got to work with for now.
// if we're offset exactly 512 bytes from a 1024-byte boundary,
// assume we have a header of that size. Otherwise, assume it's just all rom.
@ -70,14 +66,14 @@ namespace BizHawk.Client.Common
else if (file.Extension == ".DSK" || file.Extension == ".TAP" || file.Extension == ".TZX" ||
file.Extension == ".PZX" || file.Extension == ".CSW" || file.Extension == ".WAV" || file.Extension == ".CDT")
{
// these are not roms. unforunately if treated as such there are certain edge-cases
// these are not roms. unfortunately if treated as such there are certain edge-cases
// where a header offset is detected. This should mitigate this issue until a cleaner solution is found
// (-Asnivor)
RomData = FileData;
}
else
{
// if there was a header offset, read the whole file into FileData and then copy it into RomData (this is unfortunate, in case RomData isnt needed)
// if there was a header offset, read the whole file into FileData and then copy it into RomData (this is unfortunate, in case RomData isn't needed)
int romLength = fileLength - headerOffset;
RomData = new byte[romLength];
Buffer.BlockCopy(FileData, headerOffset, RomData, 0, romLength);
@ -96,7 +92,7 @@ namespace BizHawk.Client.Common
// note: this will be taking several hashes, of a potentially large amount of data.. yikes!
GameInfo = Database.GetGameInfo(RomData, file.Name);
if (GameInfo.NotInDatabase && headerOffset==128 && file.Extension == ".A78")
if (GameInfo.NotInDatabase && headerOffset == 128 && file.Extension == ".A78")
{
// if the game is not in the DB, add the header back in so the core can use it
// for now only .A78 games, but probably should be for other systems as well
@ -107,13 +103,11 @@ namespace BizHawk.Client.Common
if (patch != null)
{
using (var patchFile = new HawkFile(patch))
using var patchFile = new HawkFile(patch);
patchFile.BindFirstOf("IPS");
if (patchFile.IsBound)
{
patchFile.BindFirstOf("IPS");
if (patchFile.IsBound)
{
RomData = IPS.Patch(RomData, patchFile.GetStream());
}
RomData = IPS.Patch(RomData, patchFile.GetStream());
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -37,21 +37,21 @@ namespace BizHawk.Client.Common
offset = 0;
isExecutable = false;
var pathExt = Path.GetExtension(fileName).ToLower();
var pathExt = Path.GetExtension(fileName)?.ToLower();
if (!ArchiveExtensions.Contains(pathExt))
return false;
try
{
using (var arcTest = ArchiveFactory.Open(fileName))
switch (arcTest.Type)
{
case ArchiveType.Zip:
case ArchiveType.SevenZip:
return true;
}
using var arcTest = ArchiveFactory.Open(fileName);
switch (arcTest.Type)
{
case ArchiveType.Zip:
case ArchiveType.SevenZip:
return true;
}
}
catch (Exception _)
catch (Exception)
{
// ignored
}
@ -80,8 +80,8 @@ namespace BizHawk.Client.Common
public void ExtractFile(int index, Stream stream)
{
using (var entryStream = _archive.Entries.Where(e => !e.IsDirectory).ElementAt(index).OpenEntryStream())
entryStream.CopyTo(stream);
using var entryStream = _archive.Entries.Where(e => !e.IsDirectory).ElementAt(index).OpenEntryStream();
entryStream.CopyTo(stream);
}
}
}

View File

@ -40,11 +40,9 @@ namespace BizHawk.Client.Common
var file = new FileInfo(filepath);
if (file.Exists)
{
using (var reader = file.OpenText())
{
var r = new JsonTextReader(reader);
config = (T)Serializer.Deserialize(r, typeof(T));
}
using var reader = file.OpenText();
var r = new JsonTextReader(reader);
config = (T)Serializer.Deserialize(r, typeof(T));
}
}
catch (Exception ex)
@ -65,11 +63,9 @@ namespace BizHawk.Client.Common
var file = new FileInfo(filepath);
try
{
using (var writer = file.CreateText())
{
var w = new JsonTextWriter(writer) { Formatting = Formatting.Indented };
Serializer.Serialize(w, config);
}
using var writer = file.CreateText();
var w = new JsonTextWriter(writer) { Formatting = Formatting.Indented };
Serializer.Serialize(w, config);
}
catch
{
@ -85,27 +81,23 @@ namespace BizHawk.Client.Common
public static object LoadWithType(string serialized)
{
using (TextReader tr = new StringReader(serialized))
using (JsonTextReader jr = new JsonTextReader(tr))
{
TypeNameEncapsulator tne = (TypeNameEncapsulator)Serializer.Deserialize(jr, typeof(TypeNameEncapsulator));
using TextReader tr = new StringReader(serialized);
using JsonTextReader jr = new JsonTextReader(tr);
TypeNameEncapsulator tne = (TypeNameEncapsulator)Serializer.Deserialize(jr, typeof(TypeNameEncapsulator));
// in the case of trying to deserialize nothing, tne will be nothing
// we want to return nothing
return tne?.o;
}
// in the case of trying to deserialize nothing, tne will be nothing
// we want to return nothing
return tne?.o;
}
public static string SaveWithType(object o)
{
using (StringWriter sw = new StringWriter())
using (JsonTextWriter jw = new JsonTextWriter(sw) { Formatting = Formatting.None })
{
TypeNameEncapsulator tne = new TypeNameEncapsulator { o = o };
Serializer.Serialize(jw, tne, typeof(TypeNameEncapsulator));
sw.Flush();
return sw.ToString();
}
using StringWriter sw = new StringWriter();
using JsonTextWriter jw = new JsonTextWriter(sw) { Formatting = Formatting.None };
TypeNameEncapsulator tne = new TypeNameEncapsulator { o = o };
Serializer.Serialize(jw, tne, typeof(TypeNameEncapsulator));
sw.Flush();
return sw.ToString();
}
}
}

View File

@ -2,8 +2,6 @@
using System.ComponentModel;
using NLua;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Consoles.Sega.gpgx;
// ReSharper disable UnusedMember.Global

View File

@ -1,11 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using NLua;
using BizHawk.Emulation.Common;
// ReSharper disable UnusedMember.Global
// ReSharper disable UnusedAutoPropertyAccessor.Local
namespace BizHawk.Client.Common

View File

@ -1,7 +1,6 @@
using System;
using System.ComponentModel;
using NLua;
using BizHawk.Client.Common;
// ReSharper disable UnusedMember.Global
namespace BizHawk.Client.Common

View File

@ -1,6 +1,4 @@
using System;
using System.Runtime.InteropServices;
using BizHawk.Common;
using NLua;

View File

@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace BizHawk.Client.Common.Miniz
{

View File

@ -1,10 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace BizHawk.Client.Common.Miniz
{

View File

@ -1,6 +1,4 @@
using BizHawk.Client.Common.MovieConversionExtensions;
namespace BizHawk.Client.Common.movie.import
namespace BizHawk.Client.Common.movie.import
{
// ReSharper disable once UnusedMember.Global
[ImporterFor("BizHawk", ".bkm")]

View File

@ -15,8 +15,7 @@ namespace BizHawk.Client.Common
{
get
{
bool lag;
var result = _lagLog.TryGetValue(frame, out lag);
var result = _lagLog.TryGetValue(frame, out var lag);
if (result)
{
return lag;

View File

@ -100,9 +100,7 @@ namespace BizHawk.Client.Common
return null;
}
long address;
if (long.TryParse(parts[0], NumberStyles.HexNumber, CultureInfo.CurrentCulture, out address))
if (long.TryParse(parts[0], NumberStyles.HexNumber, CultureInfo.CurrentCulture, out var address))
{
WatchSize size = SizeFromChar(parts[1][0]);
DisplayType type = DisplayTypeFromChar(parts[2][0]);

View File

@ -265,6 +265,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=ffmpeg/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=filenames/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=filesize/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=filesizes/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Finetuned/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Fmpeg/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=fname/@EntryIndexedValue">True</s:Boolean>