diff --git a/src/app/app-settings.ts b/src/app/app-settings.ts index d303f712..cef4285b 100644 --- a/src/app/app-settings.ts +++ b/src/app/app-settings.ts @@ -2,6 +2,8 @@ import { Injectable, isDevMode } from '@angular/core'; import { SettingsService } from './services/settings.service'; +import { Observable } from 'rxjs'; + import { map } from 'rxjs/operators'; const DRIVERS = isDevMode() ? [ @@ -102,6 +104,7 @@ export class RaceOptions { time: number; pause = false; slotmode = false; + stopfin = false; drivers?: number; auto = false; pace = false; @@ -171,7 +174,7 @@ export class AppSettings { return this.settings.set('options', value); } - getQualifyingSettings() { + getQualifyingSettings(): Observable { return this.settings.observe('qualifying').pipe( map(value => Object.assign(new RaceOptions('qualifying'), value)) ); @@ -181,7 +184,7 @@ export class AppSettings { return this.settings.set('qualifying', value); } - getRaceSettings() { + getRaceSettings(): Observable { return this.settings.observe('race').pipe( map(value => Object.assign(new RaceOptions('race'), value)) ); diff --git a/src/app/rms/race-settings.component.html b/src/app/rms/race-settings.component.html index 2c1c6be6..e309ef6d 100644 --- a/src/app/rms/race-settings.component.html +++ b/src/app/rms/race-settings.component.html @@ -69,6 +69,9 @@ Finish all laps + + Stop cars when finished + diff --git a/src/app/rms/race-settings.component.ts b/src/app/rms/race-settings.component.ts index 4d68e023..bee495e9 100644 --- a/src/app/rms/race-settings.component.ts +++ b/src/app/rms/race-settings.component.ts @@ -45,6 +45,7 @@ function createQualifyingForm(fb: FormBuilder, params: NavParams) { value: params.get('pause') || false, disabled: !params.get('time') }), + stopfin: new FormControl(params.get('stopfin') || false), drivers: new FormControl(params.get('drivers') || ''), auto: new FormControl(params.get('auto') || false), pace: new FormControl(params.get('pace') || false) @@ -63,6 +64,7 @@ function createRaceForm(fb: FormBuilder, params: NavParams) { value: !!params.get('slotmode'), disabled: !params.get('laps') }), + stopfin: new FormControl(params.get('stopfin') || false), drivers: new FormControl(params.get('drivers') || ''), auto: new FormControl(params.get('auto') || false), pace: new FormControl(params.get('pace') || false) @@ -165,7 +167,8 @@ export class RaceSettingsComponent implements AfterViewInit { drivers: options.drivers ? parseInt(options.drivers) : undefined, auto: options.auto, pace: options.pace, - slotmode: options.slotmode + slotmode: options.slotmode, + stopfin: options.stopfin })); } diff --git a/src/app/rms/rms.page.ts b/src/app/rms/rms.page.ts index 997bc831..e614371f 100644 --- a/src/app/rms/rms.page.ts +++ b/src/app/rms/rms.page.ts @@ -226,12 +226,17 @@ export class RmsPage implements OnDestroy, OnInit { skipWhile(value => !value), map(value => [value ? 'yellowflag' : 'greenflag', null]) ), + session.allFinished.pipe( + filter(v => v), + take(1), + map(() => ['alldone', null]) // TODO: add notification, qualifying vs. race? + ), this.lapcount.pipe( filter(laps => { return options.laps >= 10 && laps.count === options.laps - 4 && !session.finished.value; }), take(1), - map(() => ['fivelaps', null]) + map(() => ['fivelaps', null]) // TODO: threelaps, too? ), this.lapcount.pipe( filter(laps => { @@ -312,13 +317,24 @@ export class RmsPage implements OnDestroy, OnInit { ) ); + this.subscriptions.add( + events.pipe( + filter(([event]) => event == 'alldone'), + withLatestFrom(this.getRaceOptions(options.mode)) + ).subscribe(([[event], options]) => { + if (options.stopfin) { + cu.toggleStart(); // TODO: read state? + } + }) + ); + if (options.mode != 'practice') { const start = cu.getStart(); start.pipe(take(1)).toPromise().then(value => { if (value === 0) { cu.toggleStart(); } - // wait until startlight goes off; TODO: subscribe/unsibscribe? + // wait until startlight goes off; TODO: subscribe/unsubscribe? cu.getStart().pipe(pairwise(),filter(([prev, curr]) => { return prev != 0 && curr == 0; }),take(1),).toPromise().then(() => { @@ -326,6 +342,7 @@ export class RmsPage implements OnDestroy, OnInit { session.start(); }); }); + } return session; diff --git a/src/app/rms/session.ts b/src/app/rms/session.ts index 77bdfe85..da98b95b 100644 --- a/src/app/rms/session.ts +++ b/src/app/rms/session.ts @@ -1,5 +1,5 @@ import { EMPTY, BehaviorSubject, Observable, interval, merge } from 'rxjs'; -import { combineLatest, distinctUntilChanged, filter, groupBy, map, mergeMap, publishReplay, refCount, scan, share, startWith, tap, withLatestFrom } from 'rxjs/operators'; +import { combineLatestWith, distinctUntilChanged, filter, groupBy, map, mergeMap, publishReplay, refCount, scan, share, startWith, tap, withLatestFrom } from 'rxjs/operators'; import { RaceOptions } from '../app-settings'; import { ControlUnit } from '../carrera'; @@ -60,6 +60,7 @@ export class Session { currentLap: Observable; finished = new BehaviorSubject(false); yellowFlag = new BehaviorSubject(false); + allFinished: Observable; timer: Observable; started = false; stopped = false; @@ -108,7 +109,7 @@ export class Session { this.ranking = reset.pipe( startWith(null), - combineLatest(this.grid), + combineLatestWith(this.grid), map(([_reset, grid]) => { return grid; // for reset side effects only... }), @@ -144,6 +145,17 @@ export class Session { distinctUntilChanged() ); + this.allFinished = this.ranking.pipe( + combineLatestWith(this.finished), + map(([cars, fini]) => { + return fini && cars.every(e => e.finished); + }), + startWith(false), + publishReplay(1), + refCount(), + distinctUntilChanged() + ); + if (options.time) { this.timer = interval(TIMER_INTERVAL).pipe( withLatestFrom( @@ -240,7 +252,7 @@ export class Session { type PitInfo = [number, boolean]; return times.pipe( - combineLatest( + combineLatestWith( pits.pipe( map(mask => ((mask & ~this.mask) & (1 << group.key)) != 0), distinctUntilChanged(), diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json index 7709e1ff..713adb9d 100644 --- a/src/assets/i18n/de.json +++ b/src/assets/i18n/de.json @@ -87,6 +87,7 @@ "Share": "Teilen", "Speed": "Tempo", "Start": "Start", + "Stop cars when finished": "Autos halten am Ende an", "Stop time when paused": "Zeit bei Unterbrechung stoppen", "Time": "Zeit", "Timeout": "Zeit ist um", diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 0c6dd9e8..5b84e03c 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -87,6 +87,7 @@ "Share": "Share", "Speed": "Speed", "Start": "Start", + "Stop cars when finished": "Stop cars when finished", "Stop time when paused": "Stop time when paused", "Time": "Time", "Timeout": "Time's up", diff --git a/src/assets/i18n/es.json b/src/assets/i18n/es.json index 71e82b6e..1c0e6f29 100644 --- a/src/assets/i18n/es.json +++ b/src/assets/i18n/es.json @@ -87,6 +87,7 @@ "Share": "Compartir", "Speed": "Velocidad", "Start": "Comenzar", + "Stop cars when finished": "Detener los autos cuando haya terminado", "Stop time when paused": "Cronómetro detenido", "Time": "Tiempo", "Timeout": "Se acabó el tiempo", diff --git a/src/assets/i18n/fr.json b/src/assets/i18n/fr.json index d53d7731..8b0810c1 100644 --- a/src/assets/i18n/fr.json +++ b/src/assets/i18n/fr.json @@ -87,6 +87,7 @@ "Share": "Partager", "Speed": "Vitesse", "Start": "Départ", + "Stop cars when finished": "Arrêter les voitures une fois terminé", "Stop time when paused": "Stopper le chrono sous pause", "Time": "Temps", "Timeout": "Le temps est écoulé", diff --git a/src/assets/i18n/it.json b/src/assets/i18n/it.json index ebb2c5ae..36dfe9ff 100644 --- a/src/assets/i18n/it.json +++ b/src/assets/i18n/it.json @@ -87,6 +87,7 @@ "Share": "Condividi", "Speed": "Velocità", "Start": "Partenza", + "Stop cars when finished": "Fermare le auto una volta finito", "Stop time when paused": "Cronometro fermo in pausa", "Time": "Durata", "Timeout": "Tempo scaduto",