better queue render

This commit is contained in:
sorlinv
2026-02-26 17:32:00 +01:00
parent a65700175b
commit 20a016bd3a
12 changed files with 541 additions and 12 deletions

View File

@@ -1,6 +1,7 @@
const BlenderProcess = require("./BlenderProcess.js");
const path = require("path");
const fs = require("fs");
const { Notification } = require("electron");
const STR_STATUS_IDLE = "idle";
const STR_STATUS_RUNNING = "running";
@@ -15,6 +16,11 @@ class QueueManager {
this.obj_current_process = null;
this.nb_last_render_ms = 0;
this.str_last_image_path = null;
this.obj_notification_config = { is_notify_each_image: false, is_notify_all_done: true };
}
set_notification_config(obj_config) {
this.obj_notification_config = obj_config || { is_notify_each_image: false, is_notify_all_done: true };
}
start(obj_config) {
@@ -56,10 +62,39 @@ class QueueManager {
this.obj_current_process = null;
}
if (this.nb_current_index < this.list_queue.length) {
let obj_item = this.list_queue[this.nb_current_index];
if (obj_item.str_status === "rendering") {
obj_item.str_status = "stopped";
}
}
this._send_log("Rendu arrete.");
this._send_progress();
return Promise.resolve({ is_success: true });
}
check_queue(obj_config) {
let list_queue = this._build_queue(obj_config);
let list_existing = [];
for (let nb_i = 0; nb_i < list_queue.length; nb_i++) {
let obj_item = list_queue[nb_i];
try {
if (fs.existsSync(obj_item.str_expected_file)) {
let nb_size = fs.statSync(obj_item.str_expected_file).size;
if (nb_size > 0) {
list_existing.push({ nb_index: nb_i, str_path: obj_item.str_expected_file });
}
}
} catch (obj_err) {
// Fichier inaccessible, on ignore
}
}
return Promise.resolve({ list_existing: list_existing, nb_total: list_queue.length });
}
_build_queue(obj_config) {
let list_queue = [];
let str_blend_path = obj_config.str_blend_file;
@@ -159,11 +194,21 @@ class QueueManager {
let nb_skip_count = 0;
while (this.nb_current_index < this.list_queue.length && this.str_overwrite_mode === "skip") {
let obj_check = this.list_queue[this.nb_current_index];
if (!fs.existsSync(obj_check.str_expected_file)) {
let is_exists = false;
let nb_size = 0;
try {
is_exists = fs.existsSync(obj_check.str_expected_file);
if (is_exists) {
nb_size = fs.statSync(obj_check.str_expected_file).size;
}
} catch (obj_fs_err) {
is_exists = false;
}
if (!is_exists) {
break;
}
let obj_stats = fs.statSync(obj_check.str_expected_file);
if (obj_stats.size === 0) {
if (nb_size === 0) {
this._send_log("Placeholder vide detecte, re-rendu : " + obj_check.str_camera_name + " F" + obj_check.nb_frame);
break;
}
@@ -181,10 +226,33 @@ class QueueManager {
this.str_status = STR_STATUS_IDLE;
this._send_log("Tous les rendus sont termines !");
this._send_event("render-complete", { is_all_done: true });
if (this.obj_notification_config.is_notify_all_done) {
this._send_notification("Rendus termines", "Tous les rendus de la file sont termines (" + this.list_queue.length + " elements).");
}
return;
}
let obj_item = this.list_queue[this.nb_current_index];
// Re-verification avant rendu : rattrape les fichiers non detectes par le batch skip
if (this.str_overwrite_mode === "skip") {
try {
if (fs.existsSync(obj_item.str_expected_file)) {
let nb_recheck_size = fs.statSync(obj_item.str_expected_file).size;
if (nb_recheck_size > 0) {
obj_item.str_status = "skipped";
this._send_log("Skip : " + obj_item.str_camera_name + " F" + obj_item.nb_frame + " (existant)");
this.nb_current_index++;
this._send_progress();
this._process_next();
return;
}
}
} catch (obj_recheck_err) {
// Erreur fs, on continue le rendu
}
}
obj_item.str_status = "rendering";
if (this.str_overwrite_mode === "skip") {
@@ -234,6 +302,10 @@ class QueueManager {
this._send_event("preview-update", str_image);
this._send_log("Termine : " + str_image);
if (this.obj_notification_config.is_notify_each_image) {
this._send_notification("Rendu termine", obj_item.str_camera_name + " — Frame " + obj_item.nb_frame);
}
this.nb_current_index++;
this._send_progress();
this._process_next();
@@ -260,11 +332,12 @@ class QueueManager {
this.nb_last_render_ms = Date.now() - nb_start;
this.str_last_image_path = null;
this._send_log("ERREUR : " + obj_err.str_message);
let str_err_msg = obj_err.str_message || obj_err.message || String(obj_err);
this._send_log("ERREUR : " + str_err_msg);
this._send_event("render-error", {
str_camera: obj_item.str_camera_name,
nb_frame: obj_item.nb_frame,
str_error: obj_err.str_message,
str_error: str_err_msg,
});
this.nb_current_index++;
@@ -276,9 +349,14 @@ class QueueManager {
_send_progress() {
let obj_item = this.list_queue[this.nb_current_index] || {};
let list_skipped = [];
let list_stopped = [];
let list_skipped_paths = [];
for (let nb_i = 0; nb_i < this.list_queue.length; nb_i++) {
if (this.list_queue[nb_i].str_status === "skipped") {
list_skipped.push(nb_i);
list_skipped_paths.push({ nb_index: nb_i, str_path: this.list_queue[nb_i].str_expected_file });
} else if (this.list_queue[nb_i].str_status === "stopped") {
list_stopped.push(nb_i);
}
}
this._send_event("render-progress", {
@@ -290,6 +368,8 @@ class QueueManager {
nb_last_render_ms: this.nb_last_render_ms,
str_last_image_path: this.str_last_image_path,
list_skipped: list_skipped,
list_stopped: list_stopped,
list_skipped_paths: list_skipped_paths,
});
}
@@ -302,6 +382,13 @@ class QueueManager {
this.obj_window.webContents.send(str_channel, obj_data);
}
}
_send_notification(str_title, str_body) {
if (Notification.isSupported()) {
let obj_notif = new Notification({ title: str_title, body: str_body });
obj_notif.show();
}
}
}
module.exports = QueueManager;