mikronova/kyokkou
src/renderer.rs
use std::sync::{Arc, Mutex};
use std::time::Duration;
#[derive(Debug, Clone, PartialEq)]
pub enum RenderState {
Idle,
Rendering,
Done(String),
Error(String),
}
pub struct Renderer {
pub state: Arc<Mutex<RenderState>>,
}
impl Default for Renderer {
fn default() -> Self {
Self { state: Arc::new(Mutex::new(RenderState::Idle)) }
}
}
impl Renderer {
pub fn submit(&self, json: String, ctx: egui::Context) {
let state = self.state.clone();
*state.lock().unwrap() = RenderState::Rendering;
std::thread::spawn(move || {
let result = post_render(json);
*state.lock().unwrap() = match result {
Ok(path) => RenderState::Done(path),
Err(e) => RenderState::Error(e),
};
ctx.request_repaint();
});
}
}
fn post_render(json: String) -> Result<String, String> {
let client = reqwest::blocking::Client::builder()
.timeout(Duration::from_secs(1800))
.build()
.map_err(|e| e.to_string())?;
let resp = client
.post("http://localhost:8080/render")
.header("content-type", "application/json")
.body(json)
.send()
.map_err(|e| e.to_string())?;
if resp.status().is_success() {
Ok("/tmp/kyokkou/out/render.png".to_string())
} else {
let status = resp.status();
let body = resp.text().unwrap_or_default();
Err(format!("{status}: {body}"))
}
}