geop_ops_assembly/
settle.rs1use std::{cell::RefCell, rc::Rc};
8
9use geop_core_editor::{editing::Pull, editor::Rerun, registry::Settle};
10use geop_core_math::geop_error::GeopResult;
11use geop_core_program::{reader::Reader, values::StateValues};
12
13use crate::solving::{self, check, conflicting, solved_states};
14
15#[derive(Default)]
18pub(crate) struct Settled {
19 pub(crate) conflicting: RefCell<Vec<String>>,
22}
23
24pub struct Settler {
26 pub(crate) settled: Rc<Settled>,
27}
28
29impl Settle for Settler {
30 fn settle(
39 &self,
40 rerun: &mut Rerun,
41 pulls: &[Pull],
42 own: Option<&str>,
43 ) -> GeopResult<StateValues> {
44 let state = rerun.program.state.clone();
45 let holds = check(&rerun.reader()).is_ok_and(|report| report.converged);
46 let solved = if !pulls.is_empty() {
47 solving::solve(rerun, &state, pulls, None, true, None).ok()
48 } else if holds {
49 None
50 } else {
51 let own_first = own
52 .and_then(|own| solving::solve(rerun, &state, &[], Some(own), true, None).ok())
53 .filter(|(_, report)| report.converged);
54 own_first.or_else(|| solving::solve(rerun, &state, &[], None, true, None).ok())
55 };
56 *self.settled.conflicting.borrow_mut() = match &solved {
57 Some((_, report)) if !report.converged => {
58 conflicting(rerun, &state).unwrap_or_default()
59 }
60 _ => Vec::new(),
61 };
62 Ok(solved.map(|(moved, _)| moved).unwrap_or_default())
63 }
64
65 fn solvable(&self, reader: &Reader) -> GeopResult<Vec<String>> {
66 solved_states(reader)
67 }
68}