Skip to content

Commit 149c798

Browse files
committed
Bug fixes
1 parent 88c4924 commit 149c798

File tree

3 files changed

+67
-48
lines changed

3 files changed

+67
-48
lines changed

Core/Package.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,11 @@ let package = Package(
7373
isRelative: true,
7474
isEnabled: false,
7575
),
76-
.package(
77-
path: "../../TestingLibraries/MachOSwiftSection",
78-
isRelative: true,
79-
isEnabled: true,
80-
),
76+
// .package(
77+
// path: "../../TestingLibraries/MachOSwiftSection",
78+
// isRelative: true,
79+
// isEnabled: true,
80+
// ),
8181
remote: .package(
8282
url: "https://github.com/MxIris-Reverse-Engineering/MachOSwiftSection",
8383
// from: "0.6.0"

Core/Sources/RuntimeViewerCore/RuntimeEngine.swift

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import ClassDumpRuntime
55
import FoundationToolbox
66
import RuntimeViewerCommunication
77

8-
public final actor RuntimeEngine {
8+
public actor RuntimeEngine {
99
public static let shared = RuntimeEngine()
1010

1111
private static let logger = Logger(label: "RuntimeEngine")
@@ -15,7 +15,7 @@ public final actor RuntimeEngine {
1515
@Published private var protocolList: [String] = []
1616

1717
@Published private var protocolToImage: [String: String] = [:]
18-
18+
1919
@Published private var imageToProtocols: [String: [String]] = [:]
2020

2121
@Published public private(set) var imageList: [String] = []
@@ -24,6 +24,10 @@ public final actor RuntimeEngine {
2424

2525
@Published public private(set) var imageToSwiftSections: [String: RuntimeSwiftSections] = [:]
2626

27+
private let reloadDataSubject = PassthroughSubject<Void, Never>()
28+
29+
public var reloadDataPublisher: some Publisher<Void, Never> { reloadDataSubject.eraseToAnyPublisher() }
30+
2731
fileprivate enum CommandNames: String, CaseIterable {
2832
case classList
2933
case protocolList
@@ -43,6 +47,7 @@ public final actor RuntimeEngine {
4347
case observeRuntime
4448
case interfaceForRuntimeObjectInImageWithOptions
4549
case namesOfKindInImage
50+
case reloadData
4651

4752
var commandName: String { "com.JH.RuntimeViewerCore.RuntimeEngine.\(rawValue)" }
4853
}
@@ -137,13 +142,20 @@ public final actor RuntimeEngine {
137142
try await perform(self, response)
138143
}
139144
}
145+
146+
private func setMessageHandlerBinding(forName name: CommandNames, perform: @escaping (isolated RuntimeEngine) async throws -> Void) {
147+
connection?.setMessageHandler(name: name.commandName) { [weak self] in
148+
guard let self else { return }
149+
try await perform(self)
150+
}
151+
}
140152

141153
public func reloadData() {
142154
Self.logger.debug("Start reload")
143155
classList = ObjCRuntime.classNames()
144156
protocolList = ObjCRuntime.protocolNames()
145157
imageList = DyldUtilities.imageNames()
146-
imageNodes = [DyldUtilities.dyldSharedCacheImageRootNode, DyldUtilities.otherImageRootNode]
158+
// imageNodes = [DyldUtilities.dyldSharedCacheImageRootNode, DyldUtilities.otherImageRootNode]
147159
Self.logger.debug("End reload")
148160
sendRemoteDataIfNeeded()
149161
}
@@ -157,25 +169,10 @@ public final actor RuntimeEngine {
157169
) ?? ([:], [:])
158170
self.protocolToImage = protocolToImage
159171
self.imageToProtocols = imageToProtocols
160-
Task.detached {
161-
await self.setImageNodes([DyldUtilities.dyldSharedCacheImageRootNode, DyldUtilities.otherImageRootNode])
162-
}
163172

164-
// Task.detached { [self] in
165-
// await withTaskGroup { group in
166-
// for imagePath in await imageList {
167-
// group.addTask {
168-
// do {
169-
// let section = try RuntimeSwiftSections(imagePath: imagePath)
170-
// await self.setSwiftSection(section, forImage: imagePath)
171-
// } catch {
172-
// print(imagePath)
173-
// }
174-
// }
175-
// }
176-
// await group.waitForAll()
177-
// }
178-
// }
173+
await Task.detached {
174+
await self.setImageNodes([DyldUtilities.dyldSharedCacheImageRootNode, DyldUtilities.otherImageRootNode])
175+
}.value
179176

180177
shouldReload
181178
.debounce(for: .milliseconds(15), scheduler: DispatchQueue.main)
@@ -325,7 +322,7 @@ public final actor RuntimeEngine {
325322
}
326323
}
327324
}
328-
325+
329326
private func getOrCreateSwiftSections(for imagePath: String) async throws -> RuntimeSwiftSections {
330327
if let swiftSections = imageToSwiftSections[imagePath] {
331328
return swiftSections
@@ -367,8 +364,10 @@ extension RuntimeEngine {
367364
let section = try RuntimeSwiftSections(imagePath: path)
368365
await setSwiftSection(section, forImage: path)
369366
reloadData()
367+
reloadDataSubject.send(())
370368
} remote: {
371369
try await $0.sendMessage(name: .loadImage, request: path)
370+
reloadDataSubject.send(())
372371
}
373372
}
374373

RuntimeViewerPackages/Sources/RuntimeViewerApplication/Sidebar/SidebarImageViewModel.swift

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -34,26 +34,6 @@ public class SidebarImageViewModel: ViewModel<SidebarRoute> {
3434

3535
Task {
3636
do {
37-
let loadState: RuntimeImageLoadState = try await runtimeEngine.isImageLoaded(path: imagePath) ? .loaded : .notLoaded
38-
let objcClassNames = try await runtimeEngine.names(of: .objc(.class), in: imagePath)
39-
let objcProtocolNames = try await runtimeEngine.names(of: .objc(.protocol), in: imagePath)
40-
let swiftClassNames = try await runtimeEngine.names(of: .swift(.class), in: imagePath)
41-
let swiftProtocolNames = try await runtimeEngine.names(of: .swift(.protocol), in: imagePath)
42-
let swiftEnumNames = try await runtimeEngine.names(of: .swift(.enum), in: imagePath)
43-
let swiftStructNames = try await runtimeEngine.names(of: .swift(.struct), in: imagePath)
44-
await MainActor.run {
45-
let searchString = ""
46-
let searchScope: RuntimeTypeSearchScope = .all
47-
48-
self.searchString = searchString
49-
self.searchScope = searchScope
50-
51-
self.runtimeObjects = objcClassNames + objcProtocolNames + swiftEnumNames + swiftStructNames + swiftClassNames + swiftProtocolNames
52-
self.filteredRuntimeObjects = self.runtimeObjects.sorted()
53-
54-
self.loadState = loadState
55-
}
56-
5737
let debouncedSearch = $searchString
5838
.debounce(.milliseconds(80), scheduler: MainScheduler.instance)
5939
.asObservable()
@@ -69,6 +49,16 @@ public class SidebarImageViewModel: ViewModel<SidebarRoute> {
6949
.bind(to: $filteredRuntimeObjects)
7050
.disposed(by: rx.disposeBag)
7151

52+
await runtimeEngine.reloadDataPublisher
53+
.asObservable()
54+
.subscribeOnNext { [weak self] in
55+
guard let self else { return }
56+
Task {
57+
try await self.reloadData()
58+
}
59+
}
60+
.disposed(by: rx.disposeBag)
61+
7262
await runtimeEngine.$imageList
7363
.asObservable()
7464
.flatMap { [unowned self] imageList in
@@ -80,8 +70,10 @@ public class SidebarImageViewModel: ViewModel<SidebarRoute> {
8070
.observeOnMainScheduler()
8171
.bind(to: $loadState)
8272
.disposed(by: rx.disposeBag)
73+
74+
try await reloadData()
8375
} catch {
84-
loadState = .loadError(error)
76+
self.loadState = .loadError(error)
8577
print(error)
8678
}
8779
}
@@ -109,6 +101,34 @@ public class SidebarImageViewModel: ViewModel<SidebarRoute> {
109101
public let windowSubtitle: Signal<String>
110102
}
111103

104+
private func reloadData() async throws {
105+
let loadState: RuntimeImageLoadState = try await runtimeEngine.isImageLoaded(path: imagePath) ? .loaded : .notLoaded
106+
if case .notLoaded = loadState {
107+
await MainActor.run {
108+
self.loadState = loadState
109+
}
110+
return
111+
}
112+
let objcClassNames = try await runtimeEngine.names(of: .objc(.class), in: imagePath)
113+
let objcProtocolNames = try await runtimeEngine.names(of: .objc(.protocol), in: imagePath)
114+
let swiftClassNames = try await runtimeEngine.names(of: .swift(.class), in: imagePath)
115+
let swiftProtocolNames = try await runtimeEngine.names(of: .swift(.protocol), in: imagePath)
116+
let swiftEnumNames = try await runtimeEngine.names(of: .swift(.enum), in: imagePath)
117+
let swiftStructNames = try await runtimeEngine.names(of: .swift(.struct), in: imagePath)
118+
await MainActor.run {
119+
let searchString = ""
120+
let searchScope: RuntimeTypeSearchScope = .all
121+
122+
self.searchString = searchString
123+
self.searchScope = searchScope
124+
125+
self.runtimeObjects = objcClassNames + objcProtocolNames + swiftEnumNames + swiftStructNames + swiftClassNames + swiftProtocolNames
126+
self.filteredRuntimeObjects = self.runtimeObjects.sorted()
127+
128+
self.loadState = loadState
129+
}
130+
}
131+
112132
@MainActor
113133
public func transform(_ input: Input) -> Output {
114134
input.searchString.emit(to: $searchString).disposed(by: rx.disposeBag)

0 commit comments

Comments
 (0)