@@ -21,16 +21,13 @@ class ViewController: NSViewController {
2121 @IBOutlet weak var statusTextField : NSTextField !
2222 @IBOutlet weak var tableView : NSTableView !
2323 @IBOutlet weak var tableViewContainerView : NSScrollView !
24-
25- fileprivate var dataSource : [ CompileMeasure ] = [ ]
26- fileprivate var filteredData : [ CompileMeasure ] ?
24+
25+ fileprivate let dataSource = ViewControllerDataSource ( )
2726
2827 private var currentKey : String ?
2928 private var nextDatabase : XcodeDatabase ?
3029
3130 private var processor = LogProcessor ( )
32- private var perFunctionTimes : [ CompileMeasure ] = [ ]
33- private var perFileTimes : [ CompileMeasure ] = [ ]
3431
3532 var processingState : ProcessingState = . waiting {
3633 didSet {
@@ -48,7 +45,10 @@ class ViewController: NSViewController {
4845 buildManager. delegate = self
4946 projectSelection. delegate = self
5047 projectSelection. listFolders ( )
51-
48+
49+ tableView. tableColumns [ 0 ] . sortDescriptorPrototype = NSSortDescriptor ( key: CompileMeasure . Order. time. rawValue, ascending: true )
50+ tableView. tableColumns [ 1 ] . sortDescriptorPrototype = NSSortDescriptor ( key: CompileMeasure . Order. filename. rawValue, ascending: true )
51+
5252 NotificationCenter . default. addObserver ( self , selector: #selector( windowWillClose ( notification: ) ) , name: NSWindow . willCloseNotification, object: nil )
5353 }
5454
@@ -99,21 +99,6 @@ class ViewController: NSViewController {
9999 }
100100 }
101101
102- func aggregateTimesByFile( _ functionTimes: [ CompileMeasure ] ) -> [ CompileMeasure ] {
103- var fileTimes : [ String : CompileMeasure ] = [ : ]
104-
105- for measure in functionTimes {
106- if var fileMeasure = fileTimes [ measure. path] {
107- fileMeasure. time += measure. time
108- fileTimes [ measure. path] = fileMeasure
109- } else {
110- let newFileMeasure = CompileMeasure ( rawPath: measure. path, time: measure. time)
111- fileTimes [ measure. path] = newFileMeasure
112- }
113- }
114- return Array ( fileTimes. values) . sorted { $0. time > $1. time }
115- }
116-
117102 func updateViewForState( ) {
118103 switch processingState {
119104 case . processing:
@@ -151,7 +136,7 @@ class ViewController: NSViewController {
151136 // MARK: Actions
152137
153138 @IBAction func perFileCheckboxClicked( _ sender: NSButton ) {
154- dataSource = sender. state. rawValue == 0 ? perFunctionTimes : perFileTimes
139+ dataSource. aggregateByFile = ( sender. state. rawValue == 1 )
155140 tableView. reloadData ( )
156141 }
157142
@@ -179,7 +164,7 @@ class ViewController: NSViewController {
179164
180165 override func controlTextDidChange( _ obj: Notification ) {
181166 if let field = obj. object as? NSSearchField , field == searchField {
182- filteredData = field . stringValue . isEmpty ? nil : dataSource. filter{ textContains ( $0 . code ) || textContains ( $0 . filename ) }
167+ dataSource. filter = searchField . stringValue
183168 tableView. reloadData ( )
184169 } else if let field = obj. object as? NSTextField , field == derivedDataTextField {
185170 buildManager. stopMonitoring ( )
@@ -227,9 +212,7 @@ class ViewController: NSViewController {
227212 }
228213
229214 func handleProcessorUpdate( result: [ CompileMeasure ] , didComplete: Bool , didCancel: Bool ) {
230- dataSource = result
231- perFunctionTimes = result
232- perFileTimes = aggregateTimesByFile ( perFunctionTimes)
215+ dataSource. resetSourceData ( newSourceData: result)
233216 tableView. reloadData ( )
234217
235218 if didComplete {
@@ -238,7 +221,7 @@ class ViewController: NSViewController {
238221 }
239222
240223 func completeProcessorUpdate( didCancel: Bool ) {
241- let didSucceed = !dataSource. isEmpty
224+ let didSucceed = !dataSource. isEmpty ( )
242225
243226 var stateName = ProcessingState . failedString
244227 if didCancel {
@@ -268,23 +251,18 @@ class ViewController: NSViewController {
268251 let text = " Build duration: " + ( buildTime < 60 ? " \( buildTime) s " : " \( buildTime / 60 ) m \( buildTime % 60 ) s " )
269252 compileTimeTextField. stringValue = text
270253 }
271-
272- func textContains( _ text: String ) -> Bool {
273- return text. lowercased ( ) . contains ( searchField. stringValue. lowercased ( ) )
274- }
275254}
276255
277256// MARK: NSTableViewDataSource
278257
279258extension ViewController : NSTableViewDataSource {
280259 func numberOfRows( in tableView: NSTableView ) -> Int {
281- return filteredData ? . count ?? dataSource. count
260+ return dataSource. count ( )
282261 }
283262
284263 func tableView( _ tableView: NSTableView , shouldSelectRow row: Int ) -> Bool {
285- let item = filteredData ? [ row] ?? dataSource [ row ]
264+ guard let item = dataSource . measure ( index : row) else { return false }
286265 NSWorkspace . shared. openFile ( item. path)
287-
288266
289267 let gotoLineScript =
290268 " tell application \" Xcode \" \n " +
@@ -311,12 +289,18 @@ extension ViewController: NSTableViewDataSource {
311289extension ViewController : NSTableViewDelegate {
312290 func tableView( _ tableView: NSTableView , viewFor tableColumn: NSTableColumn ? , row: Int ) -> NSView ? {
313291 guard let tableColumn = tableColumn, let columnIndex = tableView. tableColumns. index ( of: tableColumn) else { return nil }
314-
292+ guard let item = dataSource. measure ( index: row) else { return nil }
293+
315294 let result = tableView. makeView ( withIdentifier: NSUserInterfaceItemIdentifier ( rawValue: " Cell \( columnIndex) " ) , owner: self ) as? NSTableCellView
316- result? . textField? . stringValue = filteredData ? [ row ] [ columnIndex ] ?? dataSource [ row ] [ columnIndex]
295+ result? . textField? . stringValue = item [ columnIndex]
317296
318297 return result
319298 }
299+
300+ func tableView( _ tableView: NSTableView , sortDescriptorsDidChange oldDescriptors: [ NSSortDescriptor ] ) {
301+ dataSource. sortDescriptors = tableView. sortDescriptors
302+ tableView. reloadData ( )
303+ }
320304}
321305
322306// MARK: BuildManagerDelegate
0 commit comments