Skip to main content

solverforge_scoring/director/
traits.rs

1// Score director trait definition.
2
3use solverforge_core::domain::{PlanningSolution, SolutionDescriptor};
4
5// The score director manages solution state and score calculation.
6//
7// It is responsible for:
8// - Maintaining the working solution
9// - Calculating scores (incrementally when possible)
10// - Notifying about variable changes for incremental updates
11// - Providing access to solution metadata via descriptors
12pub trait Director<S: PlanningSolution>: Send {
13    // Returns a reference to the working solution.
14    fn working_solution(&self) -> &S;
15
16    // Returns a mutable reference to the working solution.
17    fn working_solution_mut(&mut self) -> &mut S;
18
19    // Calculates and returns the current score.
20    fn calculate_score(&mut self) -> S::Score;
21
22    // Returns the solution descriptor for this solution type.
23    fn solution_descriptor(&self) -> &SolutionDescriptor;
24
25    // Clones the working solution.
26    fn clone_working_solution(&self) -> S;
27
28    // Called before a planning variable is changed.
29    fn before_variable_changed(&mut self, descriptor_index: usize, entity_index: usize);
30
31    // Called after a planning variable is changed.
32    fn after_variable_changed(&mut self, descriptor_index: usize, entity_index: usize);
33
34    // Returns the number of entities for a given descriptor index.
35    fn entity_count(&self, descriptor_index: usize) -> Option<usize>;
36
37    // Returns the total number of entities across all collections.
38    fn total_entity_count(&self) -> Option<usize>;
39
40    // Returns true if this score director supports incremental scoring.
41    fn is_incremental(&self) -> bool {
42        false
43    }
44
45    // Resets the score director state.
46    fn reset(&mut self) {}
47
48    // Registers a typed undo closure.
49    //
50    // Called by moves after applying changes to enable automatic undo.
51    // The closure will be called in reverse order during `undo_changes()`.
52    //
53    // Default implementation does nothing (for non-recording directors).
54    fn register_undo(&mut self, _undo: Box<dyn FnOnce(&mut S) + Send>) {
55        // Default: no-op - only RecordingDirector stores undo closures
56    }
57}