-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstream-load.js
More file actions
126 lines (112 loc) · 3.61 KB
/
Copy pathstream-load.js
File metadata and controls
126 lines (112 loc) · 3.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/**
* Desktop mosaic mount waves + segmented thumbnail prefetch (FCFS queues).
*/
(function (global) {
let mountGen = 0;
let lazyFeedGen = 0;
let lazyFeedTimer = null;
let lazyFeedBuffer = [];
function isDesktopCanvas() {
return !(global.VWallScroll?.useScrollWall?.());
}
function tierConfig() {
const tier = global.VWallPerfGuard?.getTier?.() ?? 0;
if (tier >= 2) return { wave: 20, waveMs: 200, lazy: 6, lazyMs: 160 };
if (tier >= 1) return { wave: 32, waveMs: 140, lazy: 10, lazyMs: 120 };
return { wave: 52, waveMs: 95, lazy: 18, lazyMs: 90 };
}
function flowOrder(prepared, gridMode) {
const tagged = prepared.map((p) => ({
...p,
dist: p.pos.bx * p.pos.bx + p.pos.by * p.pos.by
}));
tagged.sort((a, b) => {
if (gridMode) {
if (a.pos.by !== b.pos.by) return a.pos.by - b.pos.by;
return a.pos.bx - b.pos.bx;
}
return a.dist - b.dist;
});
return tagged;
}
/** Index order FCFS (“rolling shutter / classic linear ingest”). */
function flowOrderFifo(prepared) {
return [...prepared].sort((a, b) => a.i - b.i);
}
/** @param {'fifo'|'spatial'} mountOrder */
function orderPreparedForMount(prepared, gridMode, mountOrder) {
return mountOrder === "spatial"
? flowOrder(prepared, gridMode)
: flowOrderFifo(prepared);
}
function cancel() {
mountGen++;
lazyFeedGen++;
if (lazyFeedTimer) {
clearTimeout(lazyFeedTimer);
lazyFeedTimer = null;
}
lazyFeedBuffer = [];
}
function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function mountInWaves(prepared, mountOne, gridMode, opts = {}) {
const mountOrder =
opts.mountOrder ??
global.VWallLadder?.ORDER_FIFO ??
"fifo";
const gen = ++mountGen;
const { wave, waveMs } = tierConfig();
const ordered = orderPreparedForMount(prepared, gridMode, mountOrder);
const total = ordered.length;
for (let i = 0; i < total; i += wave) {
if (gen !== mountGen) return;
const chunk = ordered.slice(i, i + wave);
for (const item of chunk) {
mountOne(item, { fadeIn: true });
}
global.onStreamMountWave?.({
done: Math.min(i + chunk.length, total),
total,
wave: chunk.length
});
if (i + wave < total) await delay(waveMs);
}
}
/** @typedef {(chunk: unknown[], lazyFeedGeneration: number) => void} PushChunk */
/** Shared pump for chunked FCFS prefetch (preserves parity with buffers already sipping). */
function thumbFeedPump(pushChunk, gen) {
if (lazyFeedGen !== gen) return;
const { lazy, lazyMs } = tierConfig();
const chunk = lazyFeedBuffer.splice(0, lazy);
if (chunk.length) pushChunk(chunk, gen);
if (lazyFeedBuffer.length) lazyFeedTimer = setTimeout(() => thumbFeedPump(pushChunk, gen), lazyMs);
else lazyFeedTimer = null;
}
/** @param append Concatenate pending thumbs without resetting buffers that are still hydrating */
function startLazyFeed(gen, entries, pushChunk, append = false) {
lazyFeedGen = gen;
const incoming = [...(entries || [])];
if (append && incoming.length && lazyFeedBuffer.length) {
lazyFeedBuffer.push(...incoming);
if (!lazyFeedTimer) thumbFeedPump(pushChunk, gen);
return;
}
if (lazyFeedTimer) {
clearTimeout(lazyFeedTimer);
lazyFeedTimer = null;
}
lazyFeedBuffer = incoming;
thumbFeedPump(pushChunk, gen);
}
global.VWallStreamLoad = {
isDesktopCanvas,
flowOrder,
flowOrderFifo,
orderPreparedForMount,
cancel,
mountInWaves,
startLazyFeed
};
})(window);