const RenderQueue = { list_items: [], nb_total_render_ms: 0, nb_completed_renders: 0, nb_last_current: 0, init: () => { // Initialized on demand }, build_display: (str_mode, list_cameras) => { RenderQueue.list_items = []; RenderQueue.nb_total_render_ms = 0; RenderQueue.nb_completed_renders = 0; RenderQueue.nb_last_current = 0; let list_enabled = []; for (let obj_cam of list_cameras) { if (obj_cam.is_enabled) { list_enabled.push(obj_cam); } } if (str_mode === "camera_by_camera") { for (let obj_cam of list_enabled) { let nb_step = obj_cam.nb_frame_step || 1; for (let nb_frame = obj_cam.nb_frame_start; nb_frame <= obj_cam.nb_frame_end; nb_frame += nb_step) { RenderQueue.list_items.push({ str_camera: obj_cam.str_name, nb_frame: nb_frame, str_status: "pending", str_image_path: null, obj_dom_el: null, obj_dom_icon: null, str_dom_status: null, is_click_bound: false, }); } } } else { let nb_min = Infinity; let nb_max = -Infinity; for (let obj_cam of list_enabled) { if (obj_cam.nb_frame_start < nb_min) { nb_min = obj_cam.nb_frame_start; } if (obj_cam.nb_frame_end > nb_max) { nb_max = obj_cam.nb_frame_end; } } for (let nb_frame = nb_min; nb_frame <= nb_max; nb_frame++) { for (let obj_cam of list_enabled) { let nb_cam_step = obj_cam.nb_frame_step || 1; if (nb_frame >= obj_cam.nb_frame_start && nb_frame <= obj_cam.nb_frame_end && (nb_frame - obj_cam.nb_frame_start) % nb_cam_step === 0) { RenderQueue.list_items.push({ str_camera: obj_cam.str_name, nb_frame: nb_frame, str_status: "pending", str_image_path: null, obj_dom_el: null, obj_dom_icon: null, str_dom_status: null, is_click_bound: false, }); } } } } let obj_badge = document.getElementById("badge_queue_count"); obj_badge.textContent = String(RenderQueue.list_items.length); RenderQueue._update_time_display(); RenderQueue._create_dom(); }, _create_dom: () => { let obj_container = document.getElementById("container_render_queue"); obj_container.innerHTML = ""; if (RenderQueue.list_items.length === 0) { obj_container.innerHTML = '
File vide
'; return; } let obj_fragment = document.createDocumentFragment(); for (let obj_item of RenderQueue.list_items) { let obj_el = document.createElement("div"); obj_el.classList.add("list-group-item", "bg-dark", "text-light", "border-secondary", "py-1", "px-3", "d-flex", "align-items-center", "gap-2"); let obj_icon = document.createElement("i"); obj_icon.classList.add("mdi", "mdi-clock-outline", "text-muted"); let obj_name = document.createElement("small"); obj_name.classList.add("flex-grow-1"); obj_name.textContent = obj_item.str_camera; let obj_frame = document.createElement("small"); obj_frame.classList.add("text-light-emphasis"); obj_frame.textContent = "F" + obj_item.nb_frame; obj_el.appendChild(obj_icon); obj_el.appendChild(obj_name); obj_el.appendChild(obj_frame); obj_item.obj_dom_el = obj_el; obj_item.obj_dom_icon = obj_icon; obj_item.str_dom_status = "pending"; obj_fragment.appendChild(obj_el); } obj_container.appendChild(obj_fragment); }, update_progress: (nb_current, nb_last_render_ms, str_last_image_path, list_skipped, list_stopped, list_skipped_paths) => { if (nb_current > RenderQueue.nb_last_current && nb_last_render_ms > 0) { RenderQueue.nb_total_render_ms += nb_last_render_ms; RenderQueue.nb_completed_renders++; } RenderQueue.nb_last_current = nb_current; if (str_last_image_path && nb_current > 0 && nb_current - 1 < RenderQueue.list_items.length) { RenderQueue.list_items[nb_current - 1].str_image_path = str_last_image_path; } if (list_skipped_paths) { for (let obj_sp of list_skipped_paths) { if (obj_sp.nb_index < RenderQueue.list_items.length) { RenderQueue.list_items[obj_sp.nb_index].str_image_path = obj_sp.str_path; } } } for (let nb_i = 0; nb_i < RenderQueue.list_items.length; nb_i++) { if (list_stopped && list_stopped.indexOf(nb_i) !== -1) { RenderQueue.list_items[nb_i].str_status = "stopped"; } else if (list_skipped && list_skipped.indexOf(nb_i) !== -1) { RenderQueue.list_items[nb_i].str_status = "skipped"; } else if (nb_i < nb_current) { RenderQueue.list_items[nb_i].str_status = "done"; } else if (nb_i === nb_current) { RenderQueue.list_items[nb_i].str_status = "rendering"; } else { RenderQueue.list_items[nb_i].str_status = "pending"; } } RenderQueue._update_time_display(); RenderQueue._update_statuses(); }, _update_statuses: () => { let obj_rendering_el = null; for (let obj_item of RenderQueue.list_items) { if (!obj_item.obj_dom_el) { continue; } let is_needs_click = (obj_item.str_status === "done" || obj_item.str_status === "skipped") && obj_item.str_image_path && !obj_item.is_click_bound; if (obj_item.str_status === obj_item.str_dom_status && !is_needs_click) { if (obj_item.str_status === "rendering") { obj_rendering_el = obj_item.obj_dom_el; } continue; } let str_icon = "mdi-clock-outline"; let str_color = "text-muted"; if (obj_item.str_status === "rendering") { str_icon = "mdi-loading mdi-spin"; str_color = "text-primary"; obj_rendering_el = obj_item.obj_dom_el; } else if (obj_item.str_status === "done") { str_icon = "mdi-check-circle"; str_color = "text-success"; } else if (obj_item.str_status === "error") { str_icon = "mdi-alert-circle"; str_color = "text-danger"; } else if (obj_item.str_status === "skipped") { str_icon = "mdi-skip-next-circle"; str_color = "text-info"; } else if (obj_item.str_status === "stopped") { str_icon = "mdi-stop-circle"; str_color = "text-warning"; } obj_item.obj_dom_icon.className = "mdi " + str_icon + " " + str_color; if (is_needs_click) { obj_item.obj_dom_el.classList.add("queue-item-clickable"); let str_path = obj_item.str_image_path; obj_item.obj_dom_el.addEventListener("click", () => { PreviewPanel.show_image(str_path); }); obj_item.is_click_bound = true; } obj_item.str_dom_status = obj_item.str_status; } if (obj_rendering_el) { obj_rendering_el.scrollIntoView({ behavior: "smooth", block: "center" }); } }, mark_existing: (list_existing) => { for (let obj_existing of list_existing) { if (obj_existing.nb_index < RenderQueue.list_items.length) { RenderQueue.list_items[obj_existing.nb_index].str_status = "skipped"; RenderQueue.list_items[obj_existing.nb_index].str_image_path = obj_existing.str_path; } } RenderQueue._update_statuses(); }, _update_time_display: () => { let obj_label = document.getElementById("label_queue_time_estimate"); if (!obj_label) { return; } if (RenderQueue.nb_completed_renders === 0) { obj_label.innerHTML = ""; return; } let nb_avg_ms = RenderQueue.nb_total_render_ms / RenderQueue.nb_completed_renders; let nb_remaining_count = 0; for (let obj_item of RenderQueue.list_items) { if (obj_item.str_status !== "done" && obj_item.str_status !== "skipped") { nb_remaining_count++; } } let nb_remaining_ms = nb_avg_ms * nb_remaining_count; obj_label.innerHTML = '' + RenderQueue._format_duration(nb_remaining_ms); }, _format_duration: (nb_ms) => { let nb_total_seconds = Math.ceil(nb_ms / 1000); let nb_days = Math.floor(nb_total_seconds / 86400); nb_total_seconds %= 86400; let nb_hours = Math.floor(nb_total_seconds / 3600); nb_total_seconds %= 3600; let nb_minutes = Math.floor(nb_total_seconds / 60); let nb_seconds = nb_total_seconds % 60; let str_result = ""; if (nb_days > 0) { str_result += nb_days + "j "; } if (nb_hours > 0 || nb_days > 0) { str_result += nb_hours + "h "; } if (nb_minutes > 0 || nb_hours > 0 || nb_days > 0) { str_result += nb_minutes + "m "; } str_result += nb_seconds + "s"; return str_result; }, };