Refactor Tty and Grid creation into Term::new

This moves more logic out of main() and prepares the Term type to handle
resizing. By providing all size data to Term, it is now possible to
implement a resize function there which handles all resizing logic save
for the rendering subsystem.
This commit is contained in:
Joe Wilm 2016-06-28 09:18:54 -07:00
parent 8454bbe183
commit 69ed81d249
4 changed files with 99 additions and 58 deletions

View File

@ -8,11 +8,6 @@ use util::Rotate;
use term::{Cursor, DEFAULT_FG, DEFAULT_BG};
use ::Rgb;
/// Calculate the number of cells for an axis
pub fn num_cells_axis(cell_width: u32, screen_width: u32) -> u32 {
(screen_width as f64 / cell_width as f64) as u32
}
#[derive(Clone, Debug)]
pub struct Cell {
pub c: char,

View File

@ -35,7 +35,6 @@ use std::sync::{mpsc, Arc};
use parking_lot::Mutex;
use font::FontDesc;
use grid::Grid;
use meter::Meter;
use renderer::{QuadRenderer, GlyphCache};
use term::Term;
@ -100,14 +99,6 @@ mod gl {
include!(concat!(env!("OUT_DIR"), "/gl_bindings.rs"));
}
#[derive(Debug)]
pub struct TermProps {
width: f32,
height: f32,
cell_width: f32,
cell_height: f32,
}
#[cfg(target_os = "linux")]
static FONT: &'static str = "DejaVu Sans Mono";
#[cfg(target_os = "linux")]
@ -147,24 +138,10 @@ fn main() {
println!("Cell Size: ({} x {})", cell_width, cell_height);
let num_cols = grid::num_cells_axis(cell_width, width);
let num_rows = grid::num_cells_axis(cell_height, height);
let terminal = Term::new(width as f32, height as f32, cell_width as f32, cell_height as f32);
let tty = tty::new(num_rows as u8, num_cols as u8);
tty.resize(num_rows as usize, num_cols as usize, width as usize, height as usize);
let reader = tty.reader();
let writer = tty.writer();
println!("num_cols, num_rows = {}, {}", num_cols, num_rows);
let grid = Grid::new(num_rows as usize, num_cols as usize);
let props = TermProps {
cell_width: cell_width as f32,
cell_height: cell_height as f32,
height: height as f32,
width: width as f32,
};
let reader = terminal.tty().reader();
let writer = terminal.tty().writer();
let mut glyph_cache = GlyphCache::new(rasterizer, desc, font_size);
let needs_render = Arc::new(AtomicBool::new(true));
@ -179,7 +156,7 @@ fn main() {
}
});
let terminal = Arc::new(Mutex::new(Term::new(tty, grid)));
let terminal = Arc::new(Mutex::new(terminal));
let term_ref = terminal.clone();
let mut meter = Meter::new();
@ -255,10 +232,16 @@ fn main() {
gl::Enable(gl::MULTISAMPLE);
}
// Create renderer
let mut renderer = QuadRenderer::new(width, height);
renderer.with_api(&props, |mut api| {
glyph_cache.init(&mut api);
});
// Initialize glyph cache
{
let terminal = term_ref.lock();
renderer.with_api(terminal.size_info(), |mut api| {
glyph_cache.init(&mut api);
});
}
loop {
unsafe {
@ -266,33 +249,38 @@ fn main() {
gl::Clear(gl::COLOR_BUFFER_BIT);
}
// Need scope so lock is released when swap_buffers is called
{
// Flag that it's time for render
needs_render2.store(true, Ordering::Release);
// Acquire term lock
let mut terminal = term_ref.lock();
let terminal = term_ref.lock();
// Have the lock, ok to lower flag
needs_render2.store(false, Ordering::Relaxed);
let _sampler = meter.sampler();
renderer.with_api(&props, |mut api| {
// Draw the grid
api.render_grid(terminal.grid(), &mut glyph_cache);
// Draw grid + cursor
{
let _sampler = meter.sampler();
// Also draw the cursor
if terminal.mode().contains(term::mode::SHOW_CURSOR) {
api.render_cursor(terminal.cursor(), &mut glyph_cache);
}
})
renderer.with_api(terminal.size_info(), |mut api| {
// Draw the grid
api.render_grid(terminal.grid(), &mut glyph_cache);
// Also draw the cursor
if terminal.mode().contains(term::mode::SHOW_CURSOR) {
api.render_cursor(terminal.cursor(), &mut glyph_cache);
}
})
}
// Draw render timer
let timing = format!("{:.3} usec", meter.average());
let color = Rgb { r: 0xd5, g: 0x4e, b: 0x53 };
renderer.with_api(terminal.size_info(), |mut api| {
api.render_string(&timing[..], &mut glyph_cache, &color);
});
}
// Draw render timer
let timing = format!("{:.3} usec", meter.average());
let color = Rgb { r: 0xd5, g: 0x4e, b: 0x53 };
renderer.with_api(&props, |mut api| {
api.render_string(&timing[..], &mut glyph_cache, &color);
});
window.swap_buffers().unwrap();
if process_should_exit() {

View File

@ -17,7 +17,7 @@ use font::{Rasterizer, RasterizedGlyph, FontDesc};
use grid::{self, Grid, Cell, CellFlags};
use term;
use super::{Rgb, TermProps};
use super::Rgb;
static TEXT_SHADER_F_PATH: &'static str = concat!(env!("CARGO_MANIFEST_DIR"), "/res/text.f.glsl");
static TEXT_SHADER_V_PATH: &'static str = concat!(env!("CARGO_MANIFEST_DIR"), "/res/text.v.glsl");
@ -423,7 +423,7 @@ impl QuadRenderer {
renderer
}
pub fn with_api<F>(&mut self, props: &TermProps, mut func: F)
pub fn with_api<F>(&mut self, props: &term::SizeInfo, mut func: F)
where F: FnMut(RenderApi)
{
if self.should_reload.load(Ordering::Relaxed) {
@ -681,7 +681,7 @@ impl ShaderProgram {
Ok(shader)
}
fn set_term_uniforms(&self, props: &TermProps) {
fn set_term_uniforms(&self, props: &term::SizeInfo) {
unsafe {
gl::Uniform2f(self.u_term_dim, props.width, props.height);
gl::Uniform2f(self.u_cell_dim, props.cell_width, props.cell_height);

View File

@ -89,7 +89,7 @@ pub struct Term {
alt: bool,
/// Reference to the underlying tty
_tty: tty::Tty,
tty: tty::Tty,
/// The cursor
cursor: Cursor,
@ -114,10 +114,57 @@ pub struct Term {
/// Scroll region
scroll_region: Range<usize>,
/// Size
size_info: SizeInfo,
}
/// Terminal size info
#[derive(Debug)]
pub struct SizeInfo {
/// Terminal window width
pub width: f32,
/// Terminal window height
pub height: f32,
/// Width of individual cell
pub cell_width: f32,
/// Height of individual cell
pub cell_height: f32,
}
impl SizeInfo {
#[inline]
pub fn rows(&self) -> usize {
(self.height / self.cell_height) as usize
}
#[inline]
pub fn cols(&self) -> usize {
(self.width / self.cell_width) as usize
}
}
impl Term {
pub fn new(tty: tty::Tty, grid: Grid) -> Term {
pub fn new(width: f32, height: f32, cell_width: f32, cell_height: f32) -> Term {
let size = SizeInfo {
width: width as f32,
height: height as f32,
cell_width: cell_width as f32,
cell_height: cell_height as f32,
};
let num_cols = size.cols();
let num_rows = size.rows();
println!("num_cols, num_rows = {}, {}", num_cols, num_rows);
let grid = Grid::new(num_rows, num_cols);
let tty = tty::new(num_rows as u8, num_cols as u8);
tty.resize(num_rows, num_cols, size.width as usize, size.height as usize);
let mut tabs = (0..grid.num_cols()).map(|i| i % TAB_SPACES == 0)
.collect::<Vec<bool>>();
@ -134,14 +181,25 @@ impl Term {
alt_cursor: Cursor::default(),
fg: DEFAULT_FG,
bg: DEFAULT_BG,
_tty: tty,
tty: tty,
tabs: tabs,
attr: CellFlags::empty(),
mode: Default::default(),
scroll_region: scroll_region,
size_info: size
}
}
#[inline]
pub fn tty(&self) -> &tty::Tty {
&self.tty
}
#[inline]
pub fn size_info(&self) -> &SizeInfo {
&self.size_info
}
pub fn grid(&self) -> &Grid {
&self.grid
}