use solverforge_core::domain::{PlanningSolution, SolutionDescriptor};
use solverforge_core::ConstraintRef;
use crate::api::constraint_set::ConstraintMetadata;
#[derive(Debug, PartialEq, Eq)]
pub struct DirectorScoreState<Sc> {
pub solution_score: Option<Sc>,
pub committed_score: Option<Sc>,
pub initialized: bool,
}
pub trait Director<S: PlanningSolution>: Send {
fn working_solution(&self) -> &S;
fn working_solution_mut(&mut self) -> &mut S;
fn calculate_score(&mut self) -> S::Score;
fn solution_descriptor(&self) -> &SolutionDescriptor;
fn clone_working_solution(&self) -> S;
fn before_variable_changed(&mut self, descriptor_index: usize, entity_index: usize);
fn after_variable_changed(&mut self, descriptor_index: usize, entity_index: usize);
fn entity_count(&self, descriptor_index: usize) -> Option<usize>;
fn total_entity_count(&self) -> Option<usize>;
fn constraint_metadata(&self) -> Vec<ConstraintMetadata<'_>>;
fn constraint_is_hard(&self, constraint_ref: &ConstraintRef) -> Option<bool> {
let metadata = self.constraint_metadata();
metadata
.iter()
.find(|metadata| metadata.constraint_ref == constraint_ref)
.map(|metadata| metadata.is_hard)
}
fn is_incremental(&self) -> bool {
false
}
fn snapshot_score_state(&self) -> DirectorScoreState<S::Score> {
let solution_score = self.working_solution().score();
DirectorScoreState {
solution_score,
committed_score: solution_score,
initialized: solution_score.is_some(),
}
}
fn restore_score_state(&mut self, state: DirectorScoreState<S::Score>) {
self.working_solution_mut().set_score(state.solution_score);
}
fn reset(&mut self) {}
fn register_undo(&mut self, _undo: Box<dyn FnOnce(&mut S) + Send>) {
}
}