background thread bootgod loading

This commit is contained in:
zeromus 2020-06-08 16:45:44 -05:00
parent 481a48fe85
commit 9c875b42f4
7 changed files with 149 additions and 153 deletions

View File

@ -172,113 +172,115 @@ namespace BizHawk.Client.EmuHawk
return new CoreComm(ShowMessageCoreComm, NotifyCoreComm, cfp, prefs);
}
void SetImages()
{
OpenRomMenuItem.Image = Properties.Resources.OpenFile;
RecentRomSubMenu.Image = Properties.Resources.Recent;
CloseRomMenuItem.Image = Properties.Resources.Close;
PreviousSlotMenuItem.Image = Properties.Resources.MoveLeft;
NextSlotMenuItem.Image = Properties.Resources.MoveRight;
ReadonlyMenuItem.Image = Properties.Resources.ReadOnly;
RecentMovieSubMenu.Image = Properties.Resources.Recent;
RecordMovieMenuItem.Image = Properties.Resources.RecordHS;
PlayMovieMenuItem.Image = Properties.Resources.Play;
StopMovieMenuItem.Image = Properties.Resources.Stop;
PlayFromBeginningMenuItem.Image = Properties.Resources.restart;
ImportMoviesMenuItem.Image = Properties.Resources.Import;
SaveMovieMenuItem.Image = Properties.Resources.SaveAs;
SaveMovieAsMenuItem.Image = Properties.Resources.SaveAs;
StopMovieWithoutSavingMenuItem.Image = Properties.Resources.Stop;
RecordAVMenuItem.Image = Properties.Resources.RecordHS;
ConfigAndRecordAVMenuItem.Image = Properties.Resources.AVI;
StopAVIMenuItem.Image = Properties.Resources.Stop;
ScreenshotMenuItem.Image = Properties.Resources.camera;
PauseMenuItem.Image = Properties.Resources.Pause;
RebootCoreMenuItem.Image = Properties.Resources.reboot;
SwitchToFullscreenMenuItem.Image = Properties.Resources.Fullscreen;
ControllersMenuItem.Image = Properties.Resources.GameController;
HotkeysMenuItem.Image = Properties.Resources.HotKeys;
DisplayConfigMenuItem.Image = Properties.Resources.tvIcon;
SoundMenuItem.Image = Properties.Resources.AudioHS;
PathsMenuItem.Image = Properties.Resources.CopyFolderHS;
FirmwaresMenuItem.Image = Properties.Resources.pcb;
MessagesMenuItem.Image = Properties.Resources.MessageConfig;
AutofireMenuItem.Image = Properties.Resources.Lightning;
RewindOptionsMenuItem.Image = Properties.Resources.Previous;
ProfilesMenuItem.Image = Properties.Resources.user_blue_small;
SaveConfigMenuItem.Image = Properties.Resources.Save;
LoadConfigMenuItem.Image = Properties.Resources.LoadConfig;
ToolBoxMenuItem.Image = Properties.Resources.ToolBox;
RamWatchMenuItem.Image = Properties.Resources.watch;
RamSearchMenuItem.Image = Properties.Resources.search;
LuaConsoleMenuItem.Image = Properties.Resources.Lua;
TAStudioMenuItem.Image = Properties.Resources.TAStudio;
HexEditorMenuItem.Image = Properties.Resources.poke;
TraceLoggerMenuItem.Image = Properties.Resources.pencil;
DebuggerMenuItem.Image = Properties.Resources.Bug;
CodeDataLoggerMenuItem.Image = Properties.Resources.cdlogger;
VirtualPadMenuItem.Image = Properties.Resources.GameController;
CheatsMenuItem.Image = Properties.Resources.Freeze;
GameSharkConverterMenuItem.Image = Properties.Resources.Shark;
MultiDiskBundlerFileMenuItem.Image = Properties.Resources.SaveConfig;
NesControllerSettingsMenuItem.Image = Properties.Resources.GameController;
NESGraphicSettingsMenuItem.Image = Properties.Resources.tvIcon;
NESSoundChannelsMenuItem.Image = Properties.Resources.AudioHS;
KeypadMenuItem.Image = Properties.Resources.calculator;
PSXControllerSettingsMenuItem.Image = Properties.Resources.GameController;
SNESControllerConfigurationMenuItem.Image = Properties.Resources.GameController;
SnesGfxDebuggerMenuItem.Image = Properties.Resources.Bug;
ColecoControllerSettingsMenuItem.Image = Properties.Resources.GameController;
N64PluginSettingsMenuItem.Image = Properties.Resources.monitor;
N64ControllerSettingsMenuItem.Image = Properties.Resources.GameController;
IntVControllerSettingsMenuItem.Image = Properties.Resources.GameController;
OnlineHelpMenuItem.Image = Properties.Resources.Help;
ForumsMenuItem.Image = Properties.Resources.TAStudio;
FeaturesMenuItem.Image = Properties.Resources.kitchensink;
AboutMenuItem.Image = Properties.Resources.CorpHawkSmall;
DumpStatusButton.Image = Properties.Resources.Blank;
PlayRecordStatusButton.Image = Properties.Resources.Blank;
PauseStatusButton.Image = Properties.Resources.Blank;
RebootStatusBarIcon.Image = Properties.Resources.reboot;
AVIStatusLabel.Image = Properties.Resources.Blank;
LedLightStatusLabel.Image = Properties.Resources.LightOff;
KeyPriorityStatusLabel.Image = Properties.Resources.Both;
CoreNameStatusBarButton.Image = Properties.Resources.CorpHawkSmall;
ProfileFirstBootLabel.Image = Properties.Resources.user_blue_small;
LinkConnectStatusBarButton.Image = Properties.Resources.connect_16x16;
OpenRomContextMenuItem.Image = Properties.Resources.OpenFile;
LoadLastRomContextMenuItem.Image = Properties.Resources.Recent;
StopAVContextMenuItem.Image = Properties.Resources.Stop;
RecordMovieContextMenuItem.Image = Properties.Resources.RecordHS;
PlayMovieContextMenuItem.Image = Properties.Resources.Play;
RestartMovieContextMenuItem.Image = Properties.Resources.restart;
StopMovieContextMenuItem.Image = Properties.Resources.Stop;
LoadLastMovieContextMenuItem.Image = Properties.Resources.Recent;
StopNoSaveContextMenuItem.Image = Properties.Resources.Stop;
SaveMovieContextMenuItem.Image = Properties.Resources.SaveAs;
SaveMovieAsContextMenuItem.Image = Properties.Resources.SaveAs;
UndoSavestateContextMenuItem.Image = Properties.Resources.undo;
toolStripMenuItem6.Image = Properties.Resources.GameController;
toolStripMenuItem7.Image = Properties.Resources.HotKeys;
toolStripMenuItem8.Image = Properties.Resources.tvIcon;
toolStripMenuItem9.Image = Properties.Resources.AudioHS;
toolStripMenuItem10.Image = Properties.Resources.CopyFolderHS;
toolStripMenuItem11.Image = Properties.Resources.pcb;
toolStripMenuItem12.Image = Properties.Resources.MessageConfig;
toolStripMenuItem13.Image = Properties.Resources.Lightning;
toolStripMenuItem14.Image = Properties.Resources.Previous;
toolStripMenuItem66.Image = Properties.Resources.Save;
toolStripMenuItem67.Image = Properties.Resources.LoadConfig;
ScreenshotContextMenuItem.Image = Properties.Resources.camera;
CloseRomContextMenuItem.Image = Properties.Resources.Close;
}
public MainForm(string[] args)
{
void SetImages()
{
OpenRomMenuItem.Image = Properties.Resources.OpenFile;
RecentRomSubMenu.Image = Properties.Resources.Recent;
CloseRomMenuItem.Image = Properties.Resources.Close;
PreviousSlotMenuItem.Image = Properties.Resources.MoveLeft;
NextSlotMenuItem.Image = Properties.Resources.MoveRight;
ReadonlyMenuItem.Image = Properties.Resources.ReadOnly;
RecentMovieSubMenu.Image = Properties.Resources.Recent;
RecordMovieMenuItem.Image = Properties.Resources.RecordHS;
PlayMovieMenuItem.Image = Properties.Resources.Play;
StopMovieMenuItem.Image = Properties.Resources.Stop;
PlayFromBeginningMenuItem.Image = Properties.Resources.restart;
ImportMoviesMenuItem.Image = Properties.Resources.Import;
SaveMovieMenuItem.Image = Properties.Resources.SaveAs;
SaveMovieAsMenuItem.Image = Properties.Resources.SaveAs;
StopMovieWithoutSavingMenuItem.Image = Properties.Resources.Stop;
RecordAVMenuItem.Image = Properties.Resources.RecordHS;
ConfigAndRecordAVMenuItem.Image = Properties.Resources.AVI;
StopAVIMenuItem.Image = Properties.Resources.Stop;
ScreenshotMenuItem.Image = Properties.Resources.camera;
PauseMenuItem.Image = Properties.Resources.Pause;
RebootCoreMenuItem.Image = Properties.Resources.reboot;
SwitchToFullscreenMenuItem.Image = Properties.Resources.Fullscreen;
ControllersMenuItem.Image = Properties.Resources.GameController;
HotkeysMenuItem.Image = Properties.Resources.HotKeys;
DisplayConfigMenuItem.Image = Properties.Resources.tvIcon;
SoundMenuItem.Image = Properties.Resources.AudioHS;
PathsMenuItem.Image = Properties.Resources.CopyFolderHS;
FirmwaresMenuItem.Image = Properties.Resources.pcb;
MessagesMenuItem.Image = Properties.Resources.MessageConfig;
AutofireMenuItem.Image = Properties.Resources.Lightning;
RewindOptionsMenuItem.Image = Properties.Resources.Previous;
ProfilesMenuItem.Image = Properties.Resources.user_blue_small;
SaveConfigMenuItem.Image = Properties.Resources.Save;
LoadConfigMenuItem.Image = Properties.Resources.LoadConfig;
ToolBoxMenuItem.Image = Properties.Resources.ToolBox;
RamWatchMenuItem.Image = Properties.Resources.watch;
RamSearchMenuItem.Image = Properties.Resources.search;
LuaConsoleMenuItem.Image = Properties.Resources.Lua;
TAStudioMenuItem.Image = Properties.Resources.TAStudio;
HexEditorMenuItem.Image = Properties.Resources.poke;
TraceLoggerMenuItem.Image = Properties.Resources.pencil;
DebuggerMenuItem.Image = Properties.Resources.Bug;
CodeDataLoggerMenuItem.Image = Properties.Resources.cdlogger;
VirtualPadMenuItem.Image = Properties.Resources.GameController;
CheatsMenuItem.Image = Properties.Resources.Freeze;
GameSharkConverterMenuItem.Image = Properties.Resources.Shark;
MultiDiskBundlerFileMenuItem.Image = Properties.Resources.SaveConfig;
NesControllerSettingsMenuItem.Image = Properties.Resources.GameController;
NESGraphicSettingsMenuItem.Image = Properties.Resources.tvIcon;
NESSoundChannelsMenuItem.Image = Properties.Resources.AudioHS;
KeypadMenuItem.Image = Properties.Resources.calculator;
PSXControllerSettingsMenuItem.Image = Properties.Resources.GameController;
SNESControllerConfigurationMenuItem.Image = Properties.Resources.GameController;
SnesGfxDebuggerMenuItem.Image = Properties.Resources.Bug;
ColecoControllerSettingsMenuItem.Image = Properties.Resources.GameController;
N64PluginSettingsMenuItem.Image = Properties.Resources.monitor;
N64ControllerSettingsMenuItem.Image = Properties.Resources.GameController;
IntVControllerSettingsMenuItem.Image = Properties.Resources.GameController;
OnlineHelpMenuItem.Image = Properties.Resources.Help;
ForumsMenuItem.Image = Properties.Resources.TAStudio;
FeaturesMenuItem.Image = Properties.Resources.kitchensink;
AboutMenuItem.Image = Properties.Resources.CorpHawkSmall;
DumpStatusButton.Image = Properties.Resources.Blank;
PlayRecordStatusButton.Image = Properties.Resources.Blank;
PauseStatusButton.Image = Properties.Resources.Blank;
RebootStatusBarIcon.Image = Properties.Resources.reboot;
AVIStatusLabel.Image = Properties.Resources.Blank;
LedLightStatusLabel.Image = Properties.Resources.LightOff;
KeyPriorityStatusLabel.Image = Properties.Resources.Both;
CoreNameStatusBarButton.Image = Properties.Resources.CorpHawkSmall;
ProfileFirstBootLabel.Image = Properties.Resources.user_blue_small;
LinkConnectStatusBarButton.Image = Properties.Resources.connect_16x16;
OpenRomContextMenuItem.Image = Properties.Resources.OpenFile;
LoadLastRomContextMenuItem.Image = Properties.Resources.Recent;
StopAVContextMenuItem.Image = Properties.Resources.Stop;
RecordMovieContextMenuItem.Image = Properties.Resources.RecordHS;
PlayMovieContextMenuItem.Image = Properties.Resources.Play;
RestartMovieContextMenuItem.Image = Properties.Resources.restart;
StopMovieContextMenuItem.Image = Properties.Resources.Stop;
LoadLastMovieContextMenuItem.Image = Properties.Resources.Recent;
StopNoSaveContextMenuItem.Image = Properties.Resources.Stop;
SaveMovieContextMenuItem.Image = Properties.Resources.SaveAs;
SaveMovieAsContextMenuItem.Image = Properties.Resources.SaveAs;
UndoSavestateContextMenuItem.Image = Properties.Resources.undo;
toolStripMenuItem6.Image = Properties.Resources.GameController;
toolStripMenuItem7.Image = Properties.Resources.HotKeys;
toolStripMenuItem8.Image = Properties.Resources.tvIcon;
toolStripMenuItem9.Image = Properties.Resources.AudioHS;
toolStripMenuItem10.Image = Properties.Resources.CopyFolderHS;
toolStripMenuItem11.Image = Properties.Resources.pcb;
toolStripMenuItem12.Image = Properties.Resources.MessageConfig;
toolStripMenuItem13.Image = Properties.Resources.Lightning;
toolStripMenuItem14.Image = Properties.Resources.Previous;
toolStripMenuItem66.Image = Properties.Resources.Save;
toolStripMenuItem67.Image = Properties.Resources.LoadConfig;
ScreenshotContextMenuItem.Image = Properties.Resources.camera;
CloseRomContextMenuItem.Image = Properties.Resources.Close;
}
Database.InitializeDatabase(Path.Combine(PathUtils.ExeDirectoryPath, "gamedb", "gamedb.txt"));
GlobalWin.MainForm = this;
//do this threaded stuff early so it has plenty of time to run in background
Database.InitializeDatabase(Path.Combine(PathUtils.ExeDirectoryPath, "gamedb", "gamedb.txt"));
BootGodDb.Initialize(Path.Combine(PathUtils.ExeDirectoryPath, "gamedb"));
GlobalWin.InputManager.ControllerInputCoalescer = new ControllerInputCoalescer();
GlobalWin.FirmwareManager = new FirmwareManager();
MovieSession = new MovieSession(
@ -302,23 +304,8 @@ namespace BizHawk.Client.EmuHawk
UpdateStatusSlots();
UpdateKeyPriorityIcon();
// In order to allow late construction of this database, we hook up a delegate here to dearchive the data and provide it on demand
// we could background thread this later instead if we wanted to be real clever
BootGodDb.GetDatabaseBytes = () =>
{
string xmlPath = Path.Combine(PathUtils.ExeDirectoryPath, "gamedb", "NesCarts.xml");
string x7zPath = Path.Combine(PathUtils.ExeDirectoryPath, "gamedb", "NesCarts.7z");
bool loadXml = File.Exists(xmlPath);
using var nesCartFile = new HawkFile(loadXml ? xmlPath : x7zPath);
if (!loadXml)
{
nesCartFile.BindFirst();
}
return nesCartFile
.GetStream()
.ReadAllBytes();
};
try
{
_argParser.ParseArguments(args);

View File

@ -157,9 +157,6 @@ namespace BizHawk.Emulation.Common
}
}
//commit the finished database load
//it's left as null until now to help catch mistakes in using the resource
DB = DB;
acquire.Set();
}

View File

@ -11,6 +11,7 @@
<ProjectReference Include="$(ProjectDir)../BizHawk.BizInvoke/BizHawk.BizInvoke.csproj" />
<ProjectReference Include="$(ProjectDir)../BizHawk.Emulation.Common/BizHawk.Emulation.Common.csproj" />
<ProjectReference Include="$(ProjectDir)../BizHawk.Emulation.DiscSystem/BizHawk.Emulation.DiscSystem.csproj" />
<ProjectReference Include="..\BizHawk.Common\BizHawk.Common.csproj" />
<Compile Include="$(ProjectDir)../BizHawk.Version/svnrev.cs" />
<Compile Include="$(ProjectDir)../BizHawk.Version/VersionInfo.cs" />
<EmbeddedResource Include="Resources/**/*" />

View File

@ -1,40 +1,41 @@
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.IO;
using System.IO;
using System.Xml;
using System.Threading;
using BizHawk.Common;
namespace BizHawk.Emulation.Cores.Nintendo.NES
{
public class BootGodDb
{
static object staticsyncroot = new object();
object syncroot = new object();
{
/// <summary>
/// blocks until the DB is done loading
/// </summary>
static EventWaitHandle acquire;
bool validate = true;
private readonly Bag<string, CartInfo> _sha1Table = new Bag<string, CartInfo>();
private static BootGodDb _instance;
public static BootGodDb Instance
static BootGodDb instance;
public static void Initialize(string basePath)
{
get { lock (staticsyncroot) { return _instance; } }
if (acquire != null) throw new InvalidOperationException("Bootgod DB multiply initialized");
acquire = new EventWaitHandle(false, EventResetMode.ManualReset); ;
var stopwatch = Stopwatch.StartNew();
ThreadPool.QueueUserWorkItem(_ =>
{
instance = new BootGodDb(basePath);
Console.WriteLine("Bootgod DB load: " + stopwatch.Elapsed + " sec");
acquire.Set();
});
}
private static Func<byte[]> _GetDatabaseBytes;
public static Func<byte[]> GetDatabaseBytes
{
set { lock (staticsyncroot) { _GetDatabaseBytes = value; } }
}
public static void Initialize()
{
lock (staticsyncroot)
{
_instance ??= new BootGodDb();
}
}
private BootGodDb() { }
private int ParseSize(string str)
{
@ -48,14 +49,26 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
}
return temp;
}
public BootGodDb()
public BootGodDb(string basePath)
{
// notes: there can be multiple each of prg,chr,wram,vram
// we aren't tracking the individual hashes yet.
string xmlPath = Path.Combine(basePath, "NesCarts.xml");
string x7zPath = Path.Combine(basePath, "NesCarts.7z");
bool loadXml = File.Exists(xmlPath);
using var nesCartFile = new HawkFile(loadXml ? xmlPath : x7zPath);
if (!loadXml)
{
nesCartFile.BindFirst();
}
var stream = nesCartFile.GetStream();
// in anticipation of any slowness annoying people, and just for shits and giggles, i made a super fast parser
int state=0;
var xmlReader = XmlReader.Create(new MemoryStream(_GetDatabaseBytes()));
var xmlReader = XmlReader.Create(stream);
CartInfo currCart = null;
string currName = null;
while (xmlReader.Read())
@ -141,9 +154,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
} //end xmlreader loop
}
public List<CartInfo> Identify(string sha1)
public static List<CartInfo> Identify(string sha1)
{
lock (syncroot) return _sha1Table[sha1];
if (acquire == null) throw new InvalidOperationException("Bootgod DB not initialized. It's a client responsibility because only a client knows where the database is located.");
acquire.WaitOne();
return instance._sha1Table[sha1];
}
}
}

View File

@ -140,10 +140,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
/// </summary>
CartInfo IdentifyFromBootGodDB(IEnumerable<string> hash_sha1)
{
BootGodDb.Initialize();
foreach (var hash in hash_sha1)
{
List<CartInfo> choices = BootGodDb.Instance.Identify(hash);
List<CartInfo> choices = BootGodDb.Identify(hash);
//pick the first board for this hash arbitrarily. it probably doesn't make a difference
if (choices.Count != 0)
return choices[0];

View File

@ -35,7 +35,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
SyncSettings = (NESSyncSettings)syncSettings ?? new NESSyncSettings();
ControllerSettings = SyncSettings.Controls;
BootGodDb.Initialize();
videoProvider = new MyVideoProvider(this);
Init(game, rom, fdsBios);
if (Board is FDS fds)
@ -86,7 +85,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
private NES()
{
BootGodDb.Initialize();
}
public void WriteLogTimestamp()

View File

@ -241,7 +241,6 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES
void ComputeBootGod()
{
// inefficient, sloppy, etc etc
BootGodDb.Initialize();
var chrrom = _memoryDomains["CHR VROM"];
var prgrom = _memoryDomains["PRG ROM"];
@ -262,7 +261,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES
}
sha1 = "sha1:" + sha1; // huh?
var carts = BootGodDb.Instance.Identify(sha1);
var carts = BootGodDb.Identify(sha1);
if (carts.Count > 0)
{