From 651a07c6c2a3e89c059d56e916c45e1881d56abc Mon Sep 17 00:00:00 2001 From: Mary <57835969+h1k421@users.noreply.github.com> Date: Mon, 4 May 2020 04:15:27 +0200 Subject: [PATCH] Refactor SystemInfo and implement macOS system info backend (#1177) --- Ryujinx.Common/SystemInfo.cs | 41 -------- Ryujinx.Common/SystemInfo/LinuxSystemInfo.cs | 17 ++++ Ryujinx.Common/SystemInfo/MacOSSysteminfo.cs | 97 +++++++++++++++++++ Ryujinx.Common/SystemInfo/SystemInfo.cs | 46 +++++++++ .../SystemInfo/WindowsSystemInfo.cs | 23 +++++ Ryujinx/Program.cs | 8 +- 6 files changed, 187 insertions(+), 45 deletions(-) delete mode 100644 Ryujinx.Common/SystemInfo.cs create mode 100644 Ryujinx.Common/SystemInfo/LinuxSystemInfo.cs create mode 100644 Ryujinx.Common/SystemInfo/MacOSSysteminfo.cs create mode 100644 Ryujinx.Common/SystemInfo/SystemInfo.cs create mode 100644 Ryujinx.Common/SystemInfo/WindowsSystemInfo.cs diff --git a/Ryujinx.Common/SystemInfo.cs b/Ryujinx.Common/SystemInfo.cs deleted file mode 100644 index dbe0261726..0000000000 --- a/Ryujinx.Common/SystemInfo.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Management; -using System.Runtime.InteropServices; - -namespace Ryujinx.Common -{ - public static class SystemInfo - { - public static string OsDescription { get; private set; } - public static string CpuName { get; private set; } - public static string RamSize { get; private set; } - - static SystemInfo() - { - OsDescription = $"{RuntimeInformation.OSDescription} ({RuntimeInformation.OSArchitecture})"; - CpuName = "Unknown"; - RamSize = "Unknown"; - - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - foreach (ManagementBaseObject mObject in new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_Processor").Get()) - { - CpuName = mObject["Name"].ToString(); - } - - foreach (ManagementBaseObject mObject in new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_OperatingSystem").Get()) - { - RamSize = $"{Math.Round(double.Parse(mObject["TotalVisibleMemorySize"].ToString()) / 1024, 0)} MB"; - } - } - - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - { - CpuName = File.ReadAllLines("/proc/cpuinfo").Where(line => line.StartsWith("model name")).ToList()[0].Split(":")[1].Trim(); - RamSize = $"{Math.Round(double.Parse(File.ReadAllLines("/proc/meminfo")[0].Split(":")[1].Trim().Split(" ")[0]) / 1024, 0)} MB"; - } - } - } -} \ No newline at end of file diff --git a/Ryujinx.Common/SystemInfo/LinuxSystemInfo.cs b/Ryujinx.Common/SystemInfo/LinuxSystemInfo.cs new file mode 100644 index 0000000000..bd3ee57a52 --- /dev/null +++ b/Ryujinx.Common/SystemInfo/LinuxSystemInfo.cs @@ -0,0 +1,17 @@ +using System.IO; +using System.Linq; + +namespace Ryujinx.Common.SystemInfo +{ + internal class LinuxSysteminfo : SystemInfo + { + public override string CpuName { get; } + public override ulong RamSize { get; } + + public LinuxSysteminfo() + { + CpuName = File.ReadAllLines("/proc/cpuinfo").Where(line => line.StartsWith("model name")).ToList()[0].Split(":")[1].Trim(); + RamSize = ulong.Parse(File.ReadAllLines("/proc/meminfo")[0].Split(":")[1].Trim().Split(" ")[0]) * 1024; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Common/SystemInfo/MacOSSysteminfo.cs b/Ryujinx.Common/SystemInfo/MacOSSysteminfo.cs new file mode 100644 index 0000000000..167c96dbfb --- /dev/null +++ b/Ryujinx.Common/SystemInfo/MacOSSysteminfo.cs @@ -0,0 +1,97 @@ +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; +using Ryujinx.Common.Logging; + +namespace Ryujinx.Common.SystemInfo +{ + internal class MacOSSysteminfo : SystemInfo + { + public override string CpuName { get; } + public override ulong RamSize { get; } + + [DllImport("libSystem.dylib", CharSet = CharSet.Ansi, SetLastError = true)] + private static extern int sysctlbyname(string name, IntPtr oldValue, ref ulong oldSize, IntPtr newValue, ulong newValueSize); + + private static int sysctlbyname(string name, IntPtr oldValue, ref ulong oldSize) + { + if (sysctlbyname(name, oldValue, ref oldSize, IntPtr.Zero, 0) == -1) + { + return Marshal.GetLastWin32Error(); + } + + return 0; + } + + private static int sysctlbyname(string name, ref T oldValue) + { + unsafe + { + ulong oldValueSize = (ulong)Unsafe.SizeOf(); + + return sysctlbyname(name, (IntPtr)Unsafe.AsPointer(ref oldValue), ref oldValueSize); + } + } + + private static int sysctlbyname(string name, out string oldValue) + { + oldValue = default; + + ulong strSize = 0; + + int res = sysctlbyname(name, IntPtr.Zero, ref strSize); + + if (res == 0) + { + byte[] rawData = new byte[strSize]; + + unsafe + { + fixed (byte* rawDataPtr = rawData) + { + res = sysctlbyname(name, (IntPtr)rawDataPtr, ref strSize); + } + + if (res == 0) + { + oldValue = Encoding.ASCII.GetString(rawData); + } + } + } + + return res; + } + + public MacOSSysteminfo() + { + ulong ramSize = 0; + + int res = sysctlbyname("hw.memsize", ref ramSize); + + if (res == 0) + { + RamSize = ramSize; + } + else + { + Logger.PrintError(LogClass.Application, $"Cannot get memory size, sysctlbyname error: {res}"); + + RamSize = 0; + } + + res = sysctlbyname("machdep.cpu.brand_string", out string cpuName); + + if (res == 0) + { + CpuName = cpuName; + } + else + { + Logger.PrintError(LogClass.Application, $"Cannot get CPU name, sysctlbyname error: {res}"); + + CpuName = "Unknown"; + } + } + } +} \ No newline at end of file diff --git a/Ryujinx.Common/SystemInfo/SystemInfo.cs b/Ryujinx.Common/SystemInfo/SystemInfo.cs new file mode 100644 index 0000000000..9ab1419c8a --- /dev/null +++ b/Ryujinx.Common/SystemInfo/SystemInfo.cs @@ -0,0 +1,46 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Common.SystemInfo +{ + public class SystemInfo + { + public virtual string OsDescription => $"{RuntimeInformation.OSDescription} ({RuntimeInformation.OSArchitecture})"; + public virtual string CpuName => "Unknown"; + public virtual ulong RamSize => 0; + + public string RamSizeInMB + { + get + { + if (RamSize == 0) + { + return "Unknown"; + } + + return $"{RamSize / 1024 / 1024} MB"; + } + } + + public static SystemInfo Instance { get; } + + static SystemInfo() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + Instance = new WindowsSysteminfo(); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + Instance = new LinuxSysteminfo(); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + Instance = new MacOSSysteminfo(); + } + else + { + Instance = new SystemInfo(); + } + } + } +} \ No newline at end of file diff --git a/Ryujinx.Common/SystemInfo/WindowsSystemInfo.cs b/Ryujinx.Common/SystemInfo/WindowsSystemInfo.cs new file mode 100644 index 0000000000..1d4e61faf9 --- /dev/null +++ b/Ryujinx.Common/SystemInfo/WindowsSystemInfo.cs @@ -0,0 +1,23 @@ +using System.Management; + +namespace Ryujinx.Common.SystemInfo +{ + internal class WindowsSysteminfo : SystemInfo + { + public override string CpuName { get; } + public override ulong RamSize { get; } + + public WindowsSysteminfo() + { + foreach (ManagementBaseObject mObject in new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_Processor").Get()) + { + CpuName = mObject["Name"].ToString(); + } + + foreach (ManagementBaseObject mObject in new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_OperatingSystem").Get()) + { + RamSize = ulong.Parse(mObject["TotalVisibleMemorySize"].ToString()) * 1024; + } + } + } +} \ No newline at end of file diff --git a/Ryujinx/Program.cs b/Ryujinx/Program.cs index 2a906b82a6..45876da8d0 100644 --- a/Ryujinx/Program.cs +++ b/Ryujinx/Program.cs @@ -1,6 +1,6 @@ using Gtk; -using Ryujinx.Common; using Ryujinx.Common.Logging; +using Ryujinx.Common.SystemInfo; using Ryujinx.Configuration; using Ryujinx.Debugger.Profiler; using Ryujinx.Ui; @@ -45,9 +45,9 @@ namespace Ryujinx Logger.PrintInfo(LogClass.Application, $"Ryujinx Version: {Version}"); - Logger.PrintInfo(LogClass.Application, $"Operating System: {SystemInfo.OsDescription}"); - Logger.PrintInfo(LogClass.Application, $"CPU: {SystemInfo.CpuName}"); - Logger.PrintInfo(LogClass.Application, $"Total RAM: {SystemInfo.RamSize}"); + Logger.PrintInfo(LogClass.Application, $"Operating System: {SystemInfo.Instance.OsDescription}"); + Logger.PrintInfo(LogClass.Application, $"CPU: {SystemInfo.Instance.CpuName}"); + Logger.PrintInfo(LogClass.Application, $"Total RAM: {SystemInfo.Instance.RamSizeInMB}"); string localConfigurationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json"); string globalBasePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Ryujinx");