rust: finish NcDirect & Notcurses methods.

- add missing NcDirect methods: raster_frame & render_frame.
- finish refactoring Notcurses methods.
  - turn more Option returns into NcResult.
This commit is contained in:
joseLuís 2020-12-25 20:10:31 +01:00
parent 6049e07d27
commit 36e81a573a
4 changed files with 102 additions and 56 deletions

View File

@ -23,9 +23,7 @@ fn main() -> NcResult<()> {
wc = '\u{4e00}'; wc = '\u{4e00}';
} }
if nc.render() == NCRESULT_ERR { nc.render()?;
break;
}
} }
nc.stop()?; nc.stop()?;
Ok(()) Ok(())

View File

@ -5,8 +5,8 @@ use core::ptr::{null, null_mut};
use crate::ffi::sigset_t; use crate::ffi::sigset_t;
use crate::{ use crate::{
cstring, error, NcAlign, NcBlitter, NcChannelPair, NcColor, NcDimension, NcDirect, cstring, error, NcAlign, NcBlitter, NcChannelPair, NcColor, NcDimension, NcDirect,
NcDirectFlags, NcEgc, NcError, NcInput, NcPaletteIndex, NcResult, NcRgb, NcScale, NcStyleMask, NcDirectFlags, NcEgc, NcError, NcInput, NcPaletteIndex, NcPlane, NcResult, NcRgb, NcScale,
NcTime, NCRESULT_ERR, NcStyleMask, NcTime, NCRESULT_ERR,
}; };
/// # `NcDirect` constructors and destructors /// # `NcDirect` constructors and destructors
@ -48,7 +48,7 @@ impl NcDirect {
} }
} }
/// ## NcDirect methods: clear, flush, render_image /// ## NcDirect methods: clear, flush, render
impl NcDirect { impl NcDirect {
/// Clears the screen. /// Clears the screen.
/// ///
@ -64,18 +64,63 @@ impl NcDirect {
error![unsafe { crate::ncdirect_flush(self) }] error![unsafe { crate::ncdirect_flush(self) }]
} }
/// Takes the result of [render_frame()][NcDirect#method.render_frame]
/// and writes it to the output.
///
/// The `align`, `blitter`, and `scale` arguments must be the same as those
/// passed to render_frame().
///
/// *C style function: [ncdirect_render_image()][crate::ncdirect_render_image].*
pub fn raster_frame(
&mut self,
faken: &mut NcPlane,
align: NcAlign,
blitter: NcBlitter,
scale: NcScale,
) -> NcResult<()> {
error![
unsafe { crate::ncdirect_raster_frame(self, faken, align, blitter, scale) },
(),
"Rastering frame"
]
}
/// Renders an image using the specified blitter and scaling,
/// but do not write the result.
///
/// The image may be arbitrarily many rows -- the output will scroll --
/// but will only occupy the column of the cursor, and those to the right.
///
/// To actually write (and free) this, invoke ncdirect_raster_frame().
/// and writes it to the output.
///
/// The `align`, `blitter`, and `scale` arguments must be the same as those
/// passed to render_frame().
///
/// *C style function: [ncdirect_render_image()][crate::ncdirect_render_image].*
pub fn render_frame<'a>(
&mut self,
filename: &str,
blitter: NcBlitter,
scale: NcScale,
) -> NcResult<&'a mut NcPlane> {
let res = unsafe { crate::ncdirect_render_frame(self, cstring![filename], blitter, scale) };
if res == null_mut() {
return Err(NcError::with_msg(NCRESULT_ERR, "Rendering frame"));
}
Ok(unsafe { &mut *res })
}
/// Displays an image using the specified blitter and scaling. /// Displays an image using the specified blitter and scaling.
/// ///
/// The image may be arbitrarily many rows -- the output will scroll -- but /// The image may be arbitrarily many rows -- the output will scroll -- but
/// will only occupy the column of the cursor, and those to the right. /// will only occupy the column of the cursor, and those to the right.
/// ///
/// The render/raster process can be split by using
/// [render_frame()][#method.render_frame] and
/// [raster_frame()][#method.raster_frame].
/// ///
/// *C style function: [ncdirect_render_image()][crate::ncdirect_render_image].* /// *C style function: [ncdirect_render_image()][crate::ncdirect_render_image].*
//
// TODO:
// The render/raster process can be split by using
// [render_frame()][#method.render_frame] and
// [raster_frame()][#method.raster_frame].
pub fn render_image( pub fn render_image(
&mut self, &mut self,
filename: &str, filename: &str,

View File

@ -37,6 +37,8 @@
//W ncdirect_palette_size //W ncdirect_palette_size
// X ncdirect_printf_aligned // X ncdirect_printf_aligned
//W ncdirect_putstr //W ncdirect_putstr
//W ncdirect_raster_frame
//W ncdirect_render_frame
//W ncdirect_render_image //W ncdirect_render_image
//W ncdirect_rounded_box //W ncdirect_rounded_box
//W ncdirect_stop //W ncdirect_stop

View File

@ -5,9 +5,9 @@ use std::ffi::CStr;
use crate::{ use crate::{
cstring, error, notcurses_init, NcAlign, NcBlitter, NcChannelPair, NcDimension, NcEgc, NcError, cstring, error, notcurses_init, NcAlign, NcBlitter, NcChannelPair, NcDimension, NcEgc, NcError,
NcFile, NcInput, NcIntResult, NcLogLevel, NcPlane, NcResult, NcScale, NcSignalSet, NcStats, NcFile, NcInput, NcLogLevel, NcPlane, NcResult, NcScale, NcSignalSet, NcStats, NcStyleMask,
NcStyleMask, NcTime, Notcurses, NotcursesOptions, NCOPTION_NO_ALTERNATE_SCREEN, NcTime, Notcurses, NotcursesOptions, NCOPTION_NO_ALTERNATE_SCREEN, NCOPTION_SUPPRESS_BANNERS,
NCOPTION_SUPPRESS_BANNERS, NCRESULT_ERR, NCRESULT_OK, NCRESULT_ERR,
}; };
/// # `NotcursesOptions` Constructors /// # `NotcursesOptions` Constructors
@ -130,8 +130,8 @@ impl Notcurses {
/// [NCALIGN_UNALIGNED][crate::NCALIGN_UNALIGNED] or invalid [NcAlign]. /// [NCALIGN_UNALIGNED][crate::NCALIGN_UNALIGNED] or invalid [NcAlign].
/// ///
/// *C style function: [notcurses_align()][crate::notcurses_align].* /// *C style function: [notcurses_align()][crate::notcurses_align].*
pub fn align(availcols: NcDimension, align: NcAlign, cols: NcDimension) -> NcIntResult { pub fn align(availcols: NcDimension, align: NcAlign, cols: NcDimension) -> NcResult<()> {
crate::notcurses_align(availcols, align, cols) error![crate::notcurses_align(availcols, align, cols)]
} }
/// Retrieves the current contents of the specified [NcCell][crate::NcCell] /// Retrieves the current contents of the specified [NcCell][crate::NcCell]
@ -230,8 +230,8 @@ impl Notcurses {
/// Immediate effect (no need for a call to notcurses_render()). /// Immediate effect (no need for a call to notcurses_render()).
/// ///
/// *C style function: [notcurses_cursor_disable()][crate::notcurses_cursor_disable].* /// *C style function: [notcurses_cursor_disable()][crate::notcurses_cursor_disable].*
pub fn cursor_disable(&mut self) -> NcIntResult { pub fn cursor_disable(&mut self) -> NcResult<()> {
unsafe { crate::notcurses_cursor_disable(self) } error![unsafe { crate::notcurses_cursor_disable(self) }]
} }
/// Enables the terminal's cursor, if supported, placing it at `y`, `x`. /// Enables the terminal's cursor, if supported, placing it at `y`, `x`.
@ -240,8 +240,8 @@ impl Notcurses {
/// It is an error if `y`, `x` lies outside the standard plane. /// It is an error if `y`, `x` lies outside the standard plane.
/// ///
/// *C style function: [notcurses_cursor_enable()][crate::notcurses_cursor_enable].* /// *C style function: [notcurses_cursor_enable()][crate::notcurses_cursor_enable].*
pub fn cursor_enable(&mut self, y: NcDimension, x: NcDimension) -> NcIntResult { pub fn cursor_enable(&mut self, y: NcDimension, x: NcDimension) -> NcResult<()> {
unsafe { crate::notcurses_cursor_enable(self, y as i32, x as i32) } error![unsafe { crate::notcurses_cursor_enable(self, y as i32, x as i32) }]
} }
/// Dumps Notcurses state to the supplied `debugfp`. /// Dumps Notcurses state to the supplied `debugfp`.
@ -284,7 +284,7 @@ impl Notcurses {
time: Option<NcTime>, time: Option<NcTime>,
sigmask: Option<&mut NcSignalSet>, sigmask: Option<&mut NcSignalSet>,
input: Option<&mut NcInput>, input: Option<&mut NcInput>,
) -> Option<char> { ) -> NcResult<char> {
let ntime; let ntime;
if let Some(time) = time { if let Some(time) = time {
ntime = &time as *const _; ntime = &time as *const _;
@ -308,9 +308,9 @@ impl Notcurses {
core::char::from_u32_unchecked(crate::notcurses_getc(self, ntime, nsigmask, ninput)) core::char::from_u32_unchecked(crate::notcurses_getc(self, ntime, nsigmask, ninput))
}; };
if c as u32 as i32 == NCRESULT_ERR { if c as u32 as i32 == NCRESULT_ERR {
return None; return Err(NcError::new(NCRESULT_ERR));
} }
Some(c) Ok(c)
} }
/// ///
@ -334,20 +334,19 @@ impl Notcurses {
/// with stdin (but it might be!). /// with stdin (but it might be!).
/// ///
/// *C style function: [notcurses_inputready_fd()][crate::notcurses_inputready_fd].* /// *C style function: [notcurses_inputready_fd()][crate::notcurses_inputready_fd].*
pub fn inputready_fd(&mut self) -> NcIntResult { pub fn inputready_fd(&mut self) -> NcResult<()> {
unsafe { crate::notcurses_inputready_fd(self) } error![unsafe { crate::notcurses_inputready_fd(self) }]
} }
/// Returns an [NcBlitter] from a string representation. /// Returns an [NcBlitter] from a string representation.
/// ///
/// *C style function: [notcurses_lex_blitter()][crate::notcurses_lex_blitter].* /// *C style function: [notcurses_lex_blitter()][crate::notcurses_lex_blitter].*
pub fn lex_blitter(op: &str) -> Option<NcBlitter> { pub fn lex_blitter(op: &str) -> NcResult<NcBlitter> {
let mut blitter = 0; let mut blitter = 0;
let res = unsafe { crate::notcurses_lex_blitter(cstring![op], &mut blitter) }; error![
if res == NCRESULT_OK { unsafe { crate::notcurses_lex_blitter(cstring![op], &mut blitter) },
return Some(blitter); blitter, "Invalid blitter name"
} ]
None
} }
/// Lexes a margin argument according to the standard Notcurses definition. /// Lexes a margin argument according to the standard Notcurses definition.
@ -356,36 +355,35 @@ impl Notcurses {
/// or there can be four numbers separated by commas. /// or there can be four numbers separated by commas.
/// ///
/// *C style function: [notcurses_lex_margins()][crate::notcurses_lex_margins].* /// *C style function: [notcurses_lex_margins()][crate::notcurses_lex_margins].*
pub fn lex_margins(op: &str, options: &mut NotcursesOptions) -> NcIntResult { pub fn lex_margins(op: &str, options: &mut NotcursesOptions) -> NcResult<()> {
unsafe { crate::notcurses_lex_margins(cstring![op], options) } error![unsafe { crate::notcurses_lex_margins(cstring![op], options) }]
} }
/// Returns an [NcScale] from a string representation. /// Returns an [NcScale] from a string representation.
/// ///
/// *C style function: [notcurses_lex_scalemode()][crate::notcurses_lex_scalemode].* /// *C style function: [notcurses_lex_scalemode()][crate::notcurses_lex_scalemode].*
pub fn lex_scalemode(op: &str) -> Option<NcScale> { pub fn lex_scalemode(op: &str) -> NcResult<NcScale> {
let mut scalemode = 0; let mut scalemode = 0;
let res = unsafe { crate::notcurses_lex_scalemode(cstring![op], &mut scalemode) }; error![
if res == NCRESULT_OK { unsafe { crate::notcurses_lex_scalemode(cstring![op], &mut scalemode) },
return Some(scalemode); scalemode
} ]
None
} }
/// Disables signals originating from the terminal's line discipline, i.e. /// Disables signals originating from the terminal's line discipline, i.e.
/// SIGINT (^C), SIGQUIT (^), and SIGTSTP (^Z). They are enabled by default. /// SIGINT (^C), SIGQUIT (^), and SIGTSTP (^Z). They are enabled by default.
/// ///
/// *C style function: [notcurses_linesigs_disable()][crate::notcurses_linesigs_disable].* /// *C style function: [notcurses_linesigs_disable()][crate::notcurses_linesigs_disable].*
pub fn linesigs_disable(&mut self) -> NcIntResult { pub fn linesigs_disable(&mut self) -> NcResult<()> {
unsafe { crate::notcurses_linesigs_disable(self) } error![unsafe { crate::notcurses_linesigs_disable(self) }]
} }
/// Restores signals originating from the terminal's line discipline, i.e. /// Restores signals originating from the terminal's line discipline, i.e.
/// SIGINT (^C), SIGQUIT (^), and SIGTSTP (^Z), if disabled. /// SIGINT (^C), SIGQUIT (^), and SIGTSTP (^Z), if disabled.
/// ///
/// *C style function: [notcurses_linesigs_enable()][crate::notcurses_linesigs_enable].* /// *C style function: [notcurses_linesigs_enable()][crate::notcurses_linesigs_enable].*
pub fn linesigs_enable(&mut self) -> NcIntResult { pub fn linesigs_enable(&mut self) -> NcResult<()> {
unsafe { crate::notcurses_linesigs_enable(self) } error![unsafe { crate::notcurses_linesigs_enable(self) }]
} }
/// Disables mouse events. /// Disables mouse events.
@ -393,8 +391,8 @@ impl Notcurses {
/// Any events in the input queue can still be delivered. /// Any events in the input queue can still be delivered.
/// ///
/// *C style function: [notcurses_mouse_disable()][crate::notcurses_mouse_disable].* /// *C style function: [notcurses_mouse_disable()][crate::notcurses_mouse_disable].*
pub fn mouse_disable(&mut self) -> NcIntResult { pub fn mouse_disable(&mut self) -> NcResult<()> {
unsafe { crate::notcurses_mouse_disable(self) } error![unsafe { crate::notcurses_mouse_disable(self) }]
} }
/// Enable the mouse in "button-event tracking" mode with focus detection /// Enable the mouse in "button-event tracking" mode with focus detection
@ -404,8 +402,8 @@ impl Notcurses {
/// published to [getc()][Notcurses#method.getc]. /// published to [getc()][Notcurses#method.getc].
/// ///
/// *C style function: [notcurses_mouse_enable()][crate::notcurses_mouse_enable].* /// *C style function: [notcurses_mouse_enable()][crate::notcurses_mouse_enable].*
pub fn mouse_enable(&mut self) -> NcIntResult { pub fn mouse_enable(&mut self) -> NcResult<()> {
unsafe { crate::notcurses_mouse_enable(self) } error![unsafe { crate::notcurses_mouse_enable(self) }]
} }
/// Returns the number of simultaneous colors claimed to be supported, /// Returns the number of simultaneous colors claimed to be supported,
@ -429,16 +427,19 @@ impl Notcurses {
/// ///
/// *C style function: [notcurses_refresh()][crate::notcurses_refresh].* /// *C style function: [notcurses_refresh()][crate::notcurses_refresh].*
// //
// TODO: try returning Result<(NcDimension, NcDimension), NcIntResult> pub fn refresh(&mut self) -> NcResult<(NcDimension, NcDimension)> {
pub fn refresh(&mut self, y: &mut NcDimension, x: &mut NcDimension) -> NcIntResult { let (mut y, mut x) = (0, 0);
unsafe { crate::notcurses_refresh(self, &mut (*y as i32), &mut (*x as i32)) } error![
unsafe { crate::notcurses_refresh(self, &mut y, &mut x) },
(y as NcDimension, x as NcDimension)
]
} }
/// Renders and rasterizes the standard pile in one shot. Blocking call. /// Renders and rasterizes the standard pile in one shot. Blocking call.
/// ///
/// *C style function: [notcurses_render()][crate::notcurses_render].* /// *C style function: [notcurses_render()][crate::notcurses_render].*
pub fn render(&mut self) -> NcIntResult { pub fn render(&mut self) -> NcResult<()> {
unsafe { crate::notcurses_render(self) } error![unsafe { crate::notcurses_render(self) }]
} }
/// Performs the rendering and rasterization portion of /// Performs the rendering and rasterization portion of
@ -453,10 +454,10 @@ impl Notcurses {
/// *C style function: [notcurses_render_to_buffer()][crate::notcurses_render_to_buffer].* /// *C style function: [notcurses_render_to_buffer()][crate::notcurses_render_to_buffer].*
// //
// CHECK that this works. // CHECK that this works.
pub fn render_to_buffer(&mut self, buffer: &mut Vec<u8>) -> NcIntResult { pub fn render_to_buffer(&mut self, buffer: &mut Vec<u8>) -> NcResult<()> {
let mut len = buffer.len() as u64; let mut len = buffer.len() as u64;
let mut buf = buffer.as_mut_ptr() as *mut i8; let mut buf = buffer.as_mut_ptr() as *mut i8;
unsafe { crate::notcurses_render_to_buffer(self, &mut buf, &mut len) } error![unsafe { crate::notcurses_render_to_buffer(self, &mut buf, &mut len) }]
} }
/// Writes the last rendered frame, in its entirety, to 'fp'. /// Writes the last rendered frame, in its entirety, to 'fp'.
@ -465,8 +466,8 @@ impl Notcurses {
/// nothing will be written. /// nothing will be written.
/// ///
/// *C style function: [notcurses_render_to_file()][crate::notcurses_render_to_file].* /// *C style function: [notcurses_render_to_file()][crate::notcurses_render_to_file].*
pub fn render_to_file(&mut self, fp: &mut NcFile) -> NcIntResult { pub fn render_to_file(&mut self, fp: &mut NcFile) -> NcResult<()> {
unsafe { crate::notcurses_render_to_file(self, fp.as_nc_ptr()) } error![unsafe { crate::notcurses_render_to_file(self, fp.as_nc_ptr()) }]
} }
/// Acquires an atomic snapshot of the Notcurses object's stats. /// Acquires an atomic snapshot of the Notcurses object's stats.