[Pather] avoid repeated resolve and non-atomic breaks

This commit is contained in:
Jan Petykiewicz 2026-04-02 00:11:26 -07:00
commit 06ed2ce54a
2 changed files with 81 additions and 13 deletions

View file

@ -170,6 +170,23 @@ class Pather(PortList):
port = self.ports[n]
self.paths[n].append(RenderStep('P', None, port.copy(), port.copy(), None))
def _prepare_breaks(self, names: Iterable[str | None]) -> list[tuple[str, RenderStep]]:
""" Snapshot break markers to be committed after a successful mutation. """
if self._dead:
return []
prepared: list[tuple[str, RenderStep]] = []
for n in names:
if n is not None and n in self.paths:
port = self.ports[n]
prepared.append((n, RenderStep('P', None, port.copy(), port.copy(), None)))
return prepared
def _commit_breaks(self, prepared: Iterable[tuple[str, RenderStep]]) -> None:
""" Append previously prepared break markers. """
for name, step in prepared:
self.paths[name].append(step)
@logged_op(lambda args: list(args['map_in'].keys()))
def plug(
self,
@ -178,9 +195,11 @@ class Pather(PortList):
map_out: dict[str, str | None] | None = None,
**kwargs,
) -> Self:
other = self.library.resolve(other, append=kwargs.get('append', False))
prepared_breaks: list[tuple[str, RenderStep]] = []
if not self._dead:
other_res = self.library.resolve(other, append=kwargs.get('append', False))
other_ports = other_res.ports
other_ports = other.ports
affected = set(map_in.keys())
plugged = set(map_in.values())
for name in other_ports:
@ -188,12 +207,10 @@ class Pather(PortList):
new_name = (map_out or {}).get(name, name)
if new_name is not None:
affected.add(new_name)
self._record_break(affected)
# Resolve into Abstract or Pattern
other = self.library.resolve(other, append=kwargs.get('append', False))
prepared_breaks = self._prepare_breaks(affected)
self.pattern.plug(other=other, map_in=map_in, map_out=map_out, skip_geometry=self._dead, **kwargs)
self._commit_breaks(prepared_breaks)
return self
@logged_op()
@ -203,20 +220,20 @@ class Pather(PortList):
port_map: dict[str, str | None] | None = None,
**kwargs,
) -> Self:
other = self.library.resolve(other, append=kwargs.get('append', False))
prepared_breaks: list[tuple[str, RenderStep]] = []
if not self._dead:
other_res = self.library.resolve(other, append=kwargs.get('append', False))
other_ports = other_res.ports
other_ports = other.ports
affected = set()
for name in other_ports:
new_name = (port_map or {}).get(name, name)
if new_name is not None:
affected.add(new_name)
self._record_break(affected)
# Resolve into Abstract or Pattern
other = self.library.resolve(other, append=kwargs.get('append', False))
prepared_breaks = self._prepare_breaks(affected)
self.pattern.place(other=other, port_map=port_map, skip_geometry=self._dead, **kwargs)
self._commit_breaks(prepared_breaks)
return self
@logged_op(lambda args: list(args['connections'].keys()))