use std::thread::JoinHandle;
use crossbeam_channel::Sender;
use fj_operations::shape_processor::ShapeProcessor;
use crate::{EventLoopClosed, HostThread, Model, ModelEvent};
pub struct Host {
command_tx: Sender<HostCommand>,
host_thread: Option<JoinHandle<Result<(), EventLoopClosed>>>,
model_loaded: bool,
}
impl Host {
pub fn new(
shape_processor: ShapeProcessor,
model_event_tx: Sender<ModelEvent>,
) -> Self {
let (command_tx, host_thread) =
HostThread::spawn(shape_processor, model_event_tx);
Self {
command_tx,
host_thread: Some(host_thread),
model_loaded: false,
}
}
pub fn load_model(&mut self, model: Model) {
self.command_tx
.try_send(HostCommand::LoadModel(model))
.expect("Host channel disconnected unexpectedly");
self.model_loaded = true;
}
pub fn is_model_loaded(&self) -> bool {
self.model_loaded
}
pub fn propagate_panic(&mut self) {
if self.host_thread.is_none() {
unreachable!("Constructor requires host thread")
}
if let Some(host_thread) = &self.host_thread {
if host_thread.is_finished() {
let host_thread = self.host_thread.take().unwrap();
match host_thread.join() {
Ok(_) => {
unreachable!(
"Host thread cannot exit until host handle disconnects"
)
}
Err(_) => {
panic!("Host thread panicked")
}
}
}
}
}
}
pub enum HostCommand {
LoadModel(Model),
TriggerEvaluation,
}