use std::ops::ControlFlow;
use derive_getters::Getters;
use crate::{
AutoplacerSchedule, Interactor, Vector2,
autoplacer::Jostler,
board::{
Board,
interactors::{BoardMasterInteractor, SelectInteractor},
},
layout::LayerId,
selections::PersistableSelection,
};
#[derive(Getters)]
pub struct JostlerMasterInteractor {
board_master: BoardMasterInteractor,
jostler: Jostler,
prev_pointer: Option<Vector2<i64>>,
}
impl JostlerMasterInteractor {
pub fn new(board: &mut Board, board_master: BoardMasterInteractor) -> Self {
let selection = board_master.selection().components.clone();
Self {
board_master,
jostler: Jostler::new(
board,
selection,
AutoplacerSchedule {
initial_temperature: 500.0,
temperature_common_ratio: 0.95,
initial_std_dev: 500.0,
std_dev_common_ratio: 0.995,
max_steps: 3000,
},
),
prev_pointer: None,
}
}
pub fn selection(&self) -> &PersistableSelection {
self.board_master.selection()
}
pub fn select_interactor(&self) -> &Option<SelectInteractor> {
self.board_master.select_interactor()
}
}
impl Interactor for JostlerMasterInteractor {
fn step(&mut self, board: &mut Board) -> ControlFlow<()> {
crate::profile_function!();
self.jostler.step(board);
ControlFlow::Continue(())
}
fn press(&mut self, board: &mut Board, layer: LayerId, pointer: Vector2<i64>) {
self.board_master.press(board, layer, pointer);
}
fn hold(&mut self, board: &mut Board, layer: LayerId, pointer: Vector2<i64>) {
if let Some(prev_pointer) = self.prev_pointer {
if pointer != prev_pointer {
self.jostler.abort(board);
self.jostler = Jostler::new(
board,
self.board_master.selection().components.clone(),
AutoplacerSchedule {
initial_temperature: 500.0,
temperature_common_ratio: 0.95,
initial_std_dev: 500.0,
std_dev_common_ratio: 0.995,
max_steps: 300,
},
);
}
}
self.prev_pointer = Some(pointer);
self.board_master.hold(board, layer, pointer);
}
fn release(
&mut self,
board: &mut Board,
layer: LayerId,
pointer: Vector2<i64>,
) -> ControlFlow<()> {
self.board_master.release(board, layer, pointer)
}
fn abort(&mut self, board: &mut Board) {
self.board_master.abort(board);
}
}