Add handlers for solved constraints
This should be used to trigger items that should redraw due to constraint solving.
This commit is contained in:
parent
e8566883fb
commit
de2d2a8dab
@ -1,6 +1,8 @@
|
||||
"""This module contains a connections manager."""
|
||||
|
||||
from typing import Callable, Iterator, NamedTuple, Optional
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Callable, Iterator, NamedTuple, Optional, Set
|
||||
|
||||
from gaphas import table
|
||||
from gaphas.connector import Handle, Port
|
||||
@ -40,8 +42,27 @@ class Connections:
|
||||
def __init__(self, solver: Optional[Solver] = None) -> None:
|
||||
self._solver = solver or Solver()
|
||||
self._connections: table.Table[Connection] = table.Table(
|
||||
Connection, tuple(range(4))
|
||||
Connection, tuple(range(5))
|
||||
)
|
||||
self._handlers: Set[Callable[[Connection], None]] = set()
|
||||
|
||||
self._solver.add_handler(self._on_constraint_solved)
|
||||
|
||||
def add_handler(self, handler):
|
||||
"""Add a callback handler.
|
||||
|
||||
Handlers are triggered when a constraint has been solved.
|
||||
"""
|
||||
self._handlers.add(handler)
|
||||
|
||||
def remove_handler(self, handler):
|
||||
"""Remove a previously assigned handler."""
|
||||
self._handlers.discard(handler)
|
||||
|
||||
def _on_constraint_solved(self, constraint):
|
||||
for cinfo in self._connections.query(constraint=constraint):
|
||||
for handler in self._handlers:
|
||||
handler(cinfo)
|
||||
|
||||
@property
|
||||
def solver(self) -> Solver:
|
||||
@ -107,7 +128,6 @@ class Connections:
|
||||
If handle is not None, only the connection for that handle is
|
||||
disconnected.
|
||||
"""
|
||||
# disconnect on canvas level
|
||||
for cinfo in list(self._connections.query(item=item, handle=handle)):
|
||||
self._disconnect_item(*cinfo)
|
||||
|
||||
|
@ -32,7 +32,7 @@ every constraint is being asked to solve itself
|
||||
(`constraint.Constraint.solve_for()` method) changing appropriate
|
||||
variables to make the constraint valid again.
|
||||
"""
|
||||
from typing import Collection, List, Set
|
||||
from typing import Callable, Collection, List, Set
|
||||
|
||||
from gaphas.solver.constraint import Constraint
|
||||
from gaphas.state import observed, reversible_pair
|
||||
@ -49,6 +49,19 @@ class Solver:
|
||||
self._constraints: Set[Constraint] = set()
|
||||
self._marked_cons: List[Constraint] = []
|
||||
self._solving = False
|
||||
self._handlers: Set[Callable[[Constraint], None]] = set()
|
||||
|
||||
def add_handler(self, handler):
|
||||
"""Add a callback handler, triggered when a constraint is resolved."""
|
||||
self._handlers.add(handler)
|
||||
|
||||
def remove_handler(self, handler):
|
||||
"""Remove a previously assigned handler."""
|
||||
self._handlers.discard(handler)
|
||||
|
||||
def _notify(self, constraint):
|
||||
for handler in self._handlers:
|
||||
handler(constraint)
|
||||
|
||||
@property
|
||||
def constraints(self) -> Collection[Constraint]:
|
||||
@ -154,6 +167,7 @@ class Solver:
|
||||
10.0
|
||||
"""
|
||||
marked_cons = self._marked_cons
|
||||
notify = self._notify
|
||||
try:
|
||||
self._solving = True
|
||||
|
||||
@ -164,6 +178,7 @@ class Solver:
|
||||
while n < len(marked_cons):
|
||||
c = marked_cons[n]
|
||||
c.solve()
|
||||
notify(c)
|
||||
n += 1
|
||||
|
||||
self._marked_cons = []
|
||||
|
@ -66,3 +66,38 @@ def test_remove_item_constraint_when_item_is_disconnected(connections):
|
||||
connections.disconnect_item(i)
|
||||
|
||||
assert list(connections.get_connections(item=i)) == []
|
||||
|
||||
|
||||
def test_notify_on_constraint_solved(connections):
|
||||
events = []
|
||||
|
||||
def on_notify(cinfo):
|
||||
events.append(cinfo)
|
||||
|
||||
i = item.Line(connections)
|
||||
c = EqualsConstraint(i.handles()[0].pos.x, i.handles()[0].pos.x)
|
||||
connections.add_constraint(i, c)
|
||||
|
||||
connections.add_handler(on_notify)
|
||||
connections.solve()
|
||||
|
||||
assert events
|
||||
assert events[0].constraint is c
|
||||
|
||||
|
||||
def test_connection_remove_handler(connections):
|
||||
events = []
|
||||
|
||||
def on_notify(cinfo):
|
||||
events.append(cinfo)
|
||||
|
||||
i = item.Line(connections)
|
||||
c = EqualsConstraint(i.handles()[0].pos.x, i.handles()[0].pos.x)
|
||||
connections.add_constraint(i, c)
|
||||
|
||||
connections.add_handler(on_notify)
|
||||
connections.remove_handler(on_notify)
|
||||
connections.remove_handler(on_notify)
|
||||
connections.solve()
|
||||
|
||||
assert not events
|
||||
|
Loading…
x
Reference in New Issue
Block a user