Skip to content

Commit 6a11d06

Browse files
committed
Add protocol support to ImageClassPicker
Rename to ImageRuntimeObjectsView
1 parent 5e47ed5 commit 6a11d06

File tree

3 files changed

+49
-26
lines changed

3 files changed

+49
-26
lines changed

HeaderViewer.xcodeproj/project.pbxproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
FA9687EF2B833D5F00123476 /* RuntimeObjectRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA9687EE2B833D5F00123476 /* RuntimeObjectRow.swift */; };
1616
FA9687F12B8366B500123476 /* NamedNodeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA9687F02B8366B400123476 /* NamedNodeView.swift */; };
1717
FA9687F32B8433B900123476 /* SemanticStringView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA9687F22B8433B900123476 /* SemanticStringView.swift */; };
18-
FAAA8C0F2B85788700BD85B4 /* ImageClassPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAAA8C0E2B85788700BD85B4 /* ImageClassPicker.swift */; };
18+
FAAA8C0F2B85788700BD85B4 /* ImageRuntimeObjectsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAAA8C0E2B85788700BD85B4 /* ImageRuntimeObjectsView.swift */; };
1919
FAAA8C132B857A1300BD85B4 /* RuntimeListings.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAAA8C122B857A1300BD85B4 /* RuntimeListings.swift */; };
2020
FAAA8C172B8B072100BD85B4 /* ListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAAA8C162B8B072100BD85B4 /* ListView.swift */; };
2121
FAD661F82B81D1210000D2A6 /* HeaderViewerApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAD661F72B81D1210000D2A6 /* HeaderViewerApp.swift */; };
@@ -82,7 +82,7 @@
8282
FA9687EE2B833D5F00123476 /* RuntimeObjectRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuntimeObjectRow.swift; sourceTree = "<group>"; };
8383
FA9687F02B8366B400123476 /* NamedNodeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NamedNodeView.swift; sourceTree = "<group>"; };
8484
FA9687F22B8433B900123476 /* SemanticStringView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SemanticStringView.swift; sourceTree = "<group>"; };
85-
FAAA8C0E2B85788700BD85B4 /* ImageClassPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageClassPicker.swift; sourceTree = "<group>"; };
85+
FAAA8C0E2B85788700BD85B4 /* ImageRuntimeObjectsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageRuntimeObjectsView.swift; sourceTree = "<group>"; };
8686
FAAA8C122B857A1300BD85B4 /* RuntimeListings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuntimeListings.swift; sourceTree = "<group>"; };
8787
FAAA8C162B8B072100BD85B4 /* ListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListView.swift; sourceTree = "<group>"; };
8888
FAD661F42B81D1210000D2A6 /* HeaderViewer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HeaderViewer.app; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -149,7 +149,7 @@
149149
FA6BEDCA2BD5941500D20C6F /* RuntimeObjectsView.swift */,
150150
FAAA8C162B8B072100BD85B4 /* ListView.swift */,
151151
FAAA8C122B857A1300BD85B4 /* RuntimeListings.swift */,
152-
FAAA8C0E2B85788700BD85B4 /* ImageClassPicker.swift */,
152+
FAAA8C0E2B85788700BD85B4 /* ImageRuntimeObjectsView.swift */,
153153
FA9687F02B8366B400123476 /* NamedNodeView.swift */,
154154
FA9687E82B8338E100123476 /* NamedNode.swift */,
155155
FA9687EA2B833C1700123476 /* RuntimeObjectType.swift */,
@@ -312,7 +312,7 @@
312312
buildActionMask = 2147483647;
313313
files = (
314314
FA6BEDCB2BD5941500D20C6F /* RuntimeObjectsView.swift in Sources */,
315-
FAAA8C0F2B85788700BD85B4 /* ImageClassPicker.swift in Sources */,
315+
FAAA8C0F2B85788700BD85B4 /* ImageRuntimeObjectsView.swift in Sources */,
316316
FA9687E92B8338E100123476 /* NamedNode.swift in Sources */,
317317
FA9687F32B8433B900123476 /* SemanticStringView.swift in Sources */,
318318
FAAA8C132B857A1300BD85B4 /* RuntimeListings.swift in Sources */,

HeaderViewer/ContentView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ struct ContentRootView: View {
4949
}
5050
.navigationDestination(for: NamedNode.self) { namedNode in
5151
if namedNode.isLeaf {
52-
ImageClassPicker(namedNode: namedNode, selection: $selectedObject)
52+
ImageRuntimeObjectsView(namedNode: namedNode, selection: $selectedObject)
5353
} else {
5454
NamedNodeView(node: namedNode)
5555
.environmentObject(RuntimeListings.shared)

HeaderViewer/ImageClassPicker.swift renamed to HeaderViewer/ImageRuntimeObjectsView.swift

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// ImageClassPicker.swift
2+
// ImageRuntimeObjectsView.swift
33
// HeaderViewer
44
//
55
// Created by Leptos on 2/20/24.
@@ -15,7 +15,7 @@ private enum ImageLoadState {
1515
case loadError(Error)
1616
}
1717

18-
private class ImageClassPickerModel: ObservableObject {
18+
private class ImageRuntimeObjectsViewModel: ObservableObject {
1919
let namedNode: NamedNode
2020

2121
let imagePath: String
@@ -24,13 +24,21 @@ private class ImageClassPickerModel: ObservableObject {
2424
let runtimeListings: RuntimeListings = .shared
2525

2626
@Published var searchString: String
27+
@Published var searchScope: RuntimeTypeSearchScope
2728

2829
@Published private(set) var classNames: [String] // not filtered
30+
@Published private(set) var protocolNames: [String] // not filtered
2931
@Published private(set) var runtimeObjects: [RuntimeObjectType] // filtered based on search
3032
@Published private(set) var loadState: ImageLoadState
3133

32-
private static func runtimeObjectsFor(classNames: [String], searchString: String) -> [RuntimeObjectType] {
33-
let ret: [RuntimeObjectType] = classNames.map { .class(named: $0) }
34+
private static func runtimeObjectsFor(classNames: [String], protocolNames: [String], searchString: String, searchScope: RuntimeTypeSearchScope) -> [RuntimeObjectType] {
35+
var ret: [RuntimeObjectType] = []
36+
if searchScope.includesClasses {
37+
ret += classNames.map { .class(named: $0) }
38+
}
39+
if searchScope.includesProtocols {
40+
ret += protocolNames.map { .protocol(named: $0) }
41+
}
3442
if searchString.isEmpty { return ret }
3543
return ret.filter { $0.name.localizedCaseInsensitiveContains(searchString) }
3644
}
@@ -43,12 +51,20 @@ private class ImageClassPickerModel: ObservableObject {
4351
self.imageName = namedNode.name
4452

4553
let classNames = CDUtilities.classNamesIn(image: imagePath)
54+
let protocolNames = runtimeListings.imageToProtocols[CDUtilities.patchImagePathForDyld(imagePath)] ?? []
4655
self.classNames = classNames
56+
self.protocolNames = protocolNames
4757

4858
let searchString = ""
59+
let searchScope: RuntimeTypeSearchScope = .all
60+
4961
self.searchString = searchString
62+
self.searchScope = searchScope
5063

51-
self.runtimeObjects = Self.runtimeObjectsFor(classNames: classNames, searchString: searchString)
64+
self.runtimeObjects = Self.runtimeObjectsFor(
65+
classNames: classNames, protocolNames: protocolNames,
66+
searchString: searchString, searchScope: searchScope
67+
)
5268

5369
self.loadState = runtimeListings.isImageLoaded(path: imagePath) ? .loaded : .notLoaded
5470

@@ -58,13 +74,23 @@ private class ImageClassPickerModel: ObservableObject {
5874
}
5975
.assign(to: &$classNames)
6076

77+
runtimeListings.$imageToProtocols
78+
.map { imageToProtocols in
79+
imageToProtocols[CDUtilities.patchImagePathForDyld(imagePath)] ?? []
80+
}
81+
.assign(to: &$protocolNames)
82+
6183
let debouncedSearch = $searchString
6284
.debounce(for: 0.08, scheduler: RunLoop.main)
6385

64-
$classNames.combineLatest(debouncedSearch) { classNames, searchString in
65-
Self.runtimeObjectsFor(classNames: classNames, searchString: searchString)
66-
}
67-
.assign(to: &$runtimeObjects)
86+
$searchScope
87+
.combineLatest(debouncedSearch, $classNames, $protocolNames) {
88+
Self.runtimeObjectsFor(
89+
classNames: $2, protocolNames: $3,
90+
searchString: $1, searchScope: $0
91+
)
92+
}
93+
.assign(to: &$runtimeObjects)
6894

6995
runtimeListings.$imageList
7096
.map { imageList in
@@ -88,12 +114,12 @@ private class ImageClassPickerModel: ObservableObject {
88114
}
89115
}
90116

91-
struct ImageClassPicker: View {
92-
@StateObject private var viewModel: ImageClassPickerModel
117+
struct ImageRuntimeObjectsView: View {
118+
@StateObject private var viewModel: ImageRuntimeObjectsViewModel
93119
@Binding private var selection: RuntimeObjectType?
94120

95121
init(namedNode: NamedNode, selection: Binding<RuntimeObjectType?>) {
96-
_viewModel = StateObject(wrappedValue: ImageClassPickerModel(namedNode: namedNode))
122+
_viewModel = StateObject(wrappedValue: ImageRuntimeObjectsViewModel(namedNode: namedNode))
97123
_selection = selection
98124
}
99125

@@ -115,19 +141,16 @@ struct ImageClassPicker: View {
115141
ProgressView()
116142
.scenePadding()
117143
case .loaded:
118-
if viewModel.classNames.isEmpty {
144+
if viewModel.classNames.isEmpty && viewModel.protocolNames.isEmpty {
119145
StatusView {
120-
Text("\(viewModel.imageName) is loaded however does not appear to contain any classes")
146+
Text("\(viewModel.imageName) is loaded however does not appear to contain any classes or protocols")
121147
.padding(.top)
122148
}
123149
} else {
124-
let runtimeObjects = viewModel.runtimeObjects
125-
ListView(runtimeObjects, selection: $selection) { runtimeObject in
126-
RuntimeObjectRow(type: runtimeObject)
127-
}
128-
.id(runtimeObjects) // don't try to diff the List
129-
.searchable(text: $viewModel.searchString)
130-
.autocorrectionDisabled() // turn of auto-correct for the search field
150+
RuntimeObjectsList(
151+
runtimeObjects: viewModel.runtimeObjects, selectedObject: $selection,
152+
searchString: $viewModel.searchString, searchScope: $viewModel.searchScope
153+
)
131154
}
132155
case .loadError(let error):
133156
StatusView {

0 commit comments

Comments
 (0)