2 Commits

Author SHA1 Message Date
sorlinv
02d2e9ed1d chore: release v1.5.0 2026-03-04 09:52:30 +01:00
sorlinv
b1c66f055a better render queue multi 2026-03-04 09:52:17 +01:00
6 changed files with 270 additions and 20 deletions

View File

@@ -30,7 +30,8 @@
"Bash(python3 -c \"import json,sys; d=json.load\\(sys.stdin\\); print\\(f''Release creee: id={d.get\\(\"\"id\"\", \"\"ERREUR\"\"\\)} tag={d.get\\(\"\"tag_name\"\", \"\"?\"\"\\)}''\\); print\\(d.get\\(''message'',''''\\)\\) if ''message'' in d else None\")", "Bash(python3 -c \"import json,sys; d=json.load\\(sys.stdin\\); print\\(f''Release creee: id={d.get\\(\"\"id\"\", \"\"ERREUR\"\"\\)} tag={d.get\\(\"\"tag_name\"\", \"\"?\"\"\\)}''\\); print\\(d.get\\(''message'',''''\\)\\) if ''message'' in d else None\")",
"Bash(python3 -c \"import json,sys; d=json.load\\(sys.stdin\\); print\\(f'' OK: {d.get\\(\"\"name\"\",\"\"?\"\"\\)} \\({d.get\\(\"\"size\"\",0\\)//1024//1024}MB\\)''\\)\")", "Bash(python3 -c \"import json,sys; d=json.load\\(sys.stdin\\); print\\(f'' OK: {d.get\\(\"\"name\"\",\"\"?\"\"\\)} \\({d.get\\(\"\"size\"\",0\\)//1024//1024}MB\\)''\\)\")",
"Bash(python3 -c \"import json,sys; d=json.load\\(sys.stdin\\); print\\(f''OK: {d.get\\(\"\"name\"\",d.get\\(\"\"message\"\",\"\"?\"\"\\)\\)} size={d.get\\(\"\"size\"\",0\\)//1024//1024}MB''\\)\")", "Bash(python3 -c \"import json,sys; d=json.load\\(sys.stdin\\); print\\(f''OK: {d.get\\(\"\"name\"\",d.get\\(\"\"message\"\",\"\"?\"\"\\)\\)} size={d.get\\(\"\"size\"\",0\\)//1024//1024}MB''\\)\")",
"Bash(python3 -c \":*)" "Bash(python3 -c \":*)",
"mcp__ide__getDiagnostics"
] ]
} }
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "multi-render-blender", "name": "multi-render-blender",
"version": "1.4.0", "version": "1.5.0",
"description": "Application Electron pour piloter des rendus Blender multi-cameras", "description": "Application Electron pour piloter des rendus Blender multi-cameras",
"main": "main.js", "main": "main.js",
"scripts": { "scripts": {

View File

@@ -1,13 +1,13 @@
const BlenderProcess = require("./BlenderProcess.js"); const BlenderProcess = require("./BlenderProcess.js");
const path = require("path"); const path = require("path");
const fs = require("fs"); const fs = require("fs");
const os = require("os");
const { Notification } = require("electron"); const { Notification } = require("electron");
const STR_STATUS_IDLE = "idle"; const STR_STATUS_IDLE = "idle";
const STR_STATUS_RUNNING = "running"; const STR_STATUS_RUNNING = "running";
const STR_STATUS_PAUSED = "paused"; const STR_STATUS_PAUSED = "paused";
const STR_PLACEHOLDER_CONTENT = "RENDERING"; const NB_PLACEHOLDER_MAX_SIZE = 512;
const NB_PLACEHOLDER_MAX_SIZE = 64;
class QueueManager { class QueueManager {
constructor(obj_window) { constructor(obj_window) {
@@ -19,6 +19,10 @@ class QueueManager {
this.nb_last_render_ms = 0; this.nb_last_render_ms = 0;
this.str_last_image_path = null; this.str_last_image_path = null;
this.obj_notification_config = { is_notify_each_image: false, is_notify_all_done: true }; this.obj_notification_config = { is_notify_each_image: false, is_notify_all_done: true };
this.str_hostname = os.hostname();
this.nb_total_render_ms = 0;
this.nb_completed_renders = 0;
this.map_remote_avgs = {};
} }
set_notification_config(obj_config) { set_notification_config(obj_config) {
@@ -38,6 +42,9 @@ class QueueManager {
this.str_status = STR_STATUS_RUNNING; this.str_status = STR_STATUS_RUNNING;
this.nb_last_render_ms = 0; this.nb_last_render_ms = 0;
this.str_last_image_path = null; this.str_last_image_path = null;
this.nb_total_render_ms = 0;
this.nb_completed_renders = 0;
this.map_remote_avgs = {};
this.str_overwrite_mode = obj_config.str_overwrite_mode || "overwrite"; this.str_overwrite_mode = obj_config.str_overwrite_mode || "overwrite";
this.list_collections = obj_config.list_collections || []; this.list_collections = obj_config.list_collections || [];
this.obj_render_settings = obj_config.obj_render_settings || null; this.obj_render_settings = obj_config.obj_render_settings || null;
@@ -194,6 +201,8 @@ class QueueManager {
return; return;
} }
this._check_remote_completions();
// Batch skip : boucle iterative pour eviter un stack overflow recursif // Batch skip : boucle iterative pour eviter un stack overflow recursif
let nb_skip_count = 0; let nb_skip_count = 0;
while (this.nb_current_index < this.list_queue.length && this.str_overwrite_mode === "skip") { while (this.nb_current_index < this.list_queue.length && this.str_overwrite_mode === "skip") {
@@ -215,7 +224,18 @@ class QueueManager {
if (nb_size === 0) { if (nb_size === 0) {
break; break;
} }
obj_check.str_status = "skipped";
if (nb_size > NB_PLACEHOLDER_MAX_SIZE) {
obj_check.str_status = "skipped";
try {
obj_check.str_done_date = fs.statSync(obj_check.str_expected_file).mtime.toISOString();
} catch (obj_date_err) {
// ignore
}
} else {
obj_check.str_status = "rendering_remote";
this._read_placeholder(obj_check);
}
this.nb_current_index++; this.nb_current_index++;
nb_skip_count++; nb_skip_count++;
} }
@@ -242,13 +262,26 @@ class QueueManager {
try { try {
if (fs.existsSync(obj_item.str_expected_file)) { if (fs.existsSync(obj_item.str_expected_file)) {
let nb_recheck_size = fs.statSync(obj_item.str_expected_file).size; let nb_recheck_size = fs.statSync(obj_item.str_expected_file).size;
if (nb_recheck_size > 0) { if (nb_recheck_size > NB_PLACEHOLDER_MAX_SIZE) {
obj_item.str_status = "skipped"; obj_item.str_status = "skipped";
try {
obj_item.str_done_date = fs.statSync(obj_item.str_expected_file).mtime.toISOString();
} catch (obj_d_err) {
// ignore
}
this._send_log("Skip : " + obj_item.str_camera_name + " F" + obj_item.nb_frame + " (existant)"); this._send_log("Skip : " + obj_item.str_camera_name + " F" + obj_item.nb_frame + " (existant)");
this.nb_current_index++; this.nb_current_index++;
this._send_progress(); this._send_progress();
this._process_next(); this._process_next();
return; return;
} else if (nb_recheck_size > 0) {
obj_item.str_status = "rendering_remote";
this._read_placeholder(obj_item);
this._send_log("Skip : " + obj_item.str_camera_name + " F" + obj_item.nb_frame + " (en cours par " + (obj_item.str_remote_hostname || "?") + ")");
this.nb_current_index++;
this._send_progress();
this._process_next();
return;
} }
} }
} catch (obj_recheck_err) { } catch (obj_recheck_err) {
@@ -264,7 +297,7 @@ class QueueManager {
if (!fs.existsSync(str_dir)) { if (!fs.existsSync(str_dir)) {
fs.mkdirSync(str_dir, { recursive: true }); fs.mkdirSync(str_dir, { recursive: true });
} }
fs.writeFileSync(obj_item.str_expected_file, STR_PLACEHOLDER_CONTENT); fs.writeFileSync(obj_item.str_expected_file, this._get_placeholder_content());
} catch (obj_file_err) { } catch (obj_file_err) {
this._send_log("ERREUR creation placeholder : " + obj_file_err.message); this._send_log("ERREUR creation placeholder : " + obj_file_err.message);
} }
@@ -301,6 +334,9 @@ class QueueManager {
obj_item.str_status = "done"; obj_item.str_status = "done";
this.nb_last_render_ms = Date.now() - nb_start; this.nb_last_render_ms = Date.now() - nb_start;
this.nb_total_render_ms += this.nb_last_render_ms;
this.nb_completed_renders++;
obj_item.str_done_date = new Date().toISOString();
let str_image = obj_result.str_rendered_file || obj_item.str_expected_file; let str_image = obj_result.str_rendered_file || obj_item.str_expected_file;
this.str_last_image_path = str_image; this.str_last_image_path = str_image;
@@ -356,14 +392,54 @@ class QueueManager {
let list_skipped = []; let list_skipped = [];
let list_stopped = []; let list_stopped = [];
let list_skipped_paths = []; let list_skipped_paths = [];
let list_rendering_remote = [];
let list_item_results = [];
let nb_avg = this.nb_completed_renders > 0
? Math.round(this.nb_total_render_ms / this.nb_completed_renders)
: 0;
for (let nb_i = 0; nb_i < this.list_queue.length; nb_i++) { for (let nb_i = 0; nb_i < this.list_queue.length; nb_i++) {
if (this.list_queue[nb_i].str_status === "skipped") { let obj_q = this.list_queue[nb_i];
if (obj_q.str_status === "skipped") {
list_skipped.push(nb_i); list_skipped.push(nb_i);
list_skipped_paths.push({ nb_index: nb_i, str_path: this.list_queue[nb_i].str_expected_file }); list_skipped_paths.push({ nb_index: nb_i, str_path: obj_q.str_expected_file });
} else if (this.list_queue[nb_i].str_status === "stopped") { list_item_results.push({
nb_index: nb_i,
str_type: "done",
str_date: obj_q.str_done_date || null,
str_resolution: obj_q.nb_resolution_x + "x" + obj_q.nb_resolution_y,
});
} else if (obj_q.str_status === "stopped") {
list_stopped.push(nb_i); list_stopped.push(nb_i);
} else if (obj_q.str_status === "rendering_remote") {
list_rendering_remote.push(nb_i);
list_item_results.push({
nb_index: nb_i,
str_type: "rendering_remote",
str_remote_hostname: obj_q.str_remote_hostname || "?",
nb_remote_avg_ms: obj_q.nb_remote_avg_ms || 0,
});
} else if (obj_q.str_status === "done") {
list_item_results.push({
nb_index: nb_i,
str_type: "done",
str_date: obj_q.str_done_date || null,
str_resolution: obj_q.nb_resolution_x + "x" + obj_q.nb_resolution_y,
});
} }
} }
let list_machine_avgs = [];
if (nb_avg > 0) {
list_machine_avgs.push({ str_hostname: this.str_hostname, nb_avg_ms: nb_avg });
}
for (let str_h of Object.keys(this.map_remote_avgs)) {
if (this.map_remote_avgs[str_h] > 0) {
list_machine_avgs.push({ str_hostname: str_h, nb_avg_ms: this.map_remote_avgs[str_h] });
}
}
this._send_event("render-progress", { this._send_event("render-progress", {
nb_current: this.nb_current_index, nb_current: this.nb_current_index,
nb_total: this.list_queue.length, nb_total: this.list_queue.length,
@@ -375,9 +451,57 @@ class QueueManager {
list_skipped: list_skipped, list_skipped: list_skipped,
list_stopped: list_stopped, list_stopped: list_stopped,
list_skipped_paths: list_skipped_paths, list_skipped_paths: list_skipped_paths,
list_rendering_remote: list_rendering_remote,
list_item_results: list_item_results,
str_hostname: this.str_hostname,
nb_avg_render_ms: nb_avg,
list_machine_avgs: list_machine_avgs,
}); });
} }
_get_placeholder_content() {
let nb_avg = this.nb_completed_renders > 0
? Math.round(this.nb_total_render_ms / this.nb_completed_renders)
: 0;
return JSON.stringify({ str_hostname: this.str_hostname, nb_avg_ms: nb_avg });
}
_read_placeholder(obj_item) {
try {
let str_content = fs.readFileSync(obj_item.str_expected_file, "utf-8");
let obj_data = JSON.parse(str_content);
obj_item.str_remote_hostname = obj_data.str_hostname || "?";
obj_item.nb_remote_avg_ms = obj_data.nb_avg_ms || 0;
if (obj_data.str_hostname && obj_data.nb_avg_ms > 0) {
this.map_remote_avgs[obj_data.str_hostname] = obj_data.nb_avg_ms;
}
} catch (obj_parse_err) {
obj_item.str_remote_hostname = "?";
obj_item.nb_remote_avg_ms = 0;
}
}
_check_remote_completions() {
for (let obj_q of this.list_queue) {
if (obj_q.str_status !== "rendering_remote") {
continue;
}
try {
if (fs.existsSync(obj_q.str_expected_file)) {
let nb_size = fs.statSync(obj_q.str_expected_file).size;
if (nb_size > NB_PLACEHOLDER_MAX_SIZE) {
obj_q.str_status = "skipped";
obj_q.str_done_date = fs.statSync(obj_q.str_expected_file).mtime.toISOString();
}
} else {
obj_q.str_status = "pending";
}
} catch (obj_check_err) {
// ignore
}
}
}
_send_log(str_message) { _send_log(str_message) {
this._send_event("log", str_message); this._send_event("log", str_message);
} }

View File

@@ -40,7 +40,7 @@ const ProgressBar = {
let obj_frame_label = document.getElementById("label_current_frame"); let obj_frame_label = document.getElementById("label_current_frame");
obj_frame_label.textContent = nb_frame !== null && nb_frame !== undefined ? String(nb_frame) : "-"; obj_frame_label.textContent = nb_frame !== null && nb_frame !== undefined ? String(nb_frame) : "-";
RenderQueue.update_progress(nb_current, obj_data.nb_last_render_ms || 0, obj_data.str_last_image_path || null, obj_data.list_skipped || [], obj_data.list_stopped || [], obj_data.list_skipped_paths || []); RenderQueue.update_progress(obj_data);
}, },
reset: () => { reset: () => {

View File

@@ -3,6 +3,9 @@ const RenderQueue = {
nb_total_render_ms: 0, nb_total_render_ms: 0,
nb_completed_renders: 0, nb_completed_renders: 0,
nb_last_current: 0, nb_last_current: 0,
list_machine_avgs: [],
nb_local_avg_ms: 0,
str_hostname: "",
init: () => { init: () => {
// Initialized on demand // Initialized on demand
@@ -13,6 +16,9 @@ const RenderQueue = {
RenderQueue.nb_total_render_ms = 0; RenderQueue.nb_total_render_ms = 0;
RenderQueue.nb_completed_renders = 0; RenderQueue.nb_completed_renders = 0;
RenderQueue.nb_last_current = 0; RenderQueue.nb_last_current = 0;
RenderQueue.list_machine_avgs = [];
RenderQueue.nb_local_avg_ms = 0;
RenderQueue.str_hostname = "";
let list_enabled = []; let list_enabled = [];
for (let obj_cam of list_cameras) { for (let obj_cam of list_cameras) {
@@ -32,6 +38,7 @@ const RenderQueue = {
str_image_path: null, str_image_path: null,
obj_dom_el: null, obj_dom_el: null,
obj_dom_icon: null, obj_dom_icon: null,
obj_dom_result: null,
str_dom_status: null, str_dom_status: null,
is_click_bound: false, is_click_bound: false,
}); });
@@ -60,6 +67,7 @@ const RenderQueue = {
str_image_path: null, str_image_path: null,
obj_dom_el: null, obj_dom_el: null,
obj_dom_icon: null, obj_dom_icon: null,
obj_dom_result: null,
str_dom_status: null, str_dom_status: null,
is_click_bound: false, is_click_bound: false,
}); });
@@ -101,12 +109,20 @@ const RenderQueue = {
obj_frame.classList.add("text-light-emphasis"); obj_frame.classList.add("text-light-emphasis");
obj_frame.textContent = "F" + obj_item.nb_frame; obj_frame.textContent = "F" + obj_item.nb_frame;
let obj_result = document.createElement("small");
obj_result.classList.add("text-light-emphasis", "queue-item-result");
obj_result.style.minWidth = "140px";
obj_result.style.textAlign = "right";
obj_result.style.fontSize = "0.75em";
obj_el.appendChild(obj_icon); obj_el.appendChild(obj_icon);
obj_el.appendChild(obj_name); obj_el.appendChild(obj_name);
obj_el.appendChild(obj_frame); obj_el.appendChild(obj_frame);
obj_el.appendChild(obj_result);
obj_item.obj_dom_el = obj_el; obj_item.obj_dom_el = obj_el;
obj_item.obj_dom_icon = obj_icon; obj_item.obj_dom_icon = obj_icon;
obj_item.obj_dom_result = obj_result;
obj_item.str_dom_status = "pending"; obj_item.str_dom_status = "pending";
obj_fragment.appendChild(obj_el); obj_fragment.appendChild(obj_el);
@@ -115,7 +131,21 @@ const RenderQueue = {
obj_container.appendChild(obj_fragment); obj_container.appendChild(obj_fragment);
}, },
update_progress: (nb_current, nb_last_render_ms, str_last_image_path, list_skipped, list_stopped, list_skipped_paths) => { update_progress: (obj_data) => {
let nb_current = obj_data.nb_current || 0;
let nb_last_render_ms = obj_data.nb_last_render_ms || 0;
let str_last_image_path = obj_data.str_last_image_path || null;
let list_skipped = obj_data.list_skipped || [];
let list_stopped = obj_data.list_stopped || [];
let list_skipped_paths = obj_data.list_skipped_paths || [];
let list_rendering_remote = obj_data.list_rendering_remote || [];
let list_item_results = obj_data.list_item_results || [];
let list_machine_avgs = obj_data.list_machine_avgs || [];
RenderQueue.str_hostname = obj_data.str_hostname || "";
RenderQueue.nb_local_avg_ms = obj_data.nb_avg_render_ms || 0;
RenderQueue.list_machine_avgs = list_machine_avgs;
if (nb_current > RenderQueue.nb_last_current && nb_last_render_ms > 0) { if (nb_current > RenderQueue.nb_last_current && nb_last_render_ms > 0) {
RenderQueue.nb_total_render_ms += nb_last_render_ms; RenderQueue.nb_total_render_ms += nb_last_render_ms;
RenderQueue.nb_completed_renders++; RenderQueue.nb_completed_renders++;
@@ -134,9 +164,17 @@ const RenderQueue = {
} }
} }
// Build result map for quick lookup
let map_results = {};
for (let obj_r of list_item_results) {
map_results[obj_r.nb_index] = obj_r;
}
for (let nb_i = 0; nb_i < RenderQueue.list_items.length; nb_i++) { for (let nb_i = 0; nb_i < RenderQueue.list_items.length; nb_i++) {
if (list_stopped && list_stopped.indexOf(nb_i) !== -1) { if (list_stopped && list_stopped.indexOf(nb_i) !== -1) {
RenderQueue.list_items[nb_i].str_status = "stopped"; RenderQueue.list_items[nb_i].str_status = "stopped";
} else if (list_rendering_remote && list_rendering_remote.indexOf(nb_i) !== -1) {
RenderQueue.list_items[nb_i].str_status = "rendering_remote";
} else if (list_skipped && list_skipped.indexOf(nb_i) !== -1) { } else if (list_skipped && list_skipped.indexOf(nb_i) !== -1) {
RenderQueue.list_items[nb_i].str_status = "skipped"; RenderQueue.list_items[nb_i].str_status = "skipped";
} else if (nb_i < nb_current) { } else if (nb_i < nb_current) {
@@ -146,6 +184,11 @@ const RenderQueue = {
} else { } else {
RenderQueue.list_items[nb_i].str_status = "pending"; RenderQueue.list_items[nb_i].str_status = "pending";
} }
// Store result info on item
if (map_results[nb_i]) {
RenderQueue.list_items[nb_i].obj_result = map_results[nb_i];
}
} }
RenderQueue._update_time_display(); RenderQueue._update_time_display();
@@ -163,7 +206,9 @@ const RenderQueue = {
let is_needs_click = (obj_item.str_status === "done" || obj_item.str_status === "skipped") let is_needs_click = (obj_item.str_status === "done" || obj_item.str_status === "skipped")
&& obj_item.str_image_path && !obj_item.is_click_bound; && obj_item.str_image_path && !obj_item.is_click_bound;
if (obj_item.str_status === obj_item.str_dom_status && !is_needs_click) { let is_status_changed = obj_item.str_status !== obj_item.str_dom_status;
if (!is_status_changed && !is_needs_click) {
if (obj_item.str_status === "rendering") { if (obj_item.str_status === "rendering") {
obj_rendering_el = obj_item.obj_dom_el; obj_rendering_el = obj_item.obj_dom_el;
} }
@@ -189,10 +234,18 @@ const RenderQueue = {
} else if (obj_item.str_status === "stopped") { } else if (obj_item.str_status === "stopped") {
str_icon = "mdi-stop-circle"; str_icon = "mdi-stop-circle";
str_color = "text-warning"; str_color = "text-warning";
} else if (obj_item.str_status === "rendering_remote") {
str_icon = "mdi-desktop-classic";
str_color = "text-warning";
} }
obj_item.obj_dom_icon.className = "mdi " + str_icon + " " + str_color; obj_item.obj_dom_icon.className = "mdi " + str_icon + " " + str_color;
// Update result column
if (obj_item.obj_dom_result) {
RenderQueue._update_result_cell(obj_item);
}
if (is_needs_click) { if (is_needs_click) {
obj_item.obj_dom_el.classList.add("queue-item-clickable"); obj_item.obj_dom_el.classList.add("queue-item-clickable");
let str_path = obj_item.str_image_path; let str_path = obj_item.str_image_path;
@@ -210,6 +263,45 @@ const RenderQueue = {
} }
}, },
_update_result_cell: (obj_item) => {
let obj_r = obj_item.obj_result;
if (!obj_r) {
obj_item.obj_dom_result.textContent = "";
return;
}
if (obj_r.str_type === "done") {
let str_date = "";
if (obj_r.str_date) {
let obj_d = new Date(obj_r.str_date);
let str_day = String(obj_d.getDate()).padStart(2, "0");
let str_month = String(obj_d.getMonth() + 1).padStart(2, "0");
let str_hours = String(obj_d.getHours()).padStart(2, "0");
let str_minutes = String(obj_d.getMinutes()).padStart(2, "0");
str_date = str_day + "/" + str_month + " " + str_hours + ":" + str_minutes;
}
let str_res = obj_r.str_resolution || "";
obj_item.obj_dom_result.textContent = str_date + (str_date && str_res ? " | " : "") + str_res;
obj_item.obj_dom_result.className = "text-success queue-item-result";
obj_item.obj_dom_result.style.minWidth = "140px";
obj_item.obj_dom_result.style.textAlign = "right";
obj_item.obj_dom_result.style.fontSize = "0.75em";
} else if (obj_r.str_type === "rendering_remote") {
let str_host = obj_r.str_remote_hostname || "?";
let str_avg = "";
if (obj_r.nb_remote_avg_ms > 0) {
str_avg = " ~" + RenderQueue._format_duration(obj_r.nb_remote_avg_ms) + "/i";
}
obj_item.obj_dom_result.textContent = str_host + str_avg;
obj_item.obj_dom_result.className = "text-warning queue-item-result";
obj_item.obj_dom_result.style.minWidth = "140px";
obj_item.obj_dom_result.style.textAlign = "right";
obj_item.obj_dom_result.style.fontSize = "0.75em";
} else {
obj_item.obj_dom_result.textContent = "";
}
},
mark_existing: (list_existing) => { mark_existing: (list_existing) => {
for (let obj_existing of list_existing) { for (let obj_existing of list_existing) {
if (obj_existing.nb_index < RenderQueue.list_items.length) { if (obj_existing.nb_index < RenderQueue.list_items.length) {
@@ -226,22 +318,55 @@ const RenderQueue = {
return; return;
} }
if (RenderQueue.nb_completed_renders === 0) { let nb_local_avg = RenderQueue.nb_local_avg_ms;
if (nb_local_avg === 0 && RenderQueue.nb_completed_renders > 0) {
nb_local_avg = Math.round(RenderQueue.nb_total_render_ms / RenderQueue.nb_completed_renders);
}
if (nb_local_avg === 0) {
obj_label.innerHTML = ""; obj_label.innerHTML = "";
return; return;
} }
let nb_avg_ms = RenderQueue.nb_total_render_ms / RenderQueue.nb_completed_renders;
let nb_remaining_count = 0; let nb_remaining_count = 0;
for (let obj_item of RenderQueue.list_items) { for (let obj_item of RenderQueue.list_items) {
if (obj_item.str_status !== "done" && obj_item.str_status !== "skipped") { if (obj_item.str_status !== "done" && obj_item.str_status !== "skipped" && obj_item.str_status !== "rendering_remote") {
nb_remaining_count++; nb_remaining_count++;
} }
} }
let nb_remaining_ms = nb_avg_ms * nb_remaining_count; // Part 1 : temps moyen machine actuelle /i
obj_label.innerHTML = '<i class="mdi mdi-clock-outline me-1"></i>' let str_local_avg = RenderQueue._format_duration(nb_local_avg) + "/i";
+ RenderQueue._format_duration(nb_remaining_ms);
// Part 2 : temps restant si machine seule
let nb_remaining_solo_ms = nb_local_avg * nb_remaining_count;
let str_remaining_solo = RenderQueue._format_duration(nb_remaining_solo_ms);
// Part 3 : temps restant multi-machines
let list_avgs = RenderQueue.list_machine_avgs;
let nb_machines_with_data = 0;
let nb_sum_avgs = 0;
for (let obj_m of list_avgs) {
if (obj_m.nb_avg_ms > 0) {
nb_sum_avgs += obj_m.nb_avg_ms;
nb_machines_with_data++;
}
}
let str_remaining_multi = "";
if (nb_machines_with_data > 1) {
let nb_avg_of_avgs = nb_sum_avgs / nb_machines_with_data;
let nb_remaining_multi_ms = (nb_avg_of_avgs * nb_remaining_count) / nb_machines_with_data;
str_remaining_multi = RenderQueue._format_duration(nb_remaining_multi_ms);
}
let str_display = '<i class="mdi mdi-clock-outline me-1"></i>'
+ str_local_avg + " | " + str_remaining_solo;
if (str_remaining_multi) {
str_display += " | " + str_remaining_multi;
}
obj_label.innerHTML = str_display;
}, },
_format_duration: (nb_ms) => { _format_duration: (nb_ms) => {

View File

@@ -1,3 +1,3 @@
{ {
"str_version": "1.4.0" "str_version": "1.5.0"
} }