use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Mutex;
use ncursesw;
use ncursesw::{WINDOW, Orientation, NCurseswError};
use crate::window::Window;
use crate::ncurses::{INITSCR_CALLED, INITSCR_ALREADY_CALLED, INITSCR_NOT_CALLED};
const MAX_LINES: usize = 5;
lazy_static! {
static ref RIPOFFCOUNT: AtomicUsize = AtomicUsize::new(0);
static ref RIPOFFLINES: Mutex<Vec<(Window, i32)>> = Mutex::new(Vec::with_capacity(MAX_LINES));
}
macro_rules! ripoff_init_fn {
($f: ident, $n: expr) => {
#[no_mangle]
extern fn $f(win: WINDOW, cols: i32) -> i32 {
RIPOFFLINES.lock().unwrap().insert($n, (Window::from(win, false), cols));
ncursesw::shims::constants::OK
}
}
}
ripoff_init_fn!(ripoff_init0, 0);
ripoff_init_fn!(ripoff_init1, 1);
ripoff_init_fn!(ripoff_init2, 2);
ripoff_init_fn!(ripoff_init3, 3);
ripoff_init_fn!(ripoff_init4, 4);
pub fn ripoffline(orientation: Orientation) -> result!(usize) {
if INITSCR_CALLED.load(Ordering::SeqCst) {
panic!(INITSCR_ALREADY_CALLED.to_string());
};
let number = RIPOFFCOUNT.fetch_add(1, Ordering::SeqCst);
assert!(number < MAX_LINES, "define_ripoff_line() : number={} > {}", number, MAX_LINES);
match ncursesw::ripoffline(orientation, match number {
0 => ripoff_init0,
1 => ripoff_init1,
2 => ripoff_init2,
3 => ripoff_init3,
4 => ripoff_init4,
_ => unreachable!()
}) {
Err(e) => Err(e),
_ => Ok(number)
}
}
pub fn update_ripoffline<F>(number: usize, func: F) -> result!(()) where F: Fn(&Window, i32) -> result!(()) {
if !INITSCR_CALLED.load(Ordering::SeqCst) {
panic!(INITSCR_NOT_CALLED.to_string());
};
assert!(number < MAX_LINES, "update_ripoffline() : number={} > {}", number, MAX_LINES);
let ripoff = &RIPOFFLINES.lock().unwrap()[number];
assert!(!ripoff.0.handle().is_null(), "update_ripoffline() : ripoff.0.get_handle().is_null()");
func(&ripoff.0, ripoff.1)
}