Scuffed display, scuffed uuid based checkpoint (for livesplit inspired functionality)

main
isark 1 year ago
parent cd042d99ca
commit a8443964bc

@ -27,6 +27,7 @@ pub enum EntryType {
PlanForceNext, PlanForceNext,
PlanForcePrev, PlanForcePrev,
ZoneEnter, ZoneEnter,
CheckpointReached
} }
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]

@ -54,7 +54,9 @@ export class RunStatService {
/// practically which zone can't have a last exit time as last exit is not determinable for the last entry /// practically which zone can't have a last exit time as last exit is not determinable for the last entry
aggregateNAId?: string; aggregateNAId?: string;
constructor() { } constructor() {
}
calcAggregated(data: RunHistory): UnformattedAggregationData { calcAggregated(data: RunHistory): UnformattedAggregationData {
const aggregation = new Map<string, UnformattedAggregateRunStat>(); const aggregation = new Map<string, UnformattedAggregateRunStat>();
@ -104,36 +106,11 @@ export class RunStatService {
insertTimesAtCheckpoints(history: RunHistory, plan: Plan) { insertTimesAtCheckpoints(history: RunHistory, plan: Plan) {
const data = this.calcDirect(history); const data = this.calcDirect(history);
let fakeCurrent = 0; const checkPointEntries = new Map(data.filter(entry => entry.entryType === EntryType.CheckpointReached).map(entry => [entry.zoneId, entry.entryTime]));
console.log("history", history); plan.plan.forEach(elem => {
if (checkPointEntries.has(elem.uuid!)) {
data.forEach(entry => { elem.checkpoint_millis = checkPointEntries.get(elem.uuid!);
switch (entry.entryType) {
case EntryType.PlanForceNext:
fakeCurrent++;
break;
case EntryType.PlanForcePrev:
fakeCurrent--;
break;
case EntryType.ZoneEnter:
if (plan.isNext(entry.zoneId, fakeCurrent)) {
fakeCurrent++;
if (plan.plan[fakeCurrent].checkpoint) {
plan.plan[fakeCurrent].checkpoint_millis = entry.entryTime;
}
}
break;
} }
}); });
if (fakeCurrent < plan.plan.length - 1) {
for (let current = fakeCurrent; current < plan.plan.length; current++) {
if (plan.plan[current].checkpoint) {
plan.plan[current].checkpoint_millis = -1;
}
}
}
console.log("Inserted checkpoint times", plan);
} }
} }

@ -13,6 +13,7 @@ export enum EntryType {
PlanForceNext = "PlanForceNext", PlanForceNext = "PlanForceNext",
PlanForcePrev = "PlanForcePrev", PlanForcePrev = "PlanForcePrev",
ZoneEnter = "ZoneEnter", ZoneEnter = "ZoneEnter",
CheckpointReached = "CheckpointReached",
} }
export interface TrackEntry { export interface TrackEntry {
@ -45,6 +46,8 @@ export class RunHistory {
associatedName: string; associatedName: string;
last_updated: number; last_updated: number;
plan?: Plan;
constructor(data: RunHistoryInterface) { constructor(data: RunHistoryInterface) {
this.uuid = data.uuid; this.uuid = data.uuid;
this.currentElapsedMillis = data.current_elapsed_millis; this.currentElapsedMillis = data.current_elapsed_millis;
@ -115,6 +118,7 @@ export class TimeTrackerService {
if (plan.last_stored_time) { if (plan.last_stored_time) {
this.loadHistory(plan.last_stored_time).subscribe(history => { this.loadHistory(plan.last_stored_time).subscribe(history => {
if (history) { if (history) {
this.currentRunHistory = history; this.currentRunHistory = history;
} else { } else {
@ -128,10 +132,12 @@ export class TimeTrackerService {
plan.requestSelfSave(); plan.requestSelfSave();
} }
this.currentRunHistory.plan = plan;
this.askResume(plan); this.askResume(plan);
}); });
} else { } else {
this.currentRunHistory = this.createNew(plan.name); this.currentRunHistory = this.createNew(plan.name);
this.currentRunHistory.plan = plan;
} }
} }
@ -167,10 +173,19 @@ export class TimeTrackerService {
} }
private underlyingSaveStopwatch() { private underlyingSaveStopwatch() {
if(this.currentRunHistory && this.active && this.start && this.latest) { if (this.currentRunHistory && this.active && this.start && this.latest) {
console.log("Underlying save!");
this.currentRunHistory!.currentElapsedMillis = this.elapsedTimeMillis; this.currentRunHistory!.currentElapsedMillis = this.elapsedTimeMillis;
this.currentRunHistory!.last_updated = Date.now(); this.currentRunHistory!.last_updated = Date.now();
this.saveHistory(this.currentRunHistory!).subscribe(() => { }); this.saveHistory(this.currentRunHistory!).subscribe(() => { });
this.loadCache();
if(this.currentRunHistory.plan) {
this.currentRunHistory.plan.last_stored_time = this.currentRunHistory.uuid;
this.currentRunHistory.plan.requestSelfSave();
}
} }
} }
@ -211,7 +226,17 @@ export class TimeTrackerService {
} }
} }
//Not perfect but good enough..
public reportCheckpoint(checkpoint: string) {
this.currentRunHistory?.entries.push({
type: EntryType.CheckpointReached,
zone: checkpoint,
current_elapsed_millis: this.elapsedTimeMillis
})
}
public stop() { public stop() {
console.log("Stopping stopwatch");
if (this.timerSubscription && !this.timerSubscription.closed) this.timerSubscription.unsubscribe(); if (this.timerSubscription && !this.timerSubscription.closed) this.timerSubscription.unsubscribe();
if (this.debouncedSaveStopwatch && !this.debouncedSaveStopwatch.closed) this.debouncedSaveStopwatch.unsubscribe(); if (this.debouncedSaveStopwatch && !this.debouncedSaveStopwatch.closed) this.debouncedSaveStopwatch.unsubscribe();
@ -239,7 +264,7 @@ export class TimeTrackerService {
return `${h}:${m}:${s}`; return `${h}:${m}:${s}`;
} }
private loadCache() { public loadCache() {
from(invoke<Map<string, RunHistoryMetadata>>('load_cache')).subscribe(data => { from(invoke<Map<string, RunHistoryMetadata>>('load_cache')).subscribe(data => {
this.zone.run(() => { this.zone.run(() => {
const cache = new Map<string, RunHistoryMetadata>(); const cache = new Map<string, RunHistoryMetadata>();
@ -251,9 +276,9 @@ export class TimeTrackerService {
last_updated: value.last_updated, last_updated: value.last_updated,
}); });
}); });
console.log("sending new cache!");
this.storedHistoriesSubject.next(cache); this.storedHistoriesSubject.next(cache);
}) });
}); });
} }

@ -14,13 +14,13 @@
<div class="zone-slide" [style.color]="configService.config.noteDefaultFg" <div class="zone-slide" [style.color]="configService.config.noteDefaultFg"
[style.border]="index == currentPlan.current ? '1px white solid' : 'none'"> [style.border]="index == currentPlan.current ? '1px white solid' : 'none'">
<div *ngIf="showDiff(slide)"> <div *ngIf="showDiff(slide)">
<div [class]="yourDiffClass(slide)">{{yourDiff(slide)}}</div> <div style="margin: 0 3px;" [class]="yourDiffClass(slide)">{{yourDiff(slide)}}</div>
</div> </div>
<div>{{worldAreaMap!.get(slide.area_key)!.name}}</div> <div style="margin: 0 5px">{{worldAreaMap!.get(slide.area_key)!.name}}</div>
<div class="text-marker d-flex flex-row"> <div class="text-marker d-flex flex-row">
<div>{{cpMillis(slide)}}</div> <div style="margin: 0 3px;" >{{cpMillis(slide)}}</div>
<div class="waypoint-text" *ngIf="hasWaypoint(slide.area_key)">(W)</div> <div class="waypoint-text" *ngIf="hasWaypoint(slide.area_key)">(W)</div>
<div class="trial-text" *ngIf="hasTrial(slide.area_key)">(T)</div> <div class="trial-text" *ngIf="hasTrial(slide.area_key)">(T)</div>
</div> </div>

@ -9,7 +9,7 @@ import { PlanService, UrlError } from '../_services/plan.service';
import { Plan, PlanElement, PlanMetadata } from '../_models/plan'; import { Plan, PlanElement, PlanMetadata } from '../_models/plan';
import { WorldAreaService } from '../_services/world-area.service'; import { WorldAreaService } from '../_services/world-area.service';
import { WorldArea } from '../_models/world-area'; import { WorldArea } from '../_models/world-area';
import { Subscription, from } from 'rxjs'; import { Subscription, config, from } from 'rxjs';
import { open } from '@tauri-apps/api/dialog'; import { open } from '@tauri-apps/api/dialog';
import { OverlayService, StateEvent } from '../_services/overlay.service'; import { OverlayService, StateEvent } from '../_services/overlay.service';
import { appWindow } from '@tauri-apps/api/window'; import { appWindow } from '@tauri-apps/api/window';
@ -19,12 +19,6 @@ import { MatDialog } from '@angular/material/dialog';
import { TimeTrackerService } from '../_services/time-tracker.service'; import { TimeTrackerService } from '../_services/time-tracker.service';
import { RunStatService } from '../_services/run-stat.service'; import { RunStatService } from '../_services/run-stat.service';
enum Resume {
Discard,
Next,
Instant
}
@Component({ @Component({
selector: 'plan-display', selector: 'plan-display',
templateUrl: './plan-display.component.html', templateUrl: './plan-display.component.html',
@ -84,6 +78,7 @@ export class PlanDisplayComponent implements AfterViewInit, OnInit {
this.currentPlan = plan; this.currentPlan = plan;
if (this.configService.config.enableStopwatch) { if (this.configService.config.enableStopwatch) {
console.log(configService.config.runCompareHistory);
this.loadComparisonData(this.currentPlan); this.loadComparisonData(this.currentPlan);
} }
this.timeTrackerService.onNewRun(plan); this.timeTrackerService.onNewRun(plan);
@ -238,6 +233,7 @@ export class PlanDisplayComponent implements AfterViewInit, OnInit {
this.prev(); this.prev();
if (this.configService.config.enableStopwatch) { if (this.configService.config.enableStopwatch) {
this.timeTrackerService.onForcePrev(this.currentPlan!.plan[this.currentPlan!.current].area_key); this.timeTrackerService.onForcePrev(this.currentPlan!.plan[this.currentPlan!.current].area_key);
this.checkCheckpoint();
} }
}); });
@ -245,6 +241,7 @@ export class PlanDisplayComponent implements AfterViewInit, OnInit {
this.next(); this.next();
if (this.configService.config.enableStopwatch) { if (this.configService.config.enableStopwatch) {
this.timeTrackerService.onForceNext(this.currentPlan!.plan[this.currentPlan!.current].area_key); this.timeTrackerService.onForceNext(this.currentPlan!.plan[this.currentPlan!.current].area_key);
this.checkCheckpoint();
} }
}); });
@ -274,6 +271,7 @@ export class PlanDisplayComponent implements AfterViewInit, OnInit {
const currentElem = this.currentPlan.plan[this.currentPlan.current]; const currentElem = this.currentPlan.plan[this.currentPlan.current];
if(currentElem.checkpoint && !currentElem.checkpoint_your_millis) { if(currentElem.checkpoint && !currentElem.checkpoint_your_millis) {
currentElem.checkpoint_your_millis = this.timeTrackerService.elapsedTimeMillis; currentElem.checkpoint_your_millis = this.timeTrackerService.elapsedTimeMillis;
this.timeTrackerService.reportCheckpoint(currentElem.uuid!);
} }
} }
@ -281,17 +279,20 @@ export class PlanDisplayComponent implements AfterViewInit, OnInit {
if (!element.checkpoint || !element.checkpoint_your_millis || !element.checkpoint_millis) return ""; if (!element.checkpoint || !element.checkpoint_your_millis || !element.checkpoint_millis) return "";
const diff = element.checkpoint_your_millis - element.checkpoint_millis; const diff = element.checkpoint_your_millis - element.checkpoint_millis;
const neg = diff < 0; const neg = diff <= 0;
const abs = Math.abs(diff); const abs = Math.abs(diff);
const cssClass = neg ? "negative-diff" : "positive-diff"; if(diff == 0) {
return `${neg ? "-" : "+"}${this.timeTrackerService.hmsTimestamp(abs)}`; return `${neg ? "-" : "+"}00:00:00`;
} else {
return `${neg ? "-" : "+"}${this.timeTrackerService.hmsTimestamp(abs)}`;
}
} }
yourDiffClass(element: PlanElement): string { yourDiffClass(element: PlanElement): string {
if (!element.checkpoint || !element.checkpoint_your_millis || !element.checkpoint_millis) return ""; if (!element.checkpoint || !element.checkpoint_your_millis || !element.checkpoint_millis) return "";
const diff = element.checkpoint_your_millis - element.checkpoint_millis; const diff = element.checkpoint_your_millis - element.checkpoint_millis;
const neg = diff < 0; const neg = diff <= 0;
return neg ? "negative-diff" : "positive-diff"; return neg ? "negative-diff" : "positive-diff";
} }
@ -371,9 +372,11 @@ export class PlanDisplayComponent implements AfterViewInit, OnInit {
if (event.deltaY < 0) { if (event.deltaY < 0) {
this.prev(); this.prev();
this.timeTrackerService.onForcePrev(this.currentPlan!.plan[this.currentPlan!.current].area_key); this.timeTrackerService.onForcePrev(this.currentPlan!.plan[this.currentPlan!.current].area_key);
this.checkCheckpoint();
} else { } else {
this.next(); this.next();
this.timeTrackerService.onForceNext(this.currentPlan!.plan[this.currentPlan!.current].area_key); this.timeTrackerService.onForceNext(this.currentPlan!.plan[this.currentPlan!.current].area_key);
this.checkCheckpoint();
} }
} }

@ -2,7 +2,7 @@
<ng-container *ngIf="!shouldShowTable && cache"> <ng-container *ngIf="!shouldShowTable && cache">
<div class="cache-viewport"> <div class="cache-viewport">
<div *ngFor="let item of this.cache | keyvalue" class="cache-item d-flex flex-row p-4"> <div *ngFor="let item of this.cache | keyvalue: myOrder" class="cache-item d-flex flex-row p-4">
<div class="d-flex flex-column"> <div class="d-flex flex-column">
<span>Plan: {{item.value.associatedName}}</span> <span>Plan: {{item.value.associatedName}}</span>
<span>Run time: {{hms(item.value.currentElapsedMillis)}}</span> <span>Run time: {{hms(item.value.currentElapsedMillis)}}</span>

@ -1,5 +1,5 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule, KeyValue } from '@angular/common';
import { EntryType, RunHistory, RunHistoryMetadata, TimeTrackerService } from '../_services/time-tracker.service'; import { EntryType, RunHistory, RunHistoryMetadata, TimeTrackerService } from '../_services/time-tracker.service';
import { MatTableModule } from '@angular/material/table'; import { MatTableModule } from '@angular/material/table';
import { MatSlideToggleModule } from '@angular/material/slide-toggle'; import { MatSlideToggleModule } from '@angular/material/slide-toggle';
@ -121,9 +121,13 @@ export class RunStatsComponent implements OnInit {
} }
reset() { reset() {
this.timeTrackerService.loadCache();
this.aggregated = undefined; this.aggregated = undefined;
this.direct = undefined; this.direct = undefined;
}
myOrder(a: KeyValue<string, RunHistoryMetadata>, b: KeyValue<string, RunHistoryMetadata>): number {
return b.value.last_updated - a.value.last_updated;
} }
setComparison(id: string) { setComparison(id: string) {

Loading…
Cancel
Save