[PortPather] add PortPather

This commit is contained in:
jan 2025-11-19 00:16:34 -08:00
parent dfd61b3a39
commit 2b7b1cd6e2
3 changed files with 94 additions and 3 deletions

View File

@ -80,6 +80,7 @@ from .builder import (
SimpleTool as SimpleTool,
AutoTool as AutoTool,
PathTool as PathTool,
PortPather as PortPather,
)
from .utils import (
ports2data as ports2data,

View File

@ -1,6 +1,7 @@
from .builder import Builder as Builder
from .pather import Pather as Pather
from .renderpather import RenderPather as RenderPather
from .pather_mixin import PortPather as PortPather
from .utils import ell as ell
from .tools import (
Tool as Tool,

View File

@ -1,4 +1,4 @@
from typing import Self
from typing import Self, TYPE_CHECKING
from collections.abc import Sequence, Iterator
import logging
from contextlib import contextmanager
@ -11,11 +11,15 @@ from numpy.typing import ArrayLike
from ..pattern import Pattern
from ..library import ILibrary
from ..error import PortError, BuildError
from ..utils import rotation_matrix_2d, SupportsBool
#from ..abstract import Abstract
from ..utils import SupportsBool
from ..abstract import Abstract
from .tools import Tool
from .utils import ell
if TYPE_CHECKING:
from .pather import Pather
from .renderpather import RenderPather
logger = logging.getLogger(__name__)
@ -435,3 +439,88 @@ class PatherMixin(metaclass=ABCMeta):
"""
self.pattern.flatten(self.library)
return self
class PortPather:
"""
Single-port state manager
This class provides a convenient way to perform multiple pathing operations on a
port without needing to repeatedly pass its name.
"""
port: str
pather: 'Pather | RenderPather'
def __init__(self, port: str, pather: 'Pather | RenderPather') -> None:
self.port = port
self.pather = pather
#
# Delegate to pather
#
def retool(self, tool: Tool) -> Self:
self.pather.retool(tool, keys=[self.port])
return self
@contextmanager
def toolctx(self, tool: Tool) -> Iterator[Self]:
with self.pather.toolctx(tool, keys=[self.port]):
yield self
def path(self, *args, **kwargs) -> Self:
self.pather.path(self.port, *args, **kwargs)
return self
def pathS(self, *args, **kwargs) -> Self:
self.pather.pathS(self.port, *args, **kwargs)
return self
def path_to(self, *args, **kwargs) -> Self:
self.pather.path_to(self.port, *args, **kwargs)
return self
def path_into(self, *args, **kwargs) -> Self:
self.pather.path_into(self.port, *args, **kwargs)
return self
def path_from(self, *args, **kwargs) -> Self:
self.pather.path_into(args[0], self.port, *args[1:], **kwargs)
return self
def mpath(self, *args, **kwargs) -> Self:
self.pather.mpath([self.port], *args, **kwargs)
return self
def plug(
self,
other: Abstract | str,
other_port: str,
*args,
**kwargs,
) -> Self:
self.pather.plug(other, {self.port: other_port}, *args, **kwargs)
return self
def plugged(self, other_port: str) -> Self:
self.pather.plugged({self.port: other_port})
return self
#
# Delegate to port
#
def set_ptype(self, ptype: str) -> Self:
self.pather[self.port].set_ptype(ptype)
return self
def mirror(self, *args, **kwargs) -> Self:
self.pather[self.port].mirror(*args, **kwargs)
return self
def rotate(self, rotation: float) -> Self:
self.pather[self.port].rotate(rotation)
return self
def set_rotation(self, rotation: float | None) -> Self:
self.pather[self.port].set_rotation(rotation)
return self