68 lines
1.8 KiB
Python
68 lines
1.8 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass, field
|
|
from typing import TYPE_CHECKING
|
|
|
|
from inire.router.outcomes import RoutingOutcome, infer_routing_outcome
|
|
|
|
if TYPE_CHECKING:
|
|
from inire.geometry.components import ComponentResult
|
|
from inire.model import LockedRoute
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class RoutingReport:
|
|
static_collision_count: int = 0
|
|
dynamic_collision_count: int = 0
|
|
self_collision_count: int = 0
|
|
total_length: float = 0.0
|
|
|
|
@property
|
|
def collision_count(self) -> int:
|
|
return self.static_collision_count + self.dynamic_collision_count + self.self_collision_count
|
|
|
|
@property
|
|
def is_valid(self) -> bool:
|
|
return self.collision_count == 0
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class RouteMetrics:
|
|
nodes_expanded: int
|
|
moves_generated: int
|
|
moves_added: int
|
|
pruned_closed_set: int
|
|
pruned_hard_collision: int
|
|
pruned_cost: int
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class RoutingResult:
|
|
net_id: str
|
|
path: tuple[ComponentResult, ...]
|
|
reached_target: bool = False
|
|
report: RoutingReport = field(default_factory=RoutingReport)
|
|
|
|
def __post_init__(self) -> None:
|
|
object.__setattr__(self, "path", tuple(self.path))
|
|
|
|
@property
|
|
def collisions(self) -> int:
|
|
return self.report.collision_count
|
|
|
|
@property
|
|
def outcome(self) -> RoutingOutcome:
|
|
return infer_routing_outcome(
|
|
has_path=bool(self.path),
|
|
reached_target=self.reached_target,
|
|
collision_count=self.report.collision_count,
|
|
)
|
|
|
|
@property
|
|
def is_valid(self) -> bool:
|
|
return self.outcome == "completed"
|
|
|
|
def as_locked_route(self) -> LockedRoute:
|
|
from inire.model import LockedRoute
|
|
|
|
return LockedRoute.from_path(self.path)
|