use solverforge_core::domain::PlanningSolution;
use solverforge_scoring::Director;
use crate::heuristic::r#move::Move;
use crate::heuristic::selector::move_selector::{
MoveSelector, MoveStreamContext, ResourceMoveCursor, UnitResourceCursor,
};
pub trait MoveCursorSource<S, M>
where
S: PlanningSolution,
M: Move<S>,
{
type Resources: Send;
type Cursor<'a>: ResourceMoveCursor<S, M, Self::Resources>
where
Self: 'a;
fn open_cursor<'a, D: Director<S>>(
&'a mut self,
resources: &mut Self::Resources,
score_director: &D,
context: MoveStreamContext,
) -> Self::Cursor<'a>;
}
#[doc(hidden)]
pub struct SelectorCursorSource<MS> {
selector: MS,
}
impl<MS> SelectorCursorSource<MS> {
pub(crate) fn new(selector: MS) -> Self {
Self { selector }
}
}
impl<MS: std::fmt::Debug> std::fmt::Debug for SelectorCursorSource<MS> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("SelectorCursorSource")
.field(&self.selector)
.finish()
}
}
impl<S, M, MS> MoveCursorSource<S, M> for SelectorCursorSource<MS>
where
S: PlanningSolution,
M: Move<S>,
MS: MoveSelector<S, M>,
{
type Resources = ();
type Cursor<'a>
= UnitResourceCursor<MS::Cursor<'a>>
where
Self: 'a;
fn open_cursor<'a, D: Director<S>>(
&'a mut self,
_resources: &mut Self::Resources,
score_director: &D,
context: MoveStreamContext,
) -> Self::Cursor<'a> {
UnitResourceCursor::new(
self.selector
.open_cursor_with_context(score_director, context),
)
}
}