use std::marker::PhantomData;
use solverforge_core::domain::PlanningSolution;
use solverforge_scoring::Director;
use crate::heuristic::Move;
use crate::phase::construction::{
BestFitForager, ConstructionForager, ConstructionHeuristicPhase, EntityPlacer, FirstFitForager,
};
use super::super::PhaseFactory;
pub struct ConstructionPhaseFactory<S, M, P, Fo>
where
S: PlanningSolution,
M: Move<S>,
P: EntityPlacer<S, M>,
Fo: ConstructionForager<S, M>,
{
placer: P,
forager: Fo,
_marker: PhantomData<fn() -> (S, M)>,
}
impl<S, M, P, Fo> ConstructionPhaseFactory<S, M, P, Fo>
where
S: PlanningSolution,
M: Move<S>,
P: EntityPlacer<S, M>,
Fo: ConstructionForager<S, M>,
{
pub fn new(placer: P, forager: Fo) -> Self {
Self {
placer,
forager,
_marker: PhantomData,
}
}
}
impl<S, M, P> ConstructionPhaseFactory<S, M, P, FirstFitForager<S, M>>
where
S: PlanningSolution,
M: Move<S>,
P: EntityPlacer<S, M>,
{
pub fn first_fit(placer: P) -> Self {
Self::new(placer, FirstFitForager::new())
}
}
impl<S, M, P> ConstructionPhaseFactory<S, M, P, BestFitForager<S, M>>
where
S: PlanningSolution,
M: Move<S>,
P: EntityPlacer<S, M>,
{
pub fn best_fit(placer: P) -> Self {
Self::new(placer, BestFitForager::new())
}
}
impl<S, D, M, P, Fo> PhaseFactory<S, D> for ConstructionPhaseFactory<S, M, P, Fo>
where
S: PlanningSolution,
D: Director<S>,
M: Move<S> + Clone + Send + Sync + 'static,
P: EntityPlacer<S, M> + Clone + Send + Sync + 'static,
Fo: ConstructionForager<S, M> + Clone + Send + Sync + 'static,
{
type Phase = ConstructionHeuristicPhase<S, M, P, Fo>;
fn create(&self) -> Self::Phase {
ConstructionHeuristicPhase::new(self.placer.clone(), self.forager.clone())
}
}