// SPDX-FileCopyrightText: 2025 Topola contributors // // SPDX-License-Identifier: MIT use std::ops::ControlFlow; use serde::{Deserialize, Serialize}; use specctra_core::mesadata::AccessMesadata; use crate::{ autorouter::{ anterouter::{Anterouter, AnterouterOptions, AnterouterPlan}, invoker::GetDebugOverlayData, permutator::PlanarAutorouteExecutionPermutator, planar_autoroute::PlanarAutorouteContinueStatus, ratline::RatlineUid, Autorouter, AutorouterError, PlanarAutorouteOptions, }, board::edit::BoardEdit, drawing::graph::PrimitiveIndex, geometry::primitive::PrimitiveShape, router::{navcord::Navcord, navmesh::Navmesh, thetastar::ThetastarStepper}, stepper::{Abort, EstimateProgress, Step}, }; #[derive(Clone, Copy, Debug, Deserialize, Serialize)] pub struct MultilayerAutorouteOptions { pub anterouter: AnterouterOptions, pub planar: PlanarAutorouteOptions, } pub struct MultilayerAutorouteExecutionStepper { planar: PlanarAutorouteExecutionPermutator, } impl MultilayerAutorouteExecutionStepper { pub fn new( autorouter: &mut Autorouter, ratlines: Vec, plan: AnterouterPlan, options: MultilayerAutorouteOptions, ) -> Result { let mut assigner = Anterouter::new(plan); assigner.anteroute(autorouter, &options.anterouter); Ok(Self { planar: PlanarAutorouteExecutionPermutator::new(autorouter, ratlines, options.planar)?, }) } } impl Step, Option, PlanarAutorouteContinueStatus> for MultilayerAutorouteExecutionStepper { type Error = AutorouterError; fn step( &mut self, autorouter: &mut Autorouter, ) -> Result, PlanarAutorouteContinueStatus>, AutorouterError> { self.planar.step(autorouter) } } impl Abort> for MultilayerAutorouteExecutionStepper { fn abort(&mut self, autorouter: &mut Autorouter) { self.planar.abort(autorouter) } } impl EstimateProgress for MultilayerAutorouteExecutionStepper { type Value = f64; fn estimate_progress_value(&self) -> f64 { self.planar.estimate_progress_value() } fn estimate_progress_maximum(&self) -> f64 { self.planar.estimate_progress_maximum() } } impl GetDebugOverlayData for MultilayerAutorouteExecutionStepper { fn maybe_thetastar(&self) -> Option<&ThetastarStepper> { self.planar.maybe_thetastar() } fn maybe_navcord(&self) -> Option<&Navcord> { self.planar.maybe_navcord() } fn ghosts(&self) -> &[PrimitiveShape] { self.planar.ghosts() } fn obstacles(&self) -> &[PrimitiveIndex] { self.planar.obstacles() } }