rep: working display, fixed unit problems with reps etc

master
Rob Pilling 2023-05-21 20:44:00 +01:00
parent ef26eae665
commit 057ee7df03
1 changed files with 77 additions and 61 deletions

View File

@ -8,6 +8,7 @@ const Layout = require("Layout");
type Rep = { type Rep = {
dur: number, dur: number,
label: string, label: string,
accDur: number,
}; };
const reps: Rep[] = [ const reps: Rep[] = [
@ -21,8 +22,8 @@ const reps: Rep[] = [
{dur:3/60, label:"1st-sec"}, {dur:3/60, label:"1st-sec"},
{dur:5/60, label:"5-sec"}, {dur:5/60, label:"5-sec"},
// {dur:4, label:"jog"}, {dur:4/60, label:"jog"},
// {dur:4, label:"recovery"}, {dur:4/60, label:"recovery"},
// {dur:2, label:"jog"}, // {dur:2, label:"jog"},
// {dur:2, label:"recovery"}, // {dur:2, label:"recovery"},
@ -49,7 +50,17 @@ const reps: Rep[] = [
// {dur:3, label:"static recovery"}, // {dur:3, label:"static recovery"},
// {dur:4, label:"finish"}, // {dur:4, label:"finish"},
]; ].map(((r: Rep, i: number, a: Rep[]): Rep => {
const r2 = r as Rep;
r2.dur = r2.dur * 60 * 1000;
r2.accDur = i > 0
? a[i-1]!.accDur + r.dur
: r.dur;
return r as Rep;
}) as any);
const fontSzMain = 64; const fontSzMain = 64;
const fontSzRep = 20; const fontSzRep = 20;
@ -64,11 +75,17 @@ const fontSzRepDesc = 12;
const layout = new Layout({ const layout = new Layout({
type: "v", type: "v",
c: [ c: [
{
id: "repIdx",
type: "txt",
label: "Rep 1", // TODO: update in render
font: `Vector:${fontSzRepDesc}`,
},
{ {
id: "duration", id: "duration",
lazyBuster: 1, lazyBuster: 1,
type: "custom", type: "custom",
font: `Vector:${fontSzMain}` as FontNameWithScaleFactor, // modified in draw font: `Vector:${fontSzMain}` as FontNameWithScaleFactor,
fillx: 1, fillx: 1,
filly: 1, filly: 1,
render: (l: Layout_.RenderedHierarchy) => { render: (l: Layout_.RenderedHierarchy) => {
@ -77,25 +94,26 @@ const layout = new Layout({
g.clearRect(l.x, l.y, l.x+l.w, l.y+l.h); g.clearRect(l.x, l.y, l.x+l.w, l.y+l.h);
if(state){ if(state){
const elapsed = getElapsed(state); // TODO: inefficient
const i = currentRepIndex(elapsed); const i = state.currentRepIndex();
const repElapsed = state.getElapsedForRep();
if(i == null){ if(i !== null){
// FIXME: dodgy end-of-rep handling let thisDur = reps[i]!.dur;
lbl = msToHM(elapsed);
}else{
const thisDur = repDuration(reps[i]!);
const remaining = thisDur - elapsed;
lbl = msToHM(remaining);
const fract = elapsed / thisDur; const remaining = thisDur - repElapsed;
g.setColor("#00f") lbl = msToMinSec(remaining);
const fract = repElapsed / thisDur;
g.setColor("#86caf7")
.fillRect( .fillRect(
l.x, l.x,
l.y, l.y,
l.x + fract * l.w, l.x + fract * l.w,
l.y+l.h l.y + l.h
); );
}else{
lbl = msToMinSec(repElapsed);
} }
}else{ }else{
lbl = "RDY"; lbl = "RDY";
@ -167,16 +185,9 @@ const layout = new Layout({
}, {lazy: true}); }, {lazy: true});
const onToggle = () => { const onToggle = () => {
if(!state){ if(!state)
state = { state = new State();
begin: Date.now(), state.toggle();
accumulated: 0,
};
play(true, state);
}else{
play(paused, state);
}
drawRep(); drawRep();
}; };
@ -186,47 +197,55 @@ const onPrev = () => {
const onNext = () => { const onNext = () => {
}; };
const play = (p: boolean, state: State) => { class State {
if(p){ paused: boolean = true;
layout["play"]!.label = "Pause"; begin: number = Date.now(); // only valid if !paused
accumulated: number = 0;
state.begin = Date.now(); toggle() {
if(this.paused){
this.begin = Date.now();
// TODO: move draw out
drawInterval = setInterval(drawRep, 1000); drawInterval = setInterval(drawRep, 1000);
}else{ }else{
layout["play"]!.label = "Play"; const diff = Date.now() - this.begin;
this.accumulated += diff;
const diff = Date.now() - state.begin;
state.accumulated += diff;
clearInterval(drawInterval!); clearInterval(drawInterval!);
} }
paused = !p; this.paused = !this.paused;
}
getElapsedTotal() {
return (this.paused ? 0 : Date.now() - this.begin) + this.accumulated;
}
getElapsedForRep() {
const elapsed = this.getElapsedTotal();
const i = this.currentRepIndex();
return elapsed - (i! > 0 ? reps[i!-1]!.accDur : 0);
}
currentRepIndex() {
const elapsed = this.getElapsedTotal();
let ent;
for(let i = 0; ent = reps[i]; i++)
if(elapsed < ent.accDur)
return i;
return null;
}
} }
type State = { begin: number, accumulated: number };
let state: State | undefined; let state: State | undefined;
//let drawTimeout: number | undefined;
let paused = false; // TODO: ditch this, used drawInterval
let drawInterval: IntervalId | undefined; let drawInterval: IntervalId | undefined;
const currentRepIndex = (elapsedMs: number) => {
let total = 0;
let ent;
for(let i = 0; ent = reps[i]; i++){
total += repDuration(ent);
if(elapsedMs <= total)
return i;
}
return null;
};
const repToLabel = (i: number, id: string) => { const repToLabel = (i: number, id: string) => {
const rep = reps[i]; const rep = reps[i];
if(rep){ if(rep){
layout[`${id}_name`]!.label = `${i+1}: ${rep.label} / ${rep.dur.toFixed(0)}m`; layout[`${id}_name`]!.label = `${rep.label} / ${msToMinSec(rep.dur)}`;
// FIXME: display time, i.e. hh:mm // FIXME: display time, i.e. hh:mm
//layout[`${id}_dur`]!.label = ``; //layout[`${id}_dur`]!.label = ``;
}else{ }else{
@ -240,12 +259,7 @@ const emptyLabel = (id: string) => {
const pad2 = (s: number) => ('0' + s.toFixed(0)).slice(-2); const pad2 = (s: number) => ('0' + s.toFixed(0)).slice(-2);
const repDuration = (rep: Rep) => rep.dur * 60 * 1000; const msToMinSec = (ms: number) => {
const getElapsed = (state: State) =>
Date.now() - state.begin + state.accumulated;
const msToHM = (ms: number) => {
const sec = Math.round(ms / 1000); const sec = Math.round(ms / 1000);
const min = Math.round(sec / 60); const min = Math.round(sec / 60);
return min.toFixed(0) + ":" + pad2(sec % 60); return min.toFixed(0) + ":" + pad2(sec % 60);
@ -257,8 +271,9 @@ const drawRep = () => {
if(state){ if(state){
// TODO: layout.clear(layout.next_name); layout.render(layout.next_name) // TODO: layout.clear(layout.next_name); layout.render(layout.next_name)
const elapsed = getElapsed(state); layout["play"]!.label = state.paused ? "Play" : "Pause";
const i = currentRepIndex(elapsed);
const i = state.currentRepIndex();
if(i !== null){ if(i !== null){
repToLabel(i, "cur"); repToLabel(i, "cur");
repToLabel(i+1, "next"); repToLabel(i+1, "next");
@ -272,6 +287,7 @@ const drawRep = () => {
/* /*
// TODO: figure out next rep change time? or every 5s, then countdown from 10-->0 // TODO: figure out next rep change time? or every 5s, then countdown from 10-->0
// TODO: and then use that to Bangle.buzz() on next rep
if (drawTimeout) clearTimeout(drawTimeout); if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = setTimeout(function() { drawTimeout = setTimeout(function() {
drawTimeout = undefined; drawTimeout = undefined;