forked from Textualize/textual
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
225fa24
commit e4c85ff
Showing
14 changed files
with
274 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
""" | ||
Signals are a simple pub-sub mechanism. | ||
DOMNodes can subscribe to a signal, which will invoke a callback when the signal is published. | ||
This is experimental for now, for internal use. It may be part of the public API in a future release. | ||
""" | ||
|
||
from __future__ import annotations | ||
|
||
from typing import TYPE_CHECKING | ||
from weakref import WeakKeyDictionary | ||
|
||
import rich.repr | ||
|
||
from textual import log | ||
|
||
if TYPE_CHECKING: | ||
from ._types import IgnoreReturnCallbackType | ||
from .dom import DOMNode | ||
|
||
|
||
class SignalError(Exception): | ||
"""Base class for a signal.""" | ||
|
||
|
||
@rich.repr.auto(angular=True) | ||
class Signal: | ||
"""A signal that a widget may subscribe to, in order to invoke callbacks when an associated event occurs.""" | ||
|
||
def __init__(self, owner: DOMNode, name: str) -> None: | ||
"""Initialize a signal. | ||
Args: | ||
owner: The owner of this signal. | ||
name: An identifier for debugging purposes. | ||
""" | ||
self._owner = owner | ||
self._name = name | ||
self._subscriptions: WeakKeyDictionary[ | ||
DOMNode, list[IgnoreReturnCallbackType] | ||
] = WeakKeyDictionary() | ||
|
||
def __rich_repr__(self) -> rich.repr.Result: | ||
yield "owner", self._owner | ||
yield "name", self._name | ||
yield "subscriptions", list(self._subscriptions.keys()) | ||
|
||
def subscribe(self, node: DOMNode, callback: IgnoreReturnCallbackType) -> None: | ||
"""Subscribe a node to this signal. | ||
When the signal is published, the callback will be invoked. | ||
Args: | ||
node: Node to subscribe. | ||
callback: A callback function which takes no arguments, and returns anything (return type ignored). | ||
""" | ||
if not node.is_running: | ||
raise SignalError( | ||
f"Node must be running to subscribe to a signal (has {node} been mounted)?" | ||
) | ||
callbacks = self._subscriptions.setdefault(node, []) | ||
if callback not in callbacks: | ||
callbacks.append(callback) | ||
|
||
def unsubscribe(self, node: DOMNode) -> None: | ||
"""Unsubscribe a node from this signal. | ||
Args: | ||
node: Node to unsubscribe, | ||
""" | ||
self._subscriptions.pop(node, None) | ||
|
||
def publish(self) -> None: | ||
"""Publish the signal (invoke subscribed callbacks).""" | ||
|
||
for node, callbacks in list(self._subscriptions.items()): | ||
if not node.is_running: | ||
# Removed nodes that are no longer running | ||
self._subscriptions.pop(node) | ||
else: | ||
# Call callbacks | ||
for callback in callbacks: | ||
try: | ||
callback() | ||
except Exception as error: | ||
log.error(f"error publishing signal to {node} ignored; {error}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.