From 160aba6258e1979ef85d66b2c27c33f6f28a7e38 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Tue, 17 Jan 2023 23:06:54 +0100 Subject: factor out saving logic Since we want to support SQLite at some point, it makes sense to have the exact storage method abstracted away. --- src/renderer.rs | 42 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 23 deletions(-) (limited to 'src/renderer.rs') diff --git a/src/renderer.rs b/src/renderer.rs index bb33ddc..4840e73 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -1,9 +1,6 @@ -use std::{fs, path::Path, thread}; +use std::thread; -use color_eyre::{ - eyre::{bail, Result}, - Report, -}; +use color_eyre::{eyre::Result, Report}; use image::{ImageBuffer, Luma, Pixel, RgbaImage}; use nalgebra::{vector, Vector2}; use rayon::iter::ParallelIterator; @@ -13,6 +10,13 @@ use super::{ layer::{self, TileLayer}, }; +#[derive(Debug, Clone)] +pub struct RenderedTile { + pub x: u64, + pub y: u64, + pub data: Vec, +} + pub type HeatCounter = TileLayer>; fn render_circle(layer: &mut TileLayer

, center: (u64, u64), radius: u64, pixel: P) { @@ -135,32 +139,21 @@ fn colorize_tile(tile: &ImageBuffer, Vec>, max: u32) -> RgbaImage { /// rendering the next one. /// /// This has a way lower memory usage than [`colorize_heatcounter`]. -pub fn lazy_colorization, F: Fn(usize) + Send + Sync>( +pub fn lazy_colorization Result<()> + Send + Sync>( layer: HeatCounter, - base_dir: P, - progress_callback: F, + mut save_callback: F, ) -> Result<()> { - let base_dir = base_dir.as_ref(); let max = layer.pixels().map(|l| l.0[0]).max().unwrap_or_default(); if max == 0 { return Ok(()); } - type Job = (u64, u64, Vec); - let (tx, rx) = crossbeam_channel::bounded::(30); + let (tx, rx) = crossbeam_channel::bounded::(30); thread::scope(|s| { let saver = s.spawn(move || loop { - let Ok((tile_x, tile_y, data)) = rx.recv() else { return Ok(()) }; - let folder = base_dir.join(tile_x.to_string()); - let metadata = folder.metadata(); - match metadata { - Err(_) => fs::create_dir(&folder)?, - Ok(m) if !m.is_dir() => bail!("Output path is not a directory"), - _ => {} - } - let file = folder.join(format!("{tile_y}.png")); - fs::write(file, data)?; + let Ok(tile) = rx.recv() else { return Ok::<_, Report>(()) }; + save_callback(tile)?; }); layer @@ -168,8 +161,11 @@ pub fn lazy_colorization, F: Fn(usize) + Send + Sync>( .try_for_each_with(tx, |tx, (tile_x, tile_y, tile)| { let colorized = colorize_tile(&tile, max.into()); let data = layer::compress_png_as_bytes(&colorized)?; - tx.send((tile_x, tile_y, data))?; - progress_callback(1); + tx.send(RenderedTile { + x: tile_x, + y: tile_y, + data, + })?; Ok::<(), Report>(()) })?; -- cgit v1.2.3