use async_trait::async_trait;
use r3bl_rs_utils_core::*;
use super::*;
use crate::{tui::DEBUG_SHOW_PIPELINE, *};
pub async fn paint(
pipeline: &RenderPipeline,
flush_kind: FlushKind,
shared_tw_data: &SharedTWData,
) {
let mut skip_flush = false;
if let FlushKind::ClearBeforeFlush = flush_kind {
RenderOp::default().clear_before_flush();
}
let mut hoisted_op_vec: Vec<RenderOp> = vec![];
for z_order in RENDER_ORDERED_Z_ORDER_ARRAY.iter() {
if let Some(render_ops) = pipeline.get(z_order) {
for command_ref in render_ops.iter() {
if let RenderOp::RequestShowCaretAtPositionAbs(_)
| RenderOp::RequestShowCaretAtPositionRelTo(_, _) = command_ref
{
hoisted_op_vec.push(command_ref.clone());
} else {
route_paint_render_op_to_backend(&mut skip_flush, command_ref, shared_tw_data).await;
}
}
}
}
if hoisted_op_vec.len() > 1 {
log_no_err!(
WARN,
"🥕 Too many requests to draw caret (some will be clobbered): {:?}",
hoisted_op_vec,
);
}
for command_ref in &hoisted_op_vec {
route_paint_render_op_to_backend(&mut skip_flush, command_ref, shared_tw_data).await;
}
if !skip_flush {
RenderOp::default().flush()
};
call_if_true!(DEBUG_SHOW_PIPELINE, {
log_no_err!(
INFO,
"🎨 render_pipeline::paint() ok ✅: pipeline: \n{:?}",
pipeline,
);
});
}
pub async fn sanitize_and_save_abs_position(
orig_abs_pos: Position,
shared_tw_data: &SharedTWData,
) -> Position {
let Size {
cols: max_cols,
rows: max_rows,
} = shared_tw_data.read().await.size;
let mut sanitized_abs_pos: Position = orig_abs_pos;
if orig_abs_pos.col > max_cols {
sanitized_abs_pos.col = max_cols;
}
if orig_abs_pos.row > max_rows {
sanitized_abs_pos.row = max_rows;
}
shared_tw_data.write().await.cursor_position = sanitized_abs_pos;
debug(orig_abs_pos, sanitized_abs_pos);
return sanitized_abs_pos;
fn debug(orig_pos: Position, sanitized_pos: Position) {
call_if_true!(DEBUG_TUI_MOD, {
if sanitized_pos != orig_pos {
log_no_err!(
INFO,
"pipeline : 📍🗜️ Attempt to set cursor position {:?} \
outside of terminal window; clamping to nearest edge of window {:?}",
orig_pos,
sanitized_pos
);
}
});
call_if_true!(DEBUG_SHOW_PIPELINE_EXPANDED, {
log_no_err!(
INFO,
"pipeline : 📍 Save the cursor position {:?} \
to SharedTWData",
sanitized_pos
);
});
}
}
pub async fn route_paint_render_op_to_backend(
skip_flush: &mut bool,
render_op: &RenderOp,
shared_tw_data: &SharedTWData,
) {
match TERMINAL_LIB_BACKEND {
TerminalLibBackend::Crossterm => {
RenderOpImplCrossterm {}
.paint(skip_flush, render_op, shared_tw_data)
.await;
}
TerminalLibBackend::Termion => todo!(), }
}
#[async_trait]
pub trait PaintRenderOp {
async fn paint(&self, skip_flush: &mut bool, render_op: &RenderOp, shared_tw_data: &SharedTWData);
}