Skip to content

Commit

Permalink
use_table_listener init
Browse files Browse the repository at this point in the history
  • Loading branch information
jnumainville committed Nov 13, 2023
1 parent 9e868ab commit 226b08a
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 0 deletions.
2 changes: 2 additions & 0 deletions plugins/ui/src/deephaven/ui/hooks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
from .use_memo import use_memo
from .use_state import use_state
from .use_ref import use_ref
from .use_table_listener import use_table_listener

__all__ = [
"use_callback",
"use_effect",
"use_memo",
"use_state",
"use_ref",
"use_table_listener",
]
104 changes: 104 additions & 0 deletions plugins/ui/src/deephaven/ui/hooks/use_table_listener.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
from __future__ import annotations

from functools import partial
from typing import Callable, Literal

from deephaven.table import Table
from deephaven.table_listener import listen, TableUpdate, TableListener
from deephaven.execution_context import make_user_exec_ctx, ExecutionContext

from .use_effect import use_effect

LockType: Literal["shared", "exclusive"]


def listener_with_ctx(
exec_ctx: ExecutionContext,
listener: Callable[[TableUpdate, bool], None],
update: TableUpdate,
is_replay: bool,
) -> None:
"""
Call the listener within an execution context.
Args:
exec_ctx: ExecutionContext: The execution context to use.
listener: Callable[[TableUpdate, bool], None]: The listener to call.
update: TableUpdate: The update to pass to the listener.
is_replay: bool: Whether the update is a replay.
"""
with exec_ctx:
listener(update, is_replay)


def with_ctx(
listener: Callable[[TableUpdate, bool], None]
) -> partial[[TableUpdate, bool], None]:
"""
Wrap the listener in an execution context.
Args:
listener: The listener to wrap.
Returns:
partial[[TableUpdate, bool], None]: The wrapped listener.
"""
return partial(listener_with_ctx, make_user_exec_ctx(), listener)


def wrap_listener(
listener: Callable[[TableUpdate, bool], None] | TableListener
) -> partial[[TableUpdate, bool], None]:
"""
Wrap the listener in an execution context.
Args:
listener: Callable[[TableUpdate, bool], None]: The listener to wrap.
Returns:
partial[[TableUpdate, bool], None]: The wrapped listener.
"""
if isinstance(listener, TableListener):
return with_ctx(listener.on_update)
elif callable(listener):
return with_ctx(listener)


def use_table_listener(
table: Table,
listener: Callable[[TableUpdate, bool], None] | TableListener,
description: str | None = None,
do_replay: bool = False,
replay_lock: LockType = "shared",
) -> None:
"""
Listen to a table and call a listener when the table updates.
Args:
table: Table: The table to listen to.
listener: Callable[[TableUpdate, bool], None] | TableListener: Either a function or a TableListener with an
on_update function. The function must take a TableUpdate and is_replay bool.
description: str | None: An optional description for the UpdatePerformanceTracker to append to the listener’s
entry description, default is None.
do_replay: bool: Whether to replay the initial snapshot of the table, default is False.
replay_lock: LockType: The lock type used during replay, default is ‘shared’, can also be ‘exclusive’.
"""

def start_listener() -> Callable[[], None]:
"""
Start the listener. Returns a function that can be called to stop the listener by the use_effect hook.
Returns:
Callable[[], None]: A function that can be called to stop the listener by the use_effect hook.
"""
handle = listen(
table,
wrap_listener(listener),
description=description,
do_replay=do_replay,
replay_lock=replay_lock,
)

return lambda: handle.stop()

use_effect(start_listener, [table, listener, description, do_replay, replay_lock])

0 comments on commit 226b08a

Please sign in to comment.