From d6b9babe1d73a78e963455a5a6ea3e7431a44ece Mon Sep 17 00:00:00 2001
From: Thog <me@thog.eu>
Date: Tue, 21 Jan 2020 23:23:11 +0100
Subject: Keep the GUI alive when closing a game (#888)

* Keep the GUI alive when closing a game

Make HLE.Switch init when starting a game and dispose it when closing
the GlScreen.

This also make HLE in charge of disposing the audio and gpu backend.

* Address Ac_k's comments

* Make sure to dispose the Discord module and use GTK quit method

Also update Discord Precense when closing a game.

* Make sure to dispose MainWindow

* Address gdk's comments
---
 Ryujinx.HLE/FileSystem/Content/ContentManager.cs | 74 +++++++++++++-----------
 1 file changed, 41 insertions(+), 33 deletions(-)

(limited to 'Ryujinx.HLE/FileSystem/Content/ContentManager.cs')

diff --git a/Ryujinx.HLE/FileSystem/Content/ContentManager.cs b/Ryujinx.HLE/FileSystem/Content/ContentManager.cs
index 680ebd52..1c6364c7 100644
--- a/Ryujinx.HLE/FileSystem/Content/ContentManager.cs
+++ b/Ryujinx.HLE/FileSystem/Content/ContentManager.cs
@@ -14,7 +14,7 @@ using System.Linq;
 
 namespace Ryujinx.HLE.FileSystem.Content
 {
-    internal class ContentManager
+    public class ContentManager
     {
         private const ulong SystemVersionTitleId = 0x0100000000000809;
         private const ulong SystemUpdateTitleId  = 0x0100000000000816;
@@ -26,11 +26,11 @@ namespace Ryujinx.HLE.FileSystem.Content
 
         private SortedDictionary<(ulong titleId, NcaContentType type), string> _contentDictionary;
 
-        private Switch _device;
+        private VirtualFileSystem _virtualFileSystem;
 
         private readonly object _lock = new object();
 
-        public ContentManager(Switch device)
+        public ContentManager(VirtualFileSystem virtualFileSystem)
         {
             _contentDictionary = new SortedDictionary<(ulong, NcaContentType), string>();
             _locationEntries   = new Dictionary<StorageId, LinkedList<LocationEntry>>();
@@ -55,10 +55,10 @@ namespace Ryujinx.HLE.FileSystem.Content
                 { "FontNintendoExtended",          "nintendo_ext_003.bfttf" }
             };
 
-            _device = device;
+            _virtualFileSystem = virtualFileSystem;
         }
 
-        public void LoadEntries(bool ignoreMissingFonts = false)
+        public void LoadEntries(Switch device = null)
         {
             lock (_lock)
             {
@@ -74,7 +74,7 @@ namespace Ryujinx.HLE.FileSystem.Content
                     try
                     {
                         contentPathString   = LocationHelper.GetContentRoot(storageId);
-                        contentDirectory    = LocationHelper.GetRealPath(_device.FileSystem, contentPathString);
+                        contentDirectory    = LocationHelper.GetRealPath(_virtualFileSystem, contentPathString);
                         registeredDirectory = Path.Combine(contentDirectory, "registered");
                     }
                     catch (NotSupportedException)
@@ -99,7 +99,7 @@ namespace Ryujinx.HLE.FileSystem.Content
 
                             using (FileStream ncaFile = File.OpenRead(Directory.GetFiles(directoryPath)[0]))
                             {
-                                Nca nca = new Nca(_device.System.KeySet, ncaFile.AsStorage());
+                                Nca nca = new Nca(_virtualFileSystem.KeySet, ncaFile.AsStorage());
 
                                 string switchPath = contentPathString + ":/" + ncaFile.Name.Replace(contentDirectory, string.Empty).TrimStart(Path.DirectorySeparatorChar);
 
@@ -126,7 +126,7 @@ namespace Ryujinx.HLE.FileSystem.Content
 
                             using (FileStream ncaFile = new FileStream(filePath, FileMode.Open, FileAccess.Read))
                             {
-                                Nca nca = new Nca(_device.System.KeySet, ncaFile.AsStorage());
+                                Nca nca = new Nca(_virtualFileSystem.KeySet, ncaFile.AsStorage());
 
                                 string switchPath = contentPathString + ":/" + filePath.Replace(contentDirectory, string.Empty).TrimStart(Path.DirectorySeparatorChar);
 
@@ -156,9 +156,11 @@ namespace Ryujinx.HLE.FileSystem.Content
                     }
                 }
 
-                TimeManager.Instance.InitializeTimeZone(_device);
-
-                _device.System.Font.Initialize(this, ignoreMissingFonts);
+                if (device != null)
+                {
+                    TimeManager.Instance.InitializeTimeZone(device);
+                    device.System.Font.Initialize(this);
+                }
             }
         }
 
@@ -271,7 +273,7 @@ namespace Ryujinx.HLE.FileSystem.Content
                 return false;
             }
             
-            string installedPath = _device.FileSystem.SwitchPathToSystemPath(locationEntry.ContentPath);
+            string installedPath = _virtualFileSystem.SwitchPathToSystemPath(locationEntry.ContentPath);
 
             if (!string.IsNullOrWhiteSpace(installedPath))
             {
@@ -279,7 +281,7 @@ namespace Ryujinx.HLE.FileSystem.Content
                 {
                     using (FileStream file = new FileStream(installedPath, FileMode.Open, FileAccess.Read))
                     {
-                        Nca nca = new Nca(_device.System.KeySet, file.AsStorage());
+                        Nca nca = new Nca(_virtualFileSystem.KeySet, file.AsStorage());
                         bool contentCheck = nca.Header.ContentType == contentType;
 
                         return contentCheck;
@@ -351,7 +353,7 @@ namespace Ryujinx.HLE.FileSystem.Content
         public void InstallFirmware(string firmwareSource)
         {
             string contentPathString   = LocationHelper.GetContentRoot(StorageId.NandSystem);
-            string contentDirectory    = LocationHelper.GetRealPath(_device.FileSystem, contentPathString);
+            string contentDirectory    = LocationHelper.GetRealPath(_virtualFileSystem, contentPathString);
             string registeredDirectory = Path.Combine(contentDirectory, "registered");
             string temporaryDirectory  = Path.Combine(contentDirectory, "temp");
 
@@ -386,7 +388,7 @@ namespace Ryujinx.HLE.FileSystem.Content
                         }
                         break;
                     case ".xci":
-                        Xci xci = new Xci(_device.System.KeySet, file.AsStorage());
+                        Xci xci = new Xci(_virtualFileSystem.KeySet, file.AsStorage());
                         InstallFromCart(xci, temporaryDirectory);
                         break;
                     default:
@@ -418,7 +420,7 @@ namespace Ryujinx.HLE.FileSystem.Content
         {
             foreach (var entry in filesystem.EnumerateEntries("/", "*.nca"))
             {
-                Nca nca = new Nca(_device.System.KeySet, OpenPossibleFragmentedFile(filesystem, entry.FullPath, OpenMode.Read).AsStorage());
+                Nca nca = new Nca(_virtualFileSystem.KeySet, OpenPossibleFragmentedFile(filesystem, entry.FullPath, OpenMode.Read).AsStorage());
 
                 SaveNca(nca, entry.Name.Remove(entry.Name.IndexOf('.')), temporaryDirectory);
             }
@@ -537,7 +539,7 @@ namespace Ryujinx.HLE.FileSystem.Content
                             return VerifyAndGetVersionZip(archive);
                         }
                     case ".xci":
-                        Xci xci = new Xci(_device.System.KeySet, file.AsStorage());
+                        Xci xci = new Xci(_virtualFileSystem.KeySet, file.AsStorage());
 
                         if (xci.HasPartition(XciPartitionType.Update))
                         {
@@ -561,6 +563,8 @@ namespace Ryujinx.HLE.FileSystem.Content
 
             SystemVersion VerifyAndGetVersionZip(ZipArchive archive)
             {
+                IntegrityCheckLevel integrityCheckLevel = Switch.GetIntigrityCheckLevel();
+
                 SystemVersion systemVersion = null;
 
                 foreach (var entry in archive.Entries)
@@ -571,7 +575,7 @@ namespace Ryujinx.HLE.FileSystem.Content
                         {
                             IStorage storage = ncaStream.AsStorage();
 
-                            Nca nca = new Nca(_device.System.KeySet, storage);
+                            Nca nca = new Nca(_virtualFileSystem.KeySet, storage);
 
                             if (updateNcas.ContainsKey(nca.Header.TitleId))
                             {
@@ -598,9 +602,9 @@ namespace Ryujinx.HLE.FileSystem.Content
 
                     using (Stream ncaStream = GetZipStream(fileEntry))
                     {
-                        Nca metaNca = new Nca(_device.System.KeySet, ncaStream.AsStorage());
+                        Nca metaNca = new Nca(_virtualFileSystem.KeySet, ncaStream.AsStorage());
 
-                        IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, _device.System.FsIntegrityCheckLevel);
+                        IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, integrityCheckLevel);
 
                         string cnmtPath = fs.EnumerateEntries("/", "*.cnmt").Single().FullPath;
 
@@ -628,9 +632,9 @@ namespace Ryujinx.HLE.FileSystem.Content
 
                         using (Stream ncaStream = GetZipStream(archive.GetEntry(versionEntry)))
                         {
-                            Nca nca = new Nca(_device.System.KeySet, ncaStream.AsStorage());
+                            Nca nca = new Nca(_virtualFileSystem.KeySet, ncaStream.AsStorage());
 
-                            var romfs = nca.OpenFileSystem(NcaSectionType.Data, _device.System.FsIntegrityCheckLevel);
+                            var romfs = nca.OpenFileSystem(NcaSectionType.Data, integrityCheckLevel);
 
                             if (romfs.OpenFile(out IFile systemVersionFile, "/file", OpenMode.Read).IsSuccess())
                             {
@@ -663,9 +667,9 @@ namespace Ryujinx.HLE.FileSystem.Content
                             {
                                 using (Stream contentNcaStream = GetZipStream(contentZipEntry))
                                 {
-                                    Nca metaNca = new Nca(_device.System.KeySet, metaNcaStream.AsStorage());
+                                    Nca metaNca = new Nca(_virtualFileSystem.KeySet, metaNcaStream.AsStorage());
 
-                                    IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, _device.System.FsIntegrityCheckLevel);
+                                    IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, integrityCheckLevel);
 
                                     string cnmtPath = fs.EnumerateEntries("/", "*.cnmt").Single().FullPath;
 
@@ -722,6 +726,8 @@ namespace Ryujinx.HLE.FileSystem.Content
 
             SystemVersion VerifyAndGetVersion(IFileSystem filesystem)
             {
+                IntegrityCheckLevel integrityCheckLevel = Switch.GetIntigrityCheckLevel();
+
                 SystemVersion systemVersion = null;
 
                 CnmtContentMetaEntry[] metaEntries = null;
@@ -730,11 +736,11 @@ namespace Ryujinx.HLE.FileSystem.Content
                 {
                     IStorage ncaStorage = OpenPossibleFragmentedFile(filesystem, entry.FullPath, OpenMode.Read).AsStorage();
 
-                    Nca nca = new Nca(_device.System.KeySet, ncaStorage);
+                    Nca nca = new Nca(_virtualFileSystem.KeySet, ncaStorage);
 
                     if (nca.Header.TitleId == SystemUpdateTitleId && nca.Header.ContentType == NcaContentType.Meta)
                     {
-                        IFileSystem fs = nca.OpenFileSystem(NcaSectionType.Data, _device.System.FsIntegrityCheckLevel);
+                        IFileSystem fs = nca.OpenFileSystem(NcaSectionType.Data, integrityCheckLevel);
 
                         string cnmtPath = fs.EnumerateEntries("/", "*.cnmt").Single().FullPath;
 
@@ -752,7 +758,7 @@ namespace Ryujinx.HLE.FileSystem.Content
                     }
                     else if (nca.Header.TitleId == SystemVersionTitleId && nca.Header.ContentType == NcaContentType.Data)
                     {
-                        var romfs = nca.OpenFileSystem(NcaSectionType.Data, _device.System.FsIntegrityCheckLevel);
+                        var romfs = nca.OpenFileSystem(NcaSectionType.Data, integrityCheckLevel);
 
                         if (romfs.OpenFile(out IFile systemVersionFile, "/file", OpenMode.Read).IsSuccess())
                         {
@@ -797,9 +803,9 @@ namespace Ryujinx.HLE.FileSystem.Content
                         IStorage metaStorage = OpenPossibleFragmentedFile(filesystem, metaNcaEntry.path, OpenMode.Read).AsStorage();
                         IStorage contentStorage = OpenPossibleFragmentedFile(filesystem, contentPath, OpenMode.Read).AsStorage();
 
-                        Nca metaNca = new Nca(_device.System.KeySet, metaStorage);
+                        Nca metaNca = new Nca(_virtualFileSystem.KeySet, metaStorage);
 
-                        IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, _device.System.FsIntegrityCheckLevel);
+                        IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, integrityCheckLevel);
 
                         string cnmtPath = fs.EnumerateEntries("/", "*.cnmt").Single().FullPath;
 
@@ -851,7 +857,9 @@ namespace Ryujinx.HLE.FileSystem.Content
 
         public SystemVersion GetCurrentFirmwareVersion()
         {
-            LoadEntries(true);
+            IntegrityCheckLevel integrityCheckLevel = Switch.GetIntigrityCheckLevel();
+
+            LoadEntries();
 
             lock (_lock)
             {
@@ -861,15 +869,15 @@ namespace Ryujinx.HLE.FileSystem.Content
                 {
                     if (entry.ContentType == NcaContentType.Data)
                     {
-                        var path = _device.FileSystem.SwitchPathToSystemPath(entry.ContentPath);
+                        var path = _virtualFileSystem.SwitchPathToSystemPath(entry.ContentPath);
 
                         using (FileStream fileStream = File.OpenRead(path))
                         {
-                            Nca nca = new Nca(_device.System.KeySet, fileStream.AsStorage());
+                            Nca nca = new Nca(_virtualFileSystem.KeySet, fileStream.AsStorage());
 
                             if (nca.Header.TitleId == SystemVersionTitleId && nca.Header.ContentType == NcaContentType.Data)
                             {
-                                var romfs = nca.OpenFileSystem(NcaSectionType.Data, _device.System.FsIntegrityCheckLevel);
+                                var romfs = nca.OpenFileSystem(NcaSectionType.Data, integrityCheckLevel);
 
                                 if (romfs.OpenFile(out IFile systemVersionFile, "/file", OpenMode.Read).IsSuccess())
                                 {
-- 
cgit v1.2.3-70-g09d2