@@ -65,6 +65,10 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
65
65
protected _availablePorts : Port [ ] = [ ] ;
66
66
protected _availableBoards : AvailableBoard [ ] = [ ] ;
67
67
68
+ private lastBoardsConfigOnUpload : BoardsConfig . Config | undefined ;
69
+ private lastAvailablePortsOnUpload : Port [ ] | undefined ;
70
+ private boardConfigToAutoSelect : BoardsConfig . Config | undefined ;
71
+
68
72
/**
69
73
* Unlike `onAttachedBoardsChanged` this event fires when the user modifies the selected board in the IDE.\
70
74
* This event also fires, when the boards package was not available for the currently selected board,
@@ -112,6 +116,84 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
112
116
return this . _reconciled . promise ;
113
117
}
114
118
119
+ snapshotBoardDiscoveryOnUpload ( ) : void {
120
+ this . lastBoardsConfigOnUpload = this . _boardsConfig ;
121
+ this . lastAvailablePortsOnUpload = this . _availablePorts ;
122
+ }
123
+
124
+ clearBoardDiscoverySnapshot ( ) : void {
125
+ this . lastBoardsConfigOnUpload = undefined ;
126
+ this . lastAvailablePortsOnUpload = undefined ;
127
+ }
128
+
129
+ private portToAutoSelectCanBeDerived ( ) : boolean {
130
+ return Boolean (
131
+ this . lastBoardsConfigOnUpload && this . lastAvailablePortsOnUpload
132
+ ) ;
133
+ }
134
+
135
+ attemptPostUploadAutoSelect ( ) : void {
136
+ setTimeout ( ( ) => {
137
+ if ( this . portToAutoSelectCanBeDerived ( ) ) {
138
+ this . attemptAutoSelect ( {
139
+ ports : this . _availablePorts ,
140
+ boards : this . _availableBoards ,
141
+ } ) ;
142
+ }
143
+ } , 2000 ) ; // 2 second delay same as IDE 1.8
144
+ }
145
+
146
+ private attemptAutoSelect (
147
+ newState : AttachedBoardsChangeEvent [ 'newState' ]
148
+ ) : void {
149
+ this . deriveBoardConfigToAutoSelect ( newState ) ;
150
+ this . tryReconnect ( ) ;
151
+ }
152
+
153
+ private deriveBoardConfigToAutoSelect (
154
+ newState : AttachedBoardsChangeEvent [ 'newState' ]
155
+ ) : void {
156
+ if ( ! this . portToAutoSelectCanBeDerived ( ) ) {
157
+ this . boardConfigToAutoSelect = undefined ;
158
+ return ;
159
+ }
160
+
161
+ const oldPorts = this . lastAvailablePortsOnUpload ! ;
162
+ const { ports : newPorts , boards : newBoards } = newState ;
163
+
164
+ const appearedPorts =
165
+ oldPorts . length > 0
166
+ ? newPorts . filter ( ( newPort : Port ) =>
167
+ oldPorts . every ( ( oldPort : Port ) => ! Port . sameAs ( newPort , oldPort ) )
168
+ )
169
+ : newPorts ;
170
+
171
+ for ( const port of appearedPorts ) {
172
+ const boardOnAppearedPort = newBoards . find ( ( board : Board ) =>
173
+ Port . sameAs ( board . port , port )
174
+ ) ;
175
+
176
+ const lastBoardsConfigOnUpload = this . lastBoardsConfigOnUpload ! ;
177
+
178
+ if (
179
+ boardOnAppearedPort &&
180
+ lastBoardsConfigOnUpload . selectedBoard &&
181
+ Board . sameAs (
182
+ boardOnAppearedPort ,
183
+ lastBoardsConfigOnUpload . selectedBoard
184
+ )
185
+ ) {
186
+ this . clearBoardDiscoverySnapshot ( ) ;
187
+
188
+ this . boardConfigToAutoSelect = {
189
+ selectedBoard : boardOnAppearedPort ,
190
+ selectedPort : port ,
191
+ } ;
192
+ return ;
193
+ }
194
+ }
195
+ }
196
+
115
197
protected notifyAttachedBoardsChanged (
116
198
event : AttachedBoardsChangeEvent
117
199
) : void {
@@ -120,10 +202,18 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
120
202
this . logger . info ( AttachedBoardsChangeEvent . toString ( event ) ) ;
121
203
this . logger . info ( '------------------------------------------' ) ;
122
204
}
205
+
123
206
this . _attachedBoards = event . newState . boards ;
124
207
this . _availablePorts = event . newState . ports ;
125
208
this . onAvailablePortsChangedEmitter . fire ( this . _availablePorts ) ;
126
- this . reconcileAvailableBoards ( ) . then ( ( ) => this . tryReconnect ( ) ) ;
209
+ this . reconcileAvailableBoards ( ) . then ( ( ) => {
210
+ const { uploadInProgress } = event ;
211
+ // avoid attempting "auto-selection" while an
212
+ // upload is in progress
213
+ if ( ! uploadInProgress ) {
214
+ this . attemptAutoSelect ( event . newState ) ;
215
+ }
216
+ } ) ;
127
217
}
128
218
129
219
protected notifyPlatformInstalled ( event : { item : BoardsPackage } ) : void {
@@ -239,24 +329,12 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
239
329
return true ;
240
330
}
241
331
}
242
- // If we could not find an exact match, we compare the board FQBN-name pairs and ignore the port, as it might have changed.
243
- // See documentation on `latestValidBoardsConfig`.
244
- for ( const board of this . availableBoards . filter (
245
- ( { state } ) => state !== AvailableBoard . State . incomplete
246
- ) ) {
247
- if (
248
- this . latestValidBoardsConfig . selectedBoard . fqbn === board . fqbn &&
249
- this . latestValidBoardsConfig . selectedBoard . name === board . name &&
250
- this . latestValidBoardsConfig . selectedPort . protocol ===
251
- board . port ?. protocol
252
- ) {
253
- this . boardsConfig = {
254
- ...this . latestValidBoardsConfig ,
255
- selectedPort : board . port ,
256
- } ;
257
- return true ;
258
- }
259
- }
332
+
333
+ if ( ! this . boardConfigToAutoSelect ) return false ;
334
+
335
+ this . boardsConfig = this . boardConfigToAutoSelect ;
336
+ this . boardConfigToAutoSelect = undefined ;
337
+ return true ;
260
338
}
261
339
return false ;
262
340
}
@@ -450,6 +528,11 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
450
528
const board = attachedBoards . find ( ( { port } ) =>
451
529
Port . sameAs ( boardPort , port )
452
530
) ;
531
+ // "board" will always be falsey for
532
+ // port that was originally mapped
533
+ // to unknown board and then selected
534
+ // manually by user
535
+
453
536
const lastSelectedBoard = await this . getLastSelectedBoardOnPort (
454
537
boardPort
455
538
) ;
@@ -468,7 +551,9 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
468
551
availableBoard = {
469
552
...lastSelectedBoard ,
470
553
state : AvailableBoard . State . guessed ,
471
- selected : BoardsConfig . Config . sameAs ( boardsConfig , lastSelectedBoard ) ,
554
+ selected :
555
+ BoardsConfig . Config . sameAs ( boardsConfig , lastSelectedBoard ) &&
556
+ Port . sameAs ( boardPort , boardsConfig . selectedPort ) , // to avoid double selection
472
557
port : boardPort ,
473
558
} ;
474
559
} else {
@@ -483,7 +568,7 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
483
568
484
569
if (
485
570
boardsConfig . selectedBoard &&
486
- ! availableBoards . some ( ( { selected } ) => selected )
571
+ availableBoards . every ( ( { selected } ) => ! selected )
487
572
) {
488
573
// If the selected board has the same port of an unknown board
489
574
// that is already in availableBoards we might get a duplicate port.
0 commit comments