Fix fallout from time/duration refactor. - Fix broken tests. - Fix bigint conversion in Duration.fromMillis(). - Remove dependency on globals in time.ts (fixes circular dependency). - Remove stray newline. Bug: 290833651 Change-Id: Ia2f95cb63bc87da6f628557774abd684c45bf51b
diff --git a/ui/src/common/time.ts b/ui/src/common/time.ts index f62f9b7..ad598e5 100644 --- a/ui/src/common/time.ts +++ b/ui/src/common/time.ts
@@ -15,7 +15,6 @@ import {BigintMath} from '../base/bigint_math'; import {assertTrue} from '../base/logging'; import {Brand} from '../frontend/brand'; -import {globals} from '../frontend/globals'; import {ColumnType} from './query_result'; @@ -146,7 +145,7 @@ } static fromMillis(millis: number) { - return BigInt((millis / 1e3) * TIME_UNITS_PER_SEC); + return BigInt(Math.floor((millis / 1e3) * TIME_UNITS_PER_SEC)); } // Throws if the value cannot be reasonably converted to a bigint. @@ -266,26 +265,6 @@ } } -// Offset between t=0 and the configured time domain. -export function timestampOffset(): time { - const fmt = timestampFormat(); - switch (fmt) { - case TimestampFormat.Timecode: - case TimestampFormat.Seconds: - return globals.state.traceTime.start; - case TimestampFormat.Raw: - case TimestampFormat.RawLocale: - return Time.ZERO; - default: - const x: never = fmt; - throw new Error(`Unsupported format ${x}`); - } -} - -// Convert absolute timestamp to domain time. -export function toDomainTime(ts: time): time { - return Time.sub(ts, timestampOffset()); -} export function currentDateHourAndMinute(): string { const date = new Date();
diff --git a/ui/src/common/time_unittest.ts b/ui/src/common/time_unittest.ts index 7dc9565..08d6c07 100644 --- a/ui/src/common/time_unittest.ts +++ b/ui/src/common/time_unittest.ts
@@ -43,12 +43,12 @@ expect(Duration.format(3_000n)).toEqual('3us'); expect(Duration.format(1_000_001_000n)).toEqual('1s 1us'); expect(Duration.format(200_000_000_030n)).toEqual('3m 20s 30ns'); - expect(Duration.format(3_600_000_000_000n)).toEqual('60m'); - expect(Duration.format(3_600_000_000_001n)).toEqual('60m 1ns'); - expect(Duration.format(86_400_000_000_000n)).toEqual('1,440m'); - expect(Duration.format(86_400_000_000_001n)).toEqual('1,440m 1ns'); - expect(Duration.format(31_536_000_000_000_000n)).toEqual('525,600m'); - expect(Duration.format(31_536_000_000_000_001n)).toEqual('525,600m 1ns'); + expect(Duration.format(3_600_000_000_000n)).toEqual('1h'); + expect(Duration.format(3_600_000_000_001n)).toEqual('1h 1ns'); + expect(Duration.format(86_400_000_000_000n)).toEqual('24h'); + expect(Duration.format(86_400_000_000_001n)).toEqual('24h 1ns'); + expect(Duration.format(31_536_000_000_000_000n)).toEqual('8,760h'); + expect(Duration.format(31_536_000_000_000_001n)).toEqual('8,760h 1ns'); }); test('Duration.humanise', () => { @@ -72,6 +72,12 @@ expect(Duration.humanise(31_536_000_000_000_000n)).toEqual('31536000s'); }); +test('Duration.fromMillis', () => { + expect(Duration.fromMillis(123.456789)).toEqual(123456789n); + expect(Duration.fromMillis(123.4567895)).toEqual(123456789n); + expect(Duration.fromMillis(0.0000001)).toEqual(0n); +}); + test('timecode', () => { expect(new Timecode(Time.fromRaw(0n)).toString(' ')) .toEqual('00:00:00.000 000 000');
diff --git a/ui/src/controller/trace_controller.ts b/ui/src/controller/trace_controller.ts index eb24289..4eb2310 100644 --- a/ui/src/controller/trace_controller.ts +++ b/ui/src/controller/trace_controller.ts
@@ -48,7 +48,6 @@ ProfileType, } from '../common/state'; import { - Duration, duration, Span,
diff --git a/ui/src/frontend/globals.ts b/ui/src/frontend/globals.ts index c851a1b..48d13b0 100644 --- a/ui/src/frontend/globals.ts +++ b/ui/src/frontend/globals.ts
@@ -40,8 +40,11 @@ import { duration, Span, + Time, time, TimeSpan, + TimestampFormat, + timestampFormat, } from '../common/time'; import {setPerfHooks} from '../core/perf'; import {raf} from '../core/raf_scheduler'; @@ -714,6 +717,27 @@ get commandManager(): CommandManager { return assertExists(this._cmdManager); } + + // Offset between t=0 and the configured time domain. + timestampOffset(): time { + const fmt = timestampFormat(); + switch (fmt) { + case TimestampFormat.Timecode: + case TimestampFormat.Seconds: + return globals.state.traceTime.start; + case TimestampFormat.Raw: + case TimestampFormat.RawLocale: + return Time.ZERO; + default: + const x: never = fmt; + throw new Error(`Unsupported format ${x}`); + } + } + + // Convert absolute time to domain time. + toDomainTime(ts: time): time { + return Time.sub(ts, this.timestampOffset()); + } } export const globals = new Globals();
diff --git a/ui/src/frontend/gridline_helper.ts b/ui/src/frontend/gridline_helper.ts index 49e4af1..ea6639a 100644 --- a/ui/src/frontend/gridline_helper.ts +++ b/ui/src/frontend/gridline_helper.ts
@@ -19,7 +19,6 @@ Span, time, Time, - timestampOffset, } from '../common/time'; import {TRACK_BORDER_COLOR, TRACK_SHELL_WIDTH} from './css_constants'; @@ -199,7 +198,7 @@ if (width > TRACK_SHELL_WIDTH && span.duration > 0n) { const maxMajorTicks = getMaxMajorTicks(width - TRACK_SHELL_WIDTH); const map = timeScaleForVisibleWindow(TRACK_SHELL_WIDTH, width); - const offset = timestampOffset(); + const offset = globals.timestampOffset(); for (const {type, time} of new TickGenerator(span, maxMajorTicks, offset)) { const px = Math.floor(map.timeToPx(time)); if (type === TickType.MAJOR) {
diff --git a/ui/src/frontend/notes_panel.ts b/ui/src/frontend/notes_panel.ts index 106cacf..97cfa56 100644 --- a/ui/src/frontend/notes_panel.ts +++ b/ui/src/frontend/notes_panel.ts
@@ -17,7 +17,7 @@ import {Actions} from '../common/actions'; import {randomColor} from '../common/colorizer'; import {AreaNote, Note} from '../common/state'; -import {Time, timestampOffset} from '../common/time'; +import {Time} from '../common/time'; import {raf} from '../core/raf_scheduler'; import { @@ -130,7 +130,7 @@ if (size.width > TRACK_SHELL_WIDTH && span.duration > 0n) { const maxMajorTicks = getMaxMajorTicks(size.width - TRACK_SHELL_WIDTH); const map = timeScaleForVisibleWindow(TRACK_SHELL_WIDTH, size.width); - const offset = timestampOffset(); + const offset = globals.timestampOffset(); const tickGen = new TickGenerator(span, maxMajorTicks, offset); for (const {type, time} of tickGen) { const px = Math.floor(map.timeToPx(time));
diff --git a/ui/src/frontend/overview_timeline_panel.ts b/ui/src/frontend/overview_timeline_panel.ts index 32eb53c..d0a011f 100644 --- a/ui/src/frontend/overview_timeline_panel.ts +++ b/ui/src/frontend/overview_timeline_panel.ts
@@ -22,8 +22,6 @@ time, TimestampFormat, timestampFormat, - timestampOffset, - toDomainTime, } from '../common/time'; import { @@ -100,7 +98,7 @@ if (size.width > TRACK_SHELL_WIDTH && this.traceTime.duration > 0n) { const maxMajorTicks = getMaxMajorTicks(this.width - TRACK_SHELL_WIDTH); - const offset = timestampOffset(); + const offset = globals.timestampOffset(); const tickGen = new TickGenerator(this.traceTime, maxMajorTicks, offset); // Draw time labels @@ -112,7 +110,7 @@ if (xPos > this.width) break; if (type === TickType.MAJOR) { ctx.fillRect(xPos - 1, 0, 1, headerHeight - 5); - const domainTime = toDomainTime(time); + const domainTime = globals.toDomainTime(time); renderTimestamp(ctx, domainTime, xPos + 5, 18, MIN_PX_PER_STEP); } else if (type == TickType.MEDIUM) { ctx.fillRect(xPos - 1, 0, 1, 8);
diff --git a/ui/src/frontend/tickmark_panel.ts b/ui/src/frontend/tickmark_panel.ts index 8234caf..51bfc6e 100644 --- a/ui/src/frontend/tickmark_panel.ts +++ b/ui/src/frontend/tickmark_panel.ts
@@ -14,7 +14,7 @@ import m from 'mithril'; -import {Time, timestampOffset} from '../common/time'; +import {Time} from '../common/time'; import {TRACK_SHELL_WIDTH} from './css_constants'; import {globals} from './globals'; @@ -48,7 +48,7 @@ const maxMajorTicks = getMaxMajorTicks(size.width - TRACK_SHELL_WIDTH); const map = timeScaleForVisibleWindow(TRACK_SHELL_WIDTH, size.width); - const offset = timestampOffset(); + const offset = globals.timestampOffset(); const tickGen = new TickGenerator(visibleSpan, maxMajorTicks, offset); for (const {type, time} of tickGen) { const px = Math.floor(map.timeToPx(time));
diff --git a/ui/src/frontend/time_axis_panel.ts b/ui/src/frontend/time_axis_panel.ts index c1c203a..e5ca40e 100644 --- a/ui/src/frontend/time_axis_panel.ts +++ b/ui/src/frontend/time_axis_panel.ts
@@ -19,8 +19,6 @@ time, TimestampFormat, timestampFormat, - timestampOffset, - toDomainTime, } from '../common/time'; import {TRACK_SHELL_WIDTH} from './css_constants'; @@ -44,7 +42,7 @@ ctx.textAlign = 'left'; ctx.font = '11px Roboto Condensed'; - const offset = timestampOffset(); + const offset = globals.timestampOffset(); // If our timecode domain has an offset, print this offset if (offset != 0n) { const width = renderTimestamp(ctx, offset, 6, 10, MIN_PX_PER_STEP); @@ -62,13 +60,13 @@ const maxMajorTicks = getMaxMajorTicks(size.width - TRACK_SHELL_WIDTH); const map = timeScaleForVisibleWindow(TRACK_SHELL_WIDTH, size.width); - const offset = timestampOffset(); + const offset = globals.timestampOffset(); const tickGen = new TickGenerator(span, maxMajorTicks, offset); for (const {type, time} of tickGen) { if (type === TickType.MAJOR) { const position = Math.floor(map.timeToPx(time)); ctx.fillRect(position, 0, 1, size.height); - const domainTime = toDomainTime(time); + const domainTime = globals.toDomainTime(time); renderTimestamp(ctx, domainTime, position + 5, 10, MIN_PX_PER_STEP); } }
diff --git a/ui/src/frontend/time_selection_panel.ts b/ui/src/frontend/time_selection_panel.ts index 3900252..ea4dacd 100644 --- a/ui/src/frontend/time_selection_panel.ts +++ b/ui/src/frontend/time_selection_panel.ts
@@ -23,8 +23,6 @@ TimeSpan, TimestampFormat, timestampFormat, - timestampOffset, - toDomainTime, } from '../common/time'; import { @@ -152,7 +150,7 @@ const maxMajorTicks = getMaxMajorTicks(size.width - TRACK_SHELL_WIDTH); const map = timeScaleForVisibleWindow(TRACK_SHELL_WIDTH, size.width); - const offset = timestampOffset(); + const offset = globals.timestampOffset(); const tickGen = new TickGenerator(span, maxMajorTicks, offset); for (const {type, time} of tickGen) { const px = Math.floor(map.timeToPx(time)); @@ -195,7 +193,7 @@ renderHover(ctx: CanvasRenderingContext2D, size: PanelSize, ts: time) { const {visibleTimeScale} = globals.frontendLocalState; const xPos = TRACK_SHELL_WIDTH + Math.floor(visibleTimeScale.timeToPx(ts)); - const domainTime = toDomainTime(ts); + const domainTime = globals.toDomainTime(ts); const label = stringifyTimestamp(domainTime); drawIBar(ctx, xPos, this.bounds(size), label); }
diff --git a/ui/src/frontend/widgets/timestamp.ts b/ui/src/frontend/widgets/timestamp.ts index 37e45ee..441c222 100644 --- a/ui/src/frontend/widgets/timestamp.ts +++ b/ui/src/frontend/widgets/timestamp.ts
@@ -20,7 +20,6 @@ Time, TimestampFormat, timestampFormat, - toDomainTime, } from '../../common/time'; import {Anchor} from '../anchor'; import {copyToClipboard} from '../clipboard'; @@ -74,7 +73,7 @@ function renderTimestamp(time: time): m.Children { const fmt = timestampFormat(); - const domainTime = toDomainTime(time); + const domainTime = globals.toDomainTime(time); switch (fmt) { case TimestampFormat.Timecode: return renderTimecode(domainTime);