use crate::{
bridge::render_thread::RenderContext,
gui::{
editor::{activity::ActivityRegistry, state::EditorState, view::SolidLastSolved},
solid_preview::preview_state::SolidPreviewState,
},
};
use indicatrix_cut_core::Design;
use std::{
cell::RefCell,
collections::BTreeSet,
rc::Rc,
sync::{
Arc, Mutex,
atomic::{AtomicBool, AtomicU64},
},
time::Duration,
};
pub(super) struct Runtime {
pub(super) preview_state: Option<Arc<SolidPreviewState>>,
pub(super) solid_last_solved: Option<SolidLastSolved>,
pub(super) render_ctx: Option<Arc<Mutex<RenderContext>>>,
pub(super) editor_state: Option<Rc<RefCell<EditorState>>>,
pub(super) activity: Option<Rc<ActivityRegistry>>,
pub(super) last_solve: Option<Duration>,
pub(super) current_seq: u64,
pub(super) debounce: Option<slint::Timer>,
pub(super) current_design: Option<(u64, Arc<Design>, BTreeSet<usize>)>,
pub(super) solve_in_flight: bool,
pub(super) pending_dispatch: Option<PendingDispatch>,
pub(super) idle_replan: Option<slint::Timer>,
pub(super) current_cancel: Option<Arc<AtomicBool>>,
pub(super) activity_id: Option<u64>,
pub(super) too_many_planes_toasted: bool,
}
impl Runtime {
pub(super) const fn new() -> Self {
Self {
preview_state: None,
solid_last_solved: None,
render_ctx: None,
editor_state: None,
activity: None,
last_solve: None,
current_seq: 0,
debounce: None,
current_design: None,
solve_in_flight: false,
pending_dispatch: None,
idle_replan: None,
current_cancel: None,
activity_id: None,
too_many_planes_toasted: false,
}
}
}
pub(super) struct PendingDispatch {
pub(super) design: Design,
pub(super) started_generation: u64,
pub(super) generation: Arc<AtomicU64>,
pub(super) multi_selected: BTreeSet<usize>,
}
thread_local! {
pub(super) static RUNTIME: RefCell<Runtime> = const { RefCell::new(Runtime::new()) };
}
pub(in crate::gui::editor) fn init(
preview_state: &Arc<SolidPreviewState>,
solid_last_solved: &SolidLastSolved,
activity: &Rc<ActivityRegistry>,
) {
RUNTIME.with(|cell| {
let mut rt = cell.borrow_mut();
rt.preview_state = Some(Arc::clone(preview_state));
rt.solid_last_solved = Some(Arc::clone(solid_last_solved));
rt.activity = Some(Rc::clone(activity));
});
}
pub(in crate::gui::editor) fn preview_state() -> Option<Arc<SolidPreviewState>> {
RUNTIME.with(|cell| cell.borrow().preview_state.clone())
}
pub(in crate::gui::editor) fn solid_last_solved() -> Option<SolidLastSolved> {
RUNTIME.with(|cell| cell.borrow().solid_last_solved.clone())
}
#[must_use]
pub(in crate::gui::editor) fn activity() -> Option<Rc<ActivityRegistry>> {
RUNTIME.with(|cell| cell.borrow().activity.clone())
}
pub(in crate::gui::editor) fn stash_editor_state(state: &Rc<RefCell<EditorState>>) {
RUNTIME.with(|cell| {
cell.borrow_mut().editor_state = Some(Rc::clone(state));
});
}
#[must_use]
pub(in crate::gui::editor) fn editor_state() -> Option<Rc<RefCell<EditorState>>> {
RUNTIME.with(|cell| cell.borrow().editor_state.clone())
}
pub(in crate::gui::editor) fn stash_render_ctx(render_ctx: &Arc<Mutex<RenderContext>>) {
RUNTIME.with(|cell| {
cell.borrow_mut().render_ctx = Some(Arc::clone(render_ctx));
});
}
pub(in crate::gui::editor) fn render_ctx() -> Option<Arc<Mutex<RenderContext>>> {
RUNTIME.with(|cell| cell.borrow().render_ctx.clone())
}