Skip to content

Commit

Permalink
Fix Mythic performance issues + bugfixes
Browse files Browse the repository at this point in the history
  • Loading branch information
vapidinfinity committed May 1, 2024
1 parent 66894ed commit 9a0bf43
Show file tree
Hide file tree
Showing 12 changed files with 47 additions and 45 deletions.
12 changes: 8 additions & 4 deletions Mythic.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
6A1C6F422AEFD95900F89AE7 /* WineInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A1C6F412AEFD95900F89AE7 /* WineInterface.swift */; };
6A1C6F462AEFD9B100F89AE7 /* WineInterfaceExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A1C6F452AEFD9B100F89AE7 /* WineInterfaceExt.swift */; };
6A1ECF722B0CA0560010DC17 /* EventManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A1ECF712B0CA0560010DC17 /* EventManager.swift */; };
6A218EEF2BDFDB810023D4A2 /* OnboardingR2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A218EEE2BDFDB810023D4A2 /* OnboardingR2.swift */; };
6A34366E2B8D7F1200D35BCA /* Shimmer in Frameworks */ = {isa = PBXBuildFile; productRef = 6A34366D2B8D7F1200D35BCA /* Shimmer */; };
6A3578AF2BAAE0F900092D7F /* SubscriptedTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A3578AE2BAAE0F900092D7F /* SubscriptedTextView.swift */; };
6A371B562AE7A5E20054BF7A /* Installer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A371B552AE7A5E20054BF7A /* Installer.swift */; };
Expand Down Expand Up @@ -103,6 +104,7 @@
6A1C6F412AEFD95900F89AE7 /* WineInterface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WineInterface.swift; sourceTree = "<group>"; };
6A1C6F452AEFD9B100F89AE7 /* WineInterfaceExt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WineInterfaceExt.swift; sourceTree = "<group>"; };
6A1ECF712B0CA0560010DC17 /* EventManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EventManager.swift; sourceTree = "<group>"; };
6A218EEE2BDFDB810023D4A2 /* OnboardingR2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingR2.swift; sourceTree = "<group>"; };
6A3578AE2BAAE0F900092D7F /* SubscriptedTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptedTextView.swift; sourceTree = "<group>"; };
6A371B552AE7A5E20054BF7A /* Installer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Installer.swift; sourceTree = "<group>"; };
6A371B5A2AE7E93B0054BF7A /* Libraries.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Libraries.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -455,6 +457,7 @@
6AB474A92AACBCD000AB9C63 /* Views */ = {
isa = PBXGroup;
children = (
6A218EEE2BDFDB810023D4A2 /* OnboardingR2.swift */,
6A3578AD2BAAE0D300092D7F /* Extensions */,
6ADF5AB52B9877AF0041D04E /* GameListEvo */,
6AF0EB2B2AADE2530044C09C /* WebView.swift */,
Expand Down Expand Up @@ -713,6 +716,7 @@
6AE4A9A32B44682E0060D483 /* Lock.swift in Sources */,
6A1ECF722B0CA0560010DC17 /* EventManager.swift in Sources */,
6AA6CCE32AD52B2600F664A5 /* LegendaryInterface.swift in Sources */,
6A218EEF2BDFDB810023D4A2 /* OnboardingR2.swift in Sources */,
6AC3E1892B374D2E000EB765 /* VariableManager.swift in Sources */,
6A008E9B2BC0AF350039AEF3 /* DownloadsEvo.swift in Sources */,
6A00F20B2AC5F8730054858A /* Auth.swift in Sources */,
Expand Down Expand Up @@ -865,7 +869,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 2599;
CURRENT_PROJECT_VERSION = 2607;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_ASSET_PATHS = "\"Mythic/Preview Content\"";
DEVELOPMENT_TEAM = 67ZBY275P8;
Expand All @@ -883,7 +887,7 @@
"@executable_path/../Frameworks",
);
LIBRARY_SEARCH_PATHS = "";
MARKETING_VERSION = 0.1.0;
MARKETING_VERSION = 0.0.0;
PRODUCT_BUNDLE_IDENTIFIER = xyz.blackxfiied.Mythic;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand All @@ -904,7 +908,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 2599;
CURRENT_PROJECT_VERSION = 2607;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_ASSET_PATHS = "\"Mythic/Preview Content\"";
DEVELOPMENT_TEAM = 67ZBY275P8;
Expand All @@ -922,7 +926,7 @@
"@executable_path/../Frameworks",
);
LIBRARY_SEARCH_PATHS = "";
MARKETING_VERSION = 0.1.0;
MARKETING_VERSION = 0.0.0;
PRODUCT_BUNDLE_IDENTIFIER = xyz.blackxfiied.Mythic;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"originHash" : "90d4e1ca661bb2c2485f9e9402d06ff3e38745c75cd64fec431f020402f4048b",
"pins" : [
{
"identity" : "bluesocket",
Expand All @@ -14,8 +15,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/Lakr233/ColorfulX",
"state" : {
"revision" : "24dea76cbd7dbcc1a31da6f2213264d449e7687b",
"version" : "2.4.4"
"revision" : "24bbc2f4b27c853f2be5ebed144252d9bcd27ee0",
"version" : "2.4.5"
}
},
{
Expand All @@ -41,8 +42,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/sparkle-project/Sparkle",
"state" : {
"revision" : "47d3d90aee3c52b6f61d04ceae426e607df62347",
"version" : "2.5.2"
"revision" : "0a4caaf7a81eea2cece651ef4b17331fa0634dff",
"version" : "2.6.0"
}
},
{
Expand Down Expand Up @@ -77,8 +78,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/SwiftyJSON/SwiftyJSON",
"state" : {
"revision" : "b3dcd7dbd0d488e1a7077cb33b00f2083e382f07",
"version" : "5.0.1"
"revision" : "af76cf3ef710b6ca5f8c05f3a31307d44a3c5828",
"version" : "5.0.2"
}
},
{
Expand All @@ -95,10 +96,10 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/weichsel/ZIPFoundation",
"state" : {
"revision" : "b979e8b52c7ae7f3f39fa0182e738e9e7257eb78",
"version" : "0.9.18"
"revision" : "02b6abe5f6eef7e3cbd5f247c5cc24e246efcfe0",
"version" : "0.9.19"
}
}
],
"version" : 2
"version" : 3
}
23 changes: 11 additions & 12 deletions Mythic/Controllers/Legendary/LegendaryInterface.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class Legendary {
private static let _runningCommandsQueue = DispatchQueue(label: "legendaryRunningCommands", attributes: .concurrent)

/// Dictionary to monitor running commands and their identifiers.
private static var runningCommands: [String: Process] {
static var runningCommands: [String: Process] {
get {
_runningCommandsQueue.sync {
return _runningCommands
Expand Down Expand Up @@ -76,7 +76,7 @@ class Legendary {
It handles the process's standard input, standard output, and standard error, as well as any interactions based on the output provided by the `input` closure.
*/
@available(*, message: "Revamped recently")
static func command(arguments args: [String], identifier: String, waits: Bool = true, input: ((String) -> String?)? = nil, environment: [String: String]? = nil, completion: @escaping (CommandOutput, Process) -> Void) async throws {
static func command(arguments args: [String], identifier: String, waits: Bool = true, input: ((String) -> String?)? = nil, environment: [String: String]? = nil, completion: @escaping (CommandOutput) -> Void) async throws {
let task = Process()
task.executableURL = URL(filePath: Bundle.main.path(forResource: "legendary/cli", ofType: nil)!)

Expand Down Expand Up @@ -105,7 +105,7 @@ class Legendary {
stdin.fileHandleForWriting.write(data)
}
output.stderr = availableOutput
completion(output, task) // ⚠️ FIXME: critical performance issues
completion(output) // ⚠️ FIXME: critical performance issues
}

stdout.fileHandleForReading.readabilityHandler = { [stdin, output] handle in
Expand All @@ -115,12 +115,11 @@ class Legendary {
stdin.fileHandleForWriting.write(data)
}
output.stdout = availableOutput
completion(output, task) // ⚠️ FIXME: critical performance issues
completion(output) // ⚠️ FIXME: critical performance issues
}

task.terminationHandler = { [stdin] _ in
task.terminationHandler = { _ in
runningCommands.removeValue(forKey: identifier)
try? stdin.fileHandleForWriting.close()
}

log.debug("[command] executing command [\(identifier)]: `\(terminalFormat)`")
Expand Down Expand Up @@ -236,7 +235,7 @@ class Legendary {
let diskSpeedRegex: Regex = try! .init(#"\+ Disk\s+- (?<write>[\d.]+) \w+/\w+ \(write\) / (?<read>[\d.]+) \w+/\w+ \(read\)"#)
// swiftlint:enable force_try

try await command(arguments: argBuilder, identifier: "install") { output, _ in
try await command(arguments: argBuilder, identifier: "install") { output in
// MARK: stderr (installation) handling
// TODO: ONLY APPEND RAW DATA HERE, MAY SAVE ON PERFORMANCE

Expand Down Expand Up @@ -298,7 +297,7 @@ class Legendary {
try await command(
arguments: ["move", game.id, newPath, "--skip-move"],
identifier: "move"
) { _, _ in }
) { _ in }

try await notifications.add(
.init(identifier: UUID().uuidString,
Expand All @@ -324,7 +323,7 @@ class Legendary {
arguments: ["auth", "--code", authKey],
identifier: "signin",
waits: true
) { output, _ in
) { output in
isLoggedIn = (isLoggedIn == true ? true : output.stderr.contains("Successfully logged in as"))
}

Expand Down Expand Up @@ -373,7 +372,7 @@ class Legendary {
environmentVariables["WINEMSYNC"] = bottle.settings.msync ? "1" : "0"
}

try await command(arguments: arguments, identifier: "launch\(game.id)") { _, _ in }
try await command(arguments: arguments, identifier: "launch\(game.id)") { _ in }

DispatchQueue.main.async {
GameOperation.shared.launching = nil
Expand Down Expand Up @@ -595,11 +594,11 @@ class Legendary {

if let metadataContents = try? files.contentsOfDirectory(atPath: metadata), !metadataContents.isEmpty {
Task(priority: .background) {
try? await command(arguments: ["status"], identifier: "refreshMetadata") { _, _ in }
try? await command(arguments: ["status"], identifier: "refreshMetadata") { _ in }
}
} else {
Task.sync(priority: .high) { // called during onboarding for speed
try? await command(arguments: ["status"], identifier: "refreshMetadata") { _, _ in }
try? await command(arguments: ["status"], identifier: "refreshMetadata") { _ in }
}
}

Expand Down
2 changes: 1 addition & 1 deletion Mythic/Controllers/LocalGames/LocalGames.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class LocalGames {
"MTL_HUD_ENABLED": bottle.settings.metalHUD ? "1" : "0",
"WINEMSYNC": bottle.settings.msync ? "1" : "0"
]
) { _, _/* task */ in } // TODO: pass task over through launch
) { _ in } // TODO: pass task over through launch

case .none: do { /* TODO: Error */ }
}
Expand Down
20 changes: 9 additions & 11 deletions Mythic/Controllers/Wine/WineInterface.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class Wine { // TODO: https://forum.winehq.org/viewtopic.php?t=15416
private static let _runningCommandsQueue = DispatchQueue(label: "legendaryRunningCommands", attributes: .concurrent)

/// Dictionary to monitor running commands and their identifiers.
private static var runningCommands: [String: Process] {
static var runningCommands: [String: Process] {
get {
var result: [String: Process]?
_runningCommandsQueue.sync {
Expand Down Expand Up @@ -152,7 +152,7 @@ class Wine { // TODO: https://forum.winehq.org/viewtopic.php?t=15416
It handles the process's standard input, standard output, and standard error, as well as any interactions based on the output provided by the `input` closure.
*/
@available(*, message: "Revamped recently")
static func command(arguments args: [String], identifier: String, waits: Bool = true, bottleURL: URL?, input: ((String) -> String?)? = nil, environment: [String: String]? = nil, completion: @escaping (Legendary.CommandOutput, Process) -> Void) async throws {
static func command(arguments args: [String], identifier: String, waits: Bool = true, bottleURL: URL?, input: ((String) -> String?)? = nil, environment: [String: String]? = nil, completion: @escaping (Legendary.CommandOutput) -> Void) async throws {
let task = Process()
task.executableURL = Libraries.directory.appending(path: "Wine/bin/wine64")

Expand Down Expand Up @@ -189,7 +189,7 @@ class Wine { // TODO: https://forum.winehq.org/viewtopic.php?t=15416
stdin.fileHandleForWriting.write(data)
}
output.stderr = availableOutput
completion(output, task) // ⚠️ FIXME: critical performance issues
completion(output)
}

stdout.fileHandleForReading.readabilityHandler = { [stdin, output] handle in
Expand All @@ -199,12 +199,11 @@ class Wine { // TODO: https://forum.winehq.org/viewtopic.php?t=15416
stdin.fileHandleForWriting.write(data)
}
output.stdout = availableOutput
completion(output, task) // ⚠️ FIXME: critical performance issues
completion(output)
}

task.terminationHandler = { [stdin] _ in
task.terminationHandler = { _ in
runningCommands.removeValue(forKey: identifier)
try? stdin.fileHandleForWriting.close()
}

log.debug("[command] executing command [\(identifier)]: `\(terminalFormat)`")
Expand Down Expand Up @@ -275,7 +274,7 @@ class Wine { // TODO: https://forum.winehq.org/viewtopic.php?t=15416

do {
let newBottle: Bottle = .init(url: bottleURL, settings: settings, busy: false)
try await command(arguments: ["wineboot"], identifier: "wineboot", bottleURL: bottleURL) { output, _ in
try await command(arguments: ["wineboot"], identifier: "wineboot", bottleURL: bottleURL) { output in
// swiftlint:disable:next force_try
if output.stderr.contains(try! Regex(#"wine: configuration in (.*?) has been updated\."#)) {
allBottles?[name] = newBottle
Expand Down Expand Up @@ -368,23 +367,22 @@ class Wine { // TODO: https://forum.winehq.org/viewtopic.php?t=15416
private static func addRegistryKey(bottleURL: URL, key: String, name: String, data: String, type: RegistryType) async throws {
guard bottleExists(bottleURL: bottleURL) else { throw BottleDoesNotExistError() }

try await command(arguments: ["reg", "add", key, "-v", name, "-t", type.rawValue, "-d", data, "-f"], identifier: "regadd", bottleURL: bottleURL) { _, _ in
try await command(arguments: ["reg", "add", key, "-v", name, "-t", type.rawValue, "-d", data, "-f"], identifier: "regadd", bottleURL: bottleURL) { _ in
// FIXME: errors aren't handled
}
}

// MARK: - Query Registry Key Method
private static func queryRegistryKey(bottleURL: URL, key: String, name: String, type: RegistryType, completion: @escaping (Result<String, Error>) -> Void) async {
do {

try await command(arguments: ["reg", "query", key, "-v", name], identifier: "regquery", bottleURL: bottleURL) { output, task in
try await command(arguments: ["reg", "query", key, "-v", name], identifier: "regquery", bottleURL: bottleURL) { output in
if output.stdout.contains(type.rawValue) {
let array = output.stdout.split(omittingEmptySubsequences: true, whereSeparator: \.isWhitespace)
if !array.isEmpty {
completion(.success(String(array.last!)))
} else {
completion(.failure(UnableToQueryRegistyError()))
task.suspend(); return
runningCommands["regquery"]?.terminate(); return
}
}
// FIXME: outside errors aren't handled
Expand Down
2 changes: 1 addition & 1 deletion Mythic/Deprecated/Views/Auth.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ struct AuthView: View {
}

do {
try await Legendary.command(arguments: ["auth", "--code", code], identifier: "signin") { output, _ in
try await Legendary.command(arguments: ["auth", "--code", code], identifier: "signin") { output in
if output.stderr.contains("ERROR: Login attempt failed") {
displayError(); return
}
Expand Down
2 changes: 1 addition & 1 deletion Mythic/Views/BottleList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ struct BottleListView: View {

Button("Launch Configurator") {
Task {
try await Wine.command(arguments: ["winecfg"], identifier: "winecfg", bottleURL: bottles[selectedBottleName]!.url) {_, _ in }
try await Wine.command(arguments: ["winecfg"], identifier: "winecfg", bottleURL: bottles[selectedBottleName]!.url) { _ in }
}
}
.disabled(configuratorActive)
Expand Down
4 changes: 2 additions & 2 deletions Mythic/Views/GameListEvo/InstallGameView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ struct InstallViewEvo: View {
.task(priority: .userInitiated) {
fetchingOptionalPacks = true

try? await Legendary.command(arguments: ["install", game.id], identifier: "parseOptionalPacks") { output, task in
try? await Legendary.command(arguments: ["install", game.id], identifier: "parseOptionalPacks") { output in
if output.stdout.contains("Do you wish to install") || output.stdout.contains("Additional packs") {
task.terminate() // kill is preferred
Legendary.runningCommands["parseOptionalPacks"]?.terminate(); return
}

if output.stdout.contains("The following optional packs are available") { // hate hardcoding
Expand Down
2 changes: 1 addition & 1 deletion Mythic/Views/GameListEvo/UninstallGameView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ struct UninstallViewEvo: View {
keepFiles ? "--keep-files" : nil,
skipUninstaller ? "--skip-uninstaller" : nil,
game.id
] .compactMap { $0 }, identifier: "uninstall") { output, _ in
] .compactMap { $0 }, identifier: "uninstall") { output in
guard output.stderr.contains("ERROR:") else { return }
let errorLine = output.stderr.trimmingPrefix(try! Regex(#"\[(.*?)\]"#)).trimmingPrefix("ERROR: ")
// swiftlint:disable:previous force_try
Expand Down
2 changes: 1 addition & 1 deletion Mythic/Views/Navigation/Accounts.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ struct AccountsView: View {
message: .init("This will sign you out of the account \"\(Legendary.whoAmI())\"."),
primaryButton: .destructive(.init("Sign Out")) {
Task.sync(priority: .high) {
try? await Legendary.command(arguments: ["auth", "--delete"], identifier: "signout") { _, _ in }
try? await Legendary.command(arguments: ["auth", "--delete"], identifier: "signout") { _ in }
}

signedIn = Legendary.signedIn()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ extension LibraryView.GameImportView {
"--platform", platform == .macOS ? "Mac" : platform == .windows ? "Windows" : "Mac",
game.id,
path
] .compactMap { $0 }, identifier: "epicImport") { output, _ in
] .compactMap { $0 }, identifier: "epicImport") { output in
if output.stderr.contains("INFO: Game \"\(game.title)\" has been imported.") {
isPresented = false
isGameListRefreshCalled = true
Expand Down
Loading

0 comments on commit 9a0bf43

Please sign in to comment.