retroglyph-window 0.3.1

Shared winit windowing layer for retroglyph's windowed backends
Documentation

retroglyph-window

crates.io docs.rs coverage license

A shared windowing layer for retroglyph's window-based backends (software today; GL/wgpu are future candidates). Input and Output are independent facets of Backend, which fits a terminal process (one type implements both) but not a window, where an event loop owns input and a renderer owns output separately -- this crate keeps that split (Presenter is an Output supertrait; WindowBackend owns its own Input queue) and reassembles both into one Backend via winit.

Most consumers don't depend on this crate directly; use retroglyph-software instead, which depends on it.

Quick start

[dependencies]
retroglyph-window = "0.1"

A game never implements Presenter itself -- that's retroglyph-software's job -- but a new renderer backend does. This is the whole contract it implements, sized to fit a window from its own cell geometry via WindowConfig::fit:

use retroglyph_core::backend::Output;
use retroglyph_core::grid::{Pos, Size};
use retroglyph_core::tile::Tile;
use retroglyph_window::winit::WindowConfig;
use retroglyph_window::{Presenter, WindowHandle};
use std::sync::Arc;

struct NullPresenter;

impl Output for NullPresenter {
    type Error = core::convert::Infallible;

    fn draw<'a, I>(&mut self, _content: I) -> Result<(), Self::Error>
    where
        I: Iterator<Item = (Pos, &'a Tile, Option<&'a str>)>,
    {
        Ok(())
    }

    fn draw_layers<'a, I>(&mut self, _content: I) -> Result<(), Self::Error>
    where
        I: Iterator<Item = (u8, Pos, &'a Tile, Option<&'a str>)>,
    {
        Ok(())
    }

    fn flush(&mut self) -> Result<(), Self::Error> {
        Ok(())
    }

    fn size(&self) -> Size {
        Size { width: 10, height: 5 }
    }

    fn clear(&mut self) -> Result<(), Self::Error> {
        Ok(())
    }

    fn resize(&mut self, _size: Size) {}
}

impl Presenter for NullPresenter {
    type SurfaceError = core::convert::Infallible;

    fn init_surface(&mut self, _window: Arc<dyn WindowHandle>) -> Result<(), Self::SurfaceError> {
        Ok(())
    }

    fn resize_surface(&mut self, _width: u32, _height: u32) {}

    fn present(&mut self) -> Result<(), Self::SurfaceError> {
        Ok(())
    }

    fn cell_size(&self) -> (u32, u32) {
        (8, 16)
    }
}

let config = WindowConfig::fit(&NullPresenter, "demo", None);
assert_eq!((config.width(), config.height()), (80, 80));

Hand a real Presenter (e.g. retroglyph-software's SoftwareRenderer) and a config like this to run_windowed/run_app to actually open a window and drive the event loop.

See docs.rs for the API.