Skip to content

Commit ec636cc

Browse files
authored
Update event counters only once event is drawn (#38)
Closes: #37
1 parent d92c958 commit ec636cc

File tree

3 files changed

+40
-26
lines changed

3 files changed

+40
-26
lines changed

src/components/event_counter.ts

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ import QuestionMark from "../question_mark.svg?url";
33
import QuestionMarkDark from "../question_mark_dark.svg?url";
44
import { Settings, SettingsChangedEvent } from "../settings";
55
import { registerInfoDialog } from "./info_dialog";
6-
import { AppState } from "../service/state";
6+
import { AppState, CountEvent } from "../service/state";
77

8+
const UPDATE_PERIOD = 1000;
89
const SECONDS_TO_MILLIS = 1000;
910
const MINUTES_TO_SECONDS = 60;
1011
const MINUTES_TO_MILLIS = MINUTES_TO_SECONDS * SECONDS_TO_MILLIS;
@@ -39,7 +40,7 @@ class EventCounterData {
3940
}
4041
}
4142

42-
const events: [Date, number][] = [];
43+
const events: CountEvent[] = [];
4344
let prevData = new EventCounterData();
4445
let lastData = new EventCounterData();
4546
let lastUpdate = 0;
@@ -78,7 +79,7 @@ export function setupEventCounters(
7879

7980
setInterval(() => {
8081
updateCounters(state.newEventsQueue);
81-
}, 1000);
82+
}, UPDATE_PERIOD);
8283

8384
settings.addChangedListener((event: CustomEvent<SettingsChangedEvent>) => {
8485
// Reset counters when a filter is changed
@@ -203,34 +204,35 @@ function addElements(
203204
};
204205
}
205206

206-
function updateCounters(newEventsQueue: number[]) {
207+
function updateCounters(newEventsQueue: CountEvent[]) {
207208
const currentData = new EventCounterData();
208209

209-
const currentDate = new Date();
210+
const currentTime = Date.now();
210211
lastUpdate = performance.now();
211-
events.forEach(([date, count]) => {
212-
currentData.total += count;
213-
if (date.getTime() + 5 * MINUTES_TO_MILLIS > currentDate.getTime()) {
214-
currentData.last5min += count;
215-
216-
if (date.getTime() + 1 * MINUTES_TO_MILLIS > currentDate.getTime()) {
217-
currentData.last1min += count;
218-
219-
if (date.getTime() + 10 * SECONDS_TO_MILLIS > currentDate.getTime()) {
220-
currentData.last10s += count;
212+
events.forEach(({ startTime, count }) => {
213+
if (startTime <= currentTime) {
214+
currentData.total += count;
215+
if (startTime + 5 * MINUTES_TO_MILLIS > currentTime) {
216+
currentData.last5min += count;
217+
218+
if (startTime + 1 * MINUTES_TO_MILLIS > currentTime) {
219+
currentData.last1min += count;
220+
221+
if (startTime + 10 * SECONDS_TO_MILLIS > currentTime) {
222+
currentData.last10s += count;
223+
}
221224
}
222225
}
223226
}
224227
});
225228

226-
const newSum = newEventsQueue
227-
.splice(0, newEventsQueue.length)
228-
.reduce((l: number, r: number, _index, _array) => l + r, 0);
229-
if (newSum > 0) {
230-
events.push([new Date(), newSum]);
229+
newEventsQueue.splice(0, newEventsQueue.length).forEach((c: CountEvent) => {
230+
events.push(c);
231231

232-
currentData.addToAll(newSum);
233-
}
232+
if (c.startTime <= currentTime) {
233+
currentData.addToAll(c.count);
234+
}
235+
});
234236

235237
prevData = lastData;
236238
lastData = currentData;
@@ -240,8 +242,8 @@ function updateCountersUI(
240242
timestamp: DOMHighResTimeStamp,
241243
elements: EventCounterElements,
242244
) {
243-
const delta = clamp(timestamp - lastUpdate, 0, 1000);
244-
const factor = delta / 1000;
245+
const delta = clamp(timestamp - lastUpdate, 0, UPDATE_PERIOD);
246+
const factor = delta / UPDATE_PERIOD;
245247
const scaledValue = prevData.lerpTo(lastData, factor);
246248
for (const [element, value] of [
247249
[elements.total, scaledValue.total],

src/service/data.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,10 @@ export function processServiceData(
287287
return;
288288
}
289289
if (incomingEvent.counter_include ?? true) {
290-
appState.newEventsQueue.push(incomingEvent.counter ?? 1);
290+
appState.newEventsQueue.push({
291+
count: incomingEvent.counter ?? 1,
292+
startTime: Date.now() + (incomingEvent.draw_delay ?? 0),
293+
});
291294
}
292295

293296
// Ignore invalid 0-0 data

src/service/state.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export class AppState {
1313
/**
1414
* All new incoming data should be pushed into this queue (only counts). This is used to update event counter.
1515
*/
16-
newEventsQueue: number[] = [];
16+
newEventsQueue: CountEvent[] = [];
1717
/**
1818
* If new camera positions are requested programatically, they need to be pushed into this queue.
1919
* Globe should periodically process this queue.
@@ -25,6 +25,15 @@ export class AppState {
2525
globeCurrentZoomFactor = 0;
2626
}
2727

28+
/**
29+
* Represents any event (not command) that was received.
30+
* Used to update event counters. Time is used to ensure that count is synchronized with the display.
31+
*/
32+
export interface CountEvent {
33+
startTime: number;
34+
count: number;
35+
}
36+
2837
/**
2938
* Creates a new {@link AppState} instance, based on the provided {@link Settings}.
3039
* Takes camera startup position from the settings and pushes it into the camera positions queue.

0 commit comments

Comments
 (0)