mcsdf-font-tech-demo 1.0.1

Multi-channel signed distance fields font tech demo
use glium::glutin::event_loop::EventLoopProxy;
use mcsdf::font::TextureRenderBatch;
use mcsdf::renderer::render_shape;
use rayon::prelude::*;
use std::sync::mpsc::{Receiver, RecvError, Sender};
use std::time::Instant;

pub struct RendererContext {
    pub receiver: Receiver<RendererCommand>,
    pub sender: Sender<RendererResult>,
    pub proxy: EventLoopProxy<()>,
}

pub enum RendererCommand {
    RenderShapes(String, TextureRenderBatch),
    Exit,
}

pub enum RendererResult {
    ShapesRendered(String, TextureRenderBatch, std::time::Duration),
}

#[allow(clippy::needless_pass_by_value)]
pub fn renderer_entry_point(context: RendererContext) -> Result<(), RecvError> {
    println!("Renderer thread started");
    loop {
        let command = context.receiver.recv()?;
        match command {
            RendererCommand::RenderShapes(name, mut batch) => {
                let time = {
                    let mut texture_mutex = batch.texture.lock().unwrap();
                    let render_time = Instant::now();
                    let texture_lock = texture_mutex.lock();

                    batch.allocated_shapes.par_iter_mut().for_each(|shape| {
                        render_shape(shape, &texture_lock);
                    });

                    render_time.elapsed() / batch.allocated_shapes.len() as u32
                };

                context
                    .sender
                    .send(RendererResult::ShapesRendered(name, batch, time))
                    .unwrap_or_else(|_| {
                        println!("Coudn't send rendered shapes result");
                    })
            }
            RendererCommand::Exit => {
                println!("Closing renderer thread...");
                break;
            }
        };

        context.proxy.send_event(()).unwrap_or_else(|_| {
            println!("Coudn't wakeup main thread!");
        });
    }
    Ok(())
}