重整cmake
This commit is contained in:
+42
-18
@@ -161,6 +161,8 @@ class GallerySession {
|
||||
this.telemetry = {};
|
||||
this.controlValues = new Map();
|
||||
this.lastSubmittedControls = new Map();
|
||||
this.pendingStateRequests = [];
|
||||
this.lastFeedbackAt = 0;
|
||||
this.frameCount = 0;
|
||||
this.framePending = false;
|
||||
this.frameTimeout = null;
|
||||
@@ -283,7 +285,8 @@ class GallerySession {
|
||||
if (this.socket !== socket) return;
|
||||
this.socketState = "ready";
|
||||
this.socketText = "WS 已连接";
|
||||
this.send("gallery_open", {case: this.definition.id, frame_mode: this.mode.id});
|
||||
this.lastFeedbackAt = 0;
|
||||
this.sendStateRequest("open", "gallery_open", {case: this.definition.id, frame_mode: this.mode.id});
|
||||
this.resize();
|
||||
});
|
||||
socket.addEventListener("message", event => {
|
||||
@@ -299,6 +302,9 @@ class GallerySession {
|
||||
this.framePending = false;
|
||||
clearTimeout(this.frameTimeout);
|
||||
this.frameTimeout = null;
|
||||
this.pendingStateRequests.length = 0;
|
||||
this.lastSubmittedControls.clear();
|
||||
this.lastFeedbackAt = 0;
|
||||
this.socketState = "error";
|
||||
this.socketText = this.displayVisible() ? "连接关闭 · 自动重连" : "连接关闭 · 等待可见";
|
||||
this.updateMotionStatus();
|
||||
@@ -315,6 +321,11 @@ class GallerySession {
|
||||
send(type, payload = {}) {
|
||||
if (this.socket?.readyState === WebSocket.OPEN) this.socket.send(message(type, payload));
|
||||
}
|
||||
sendStateRequest(kind, type, payload = {}) {
|
||||
if (this.socket?.readyState !== WebSocket.OPEN) return;
|
||||
this.pendingStateRequests.push(kind);
|
||||
this.socket.send(message(type, payload));
|
||||
}
|
||||
receiveJson(raw) {
|
||||
let data;
|
||||
try {
|
||||
@@ -324,19 +335,21 @@ class GallerySession {
|
||||
return;
|
||||
}
|
||||
if (data.type === "error") {
|
||||
this.pendingStateRequests.shift();
|
||||
const detail = Object.values(data.field_errors || {})[0] || data.message || "后端拒绝操作";
|
||||
this.lastSubmittedControls.clear();
|
||||
notify(detail, true);
|
||||
if (menuSession === this) {
|
||||
menuStatus = detail;
|
||||
renderMenu(this, true);
|
||||
updateMenuData();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (data.type !== "case_state") return;
|
||||
const requestKind = this.pendingStateRequests.shift();
|
||||
this.controls = data.controls?.data || [];
|
||||
this.actions = data.actions?.data || [];
|
||||
this.telemetry = data.telemetry || {};
|
||||
if (requestKind === "open" || requestKind === "refresh") this.telemetry = data.telemetry || {};
|
||||
this.controlValues.clear();
|
||||
for (const item of this.controls) this.controlValues.set(item.id, item.value);
|
||||
this.lastSubmittedControls.clear();
|
||||
@@ -467,10 +480,19 @@ class GallerySession {
|
||||
}, 1500);
|
||||
}
|
||||
refreshBackendState() {
|
||||
const time = performance.now();
|
||||
if (!this.ready || this.socket?.readyState !== WebSocket.OPEN) return;
|
||||
this.pushClientFeedback(performance.now());
|
||||
this.sendStateRequest("refresh", "gallery_refresh");
|
||||
}
|
||||
pushClientFeedback(time) {
|
||||
this.lastFeedbackAt = time;
|
||||
this.transportFps = this.currentRate(this.transportTimes, time);
|
||||
this.presentationFps = this.currentRate(this.presentationTimes, time);
|
||||
this.send("gallery_refresh", {client_metrics: this.clientMetrics(time)});
|
||||
this.send("gallery_feedback", {client_metrics: this.clientMetrics(time)});
|
||||
}
|
||||
sendClientFeedback(time) {
|
||||
if (!this.ready || !this.displayVisible() || this.socket?.readyState !== WebSocket.OPEN || time - this.lastFeedbackAt < 650) return;
|
||||
this.pushClientFeedback(time);
|
||||
}
|
||||
clientMetrics(time = performance.now()) {
|
||||
return {
|
||||
@@ -525,7 +547,7 @@ class GallerySession {
|
||||
const value = normalizeEventValue(payload, id);
|
||||
if (Object.is(this.lastSubmittedControls.get(id), value) || Object.is(this.controlValues.get(id), value)) return;
|
||||
this.lastSubmittedControls.set(id, value);
|
||||
this.send("gallery_patch", {patch: {[id]: value}});
|
||||
this.sendStateRequest("patch", "gallery_patch", {patch: {[id]: value}});
|
||||
menuStatus = `提交 ${item.api} · 等待后端回读`;
|
||||
}
|
||||
runAction(id, payload) {
|
||||
@@ -536,7 +558,7 @@ class GallerySession {
|
||||
const field = `action_${item.id}`;
|
||||
request.argument = normalizeEventValue(payload, field);
|
||||
}
|
||||
this.send("gallery_action", request);
|
||||
this.sendStateRequest("action", "gallery_action", request);
|
||||
menuStatus = `执行 ${item.api}`;
|
||||
if (["mode_render", "mode_dequeue", "mode_cycle"].includes(item.id)) setTimeout(() => this.requestFrame(performance.now(), true), 40);
|
||||
}
|
||||
@@ -555,7 +577,7 @@ class GallerySession {
|
||||
const limitDurations = {frequency_limited: observer.target_interval_ns, paint_limited: observer.paint_duration_ns, render_limited: observer.render_duration_ns, consumer_limited: observer.consumer_interval_ns};
|
||||
const limitName = limitNames[limit.current] || limit.current || "N/A";
|
||||
const limitDuration = limitDurations[limit.current];
|
||||
const client = this.clientMetrics();
|
||||
const client = this.telemetry.client_performance || {};
|
||||
const observerValues = {};
|
||||
const clientValues = {};
|
||||
observerValues.mode = observer.mode || this.mode.id;
|
||||
@@ -571,10 +593,10 @@ class GallerySession {
|
||||
motionText: this.motionText,
|
||||
frameCount: formatInteger(this.frameCount),
|
||||
backendFps: formatFps(performanceData.measured_fps),
|
||||
transportFps: formatFps(performanceData.pixel_response_fps || this.transportFps),
|
||||
presentationFps: formatFps(this.presentationFps),
|
||||
roundTrip: Number(this.frameRoundTripMs || 0).toFixed(2),
|
||||
overwritten: formatInteger(this.overwrittenPixelFrames),
|
||||
transportFps: formatFps(performanceData.pixel_response_fps || client.transport_fps),
|
||||
presentationFps: formatFps(client.presentation_fps),
|
||||
roundTrip: Number(client.frame_round_trip_ms || 0).toFixed(2),
|
||||
overwritten: formatInteger(client.overwritten_pixel_frames),
|
||||
renderMs: Number(performanceData.last_render_ms || 0).toFixed(2),
|
||||
encodeMs: Number(performanceData.last_pixel_encode_ms || 0).toFixed(2),
|
||||
bandwidth: Number(performanceData.pixel_payload_megabytes_per_second || 0).toFixed(1),
|
||||
@@ -583,8 +605,8 @@ class GallerySession {
|
||||
points: `${formatInteger(dataShape.input_points)}→${formatInteger(dataShape.rendered_elements)}`,
|
||||
limit: limitDuration === undefined ? limitName : `${limitName} · ${formatNanoseconds(limitDuration)}`,
|
||||
event: observer.last_event || "none",
|
||||
timeouts: formatInteger(this.frameTimeoutCount),
|
||||
pixelAge: this.lastPixelReceivedAt ? `${Math.max(0, performance.now() - this.lastPixelReceivedAt).toFixed(0)} ms` : "—",
|
||||
timeouts: formatInteger(client.frame_request_timeout_count),
|
||||
pixelAge: Number(client.last_pixel_receive_age_ms || 0) > 0 ? `${Number(client.last_pixel_receive_age_ms).toFixed(0)} ms` : "—",
|
||||
limitFrequency: limitTile(observer.frequency_limit_enabled !== false, limit.current === "frequency_limited", observer.target_interval_ns),
|
||||
limitPaint: limitTile(true, limit.current === "paint_limited", observer.paint_duration_ns),
|
||||
limitRender: limitTile(true, limit.current === "render_limited", observer.render_duration_ns),
|
||||
@@ -711,9 +733,10 @@ function controlEventAction(session, item, source) {
|
||||
}
|
||||
function controlSchema(session, item) {
|
||||
const control = {...item.amis};
|
||||
const formId = `control_${session.key}_${item.id}`.replace(/[^A-Za-z0-9_-]/g, "_");
|
||||
const eventName = ["switch", "select", "input-color"].includes(control.type) ? "change" : "blur";
|
||||
control.onEvent = {[eventName]: {actions: [controlEventAction(session, item, "context.data")]}};
|
||||
return {type: "form", wrapWithPanel: false, className: "rv-control-form", body: [control], actions: []};
|
||||
control.onEvent = {[eventName]: {actions: [{actionType: "submit", componentId: formId}]}};
|
||||
return {type: "form", id: formId, wrapWithPanel: false, className: "rv-control-form", body: [control], actions: [], onEvent: {submit: {preventDefault: true, actions: [controlEventAction(session, item, "context.data")]}}};
|
||||
}
|
||||
function buildControlTab(session) {
|
||||
return [...groupItems(session.controls)].map(([group, items]) => ({type: "panel", className: "rv-control-panel", title: group, body: items.map(item => controlSchema(session, item))}));
|
||||
@@ -725,8 +748,8 @@ function actionSchema(session, item) {
|
||||
const description = item.description || "";
|
||||
const body = [{type: "tpl", tpl: `<div class="rv-action-head"><div><b>${escapeHtml(label)}</b><code>${escapeHtml(api)}</code></div>${description ? `<small>${escapeHtml(description)}</small>` : ""}</div>`}];
|
||||
if (item.argument_input) body.push({...item.argument_amis, name: field});
|
||||
body.push({type: "button", label: `执行 · ${label}`, level: "primary", onEvent: {click: {actions: [{actionType: "custom", script: `window.RenderiveGallery.runAction(${quote(session.key)},${quote(item.id)},context.data);`}]}}});
|
||||
return {type: "form", wrapWithPanel: false, className: "rv-action-form", body, actions: []};
|
||||
body.push({type: "button", actionType: "submit", label: `执行 · ${label}`, level: "primary"});
|
||||
return {type: "form", wrapWithPanel: false, className: "rv-action-form", body, actions: [], onEvent: {submit: {preventDefault: true, actions: [{actionType: "custom", script: `window.RenderiveGallery.runAction(${quote(session.key)},${quote(item.id)},context.data);`}]}}};
|
||||
}
|
||||
function buildActionTab(session) {
|
||||
return [...groupItems(session.actions)].map(([group, items]) => ({type: "panel", className: "rv-control-panel", title: group, body: items.map(item => actionSchema(session, item))}));
|
||||
@@ -852,6 +875,7 @@ function loop(time) {
|
||||
session.presentLatest(time);
|
||||
session.updateMotionStatus(time);
|
||||
if (session.mode.id !== "low_latency") session.requestFrame(time);
|
||||
session.sendClientFeedback(time);
|
||||
}
|
||||
requestAnimationFrame(loop);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user