mirror of
https://github.com/tiqi-group/pydase.git
synced 2025-06-07 05:50:41 +02:00
replaces lambda functions with functions in callback manager
This commit is contained in:
parent
0ea997384c
commit
f5116607b9
@ -3,7 +3,7 @@ from __future__ import annotations
|
|||||||
import inspect
|
import inspect
|
||||||
import logging
|
import logging
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
from typing import TYPE_CHECKING, Any, cast
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
from pydase.data_service.abstract_data_service import AbstractDataService
|
from pydase.data_service.abstract_data_service import AbstractDataService
|
||||||
from pydase.utils.helpers import get_class_and_instance_attributes
|
from pydase.utils.helpers import get_class_and_instance_attributes
|
||||||
@ -96,17 +96,20 @@ class CallbackManager:
|
|||||||
# Default arguments solve the late binding problem by capturing the
|
# Default arguments solve the late binding problem by capturing the
|
||||||
# value at the time the lambda is defined, not when it is called. This
|
# value at the time the lambda is defined, not when it is called. This
|
||||||
# prevents attr_name from being overwritten in the next loop iteration.
|
# prevents attr_name from being overwritten in the next loop iteration.
|
||||||
callback = (
|
def callback(
|
||||||
lambda index, value, attr_name=attr_name: self.service._callback_manager.emit_notification(
|
index: int, value: Any, attr_name: str = attr_name
|
||||||
parent_path=parent_path,
|
) -> None:
|
||||||
name=f"{attr_name}[{index}]",
|
"""Emits a notification through the service's callback manager."""
|
||||||
value=value,
|
|
||||||
)
|
|
||||||
if self.service == self.service.__root__
|
|
||||||
# Skip private and protected lists
|
# Skip private and protected lists
|
||||||
and not cast(str, attr_name).startswith("_")
|
if (
|
||||||
else None
|
self.service == self.service.__root__
|
||||||
)
|
and not attr_name.startswith("_")
|
||||||
|
):
|
||||||
|
self.service._callback_manager.emit_notification(
|
||||||
|
parent_path=parent_path,
|
||||||
|
name=f"{attr_name}[{index}]",
|
||||||
|
value=value,
|
||||||
|
)
|
||||||
|
|
||||||
# Check if attr_value is already a DataServiceList or in the mapping
|
# Check if attr_value is already a DataServiceList or in the mapping
|
||||||
if isinstance(attr_value, DataServiceList):
|
if isinstance(attr_value, DataServiceList):
|
||||||
@ -164,17 +167,20 @@ class CallbackManager:
|
|||||||
|
|
||||||
# Create and register a callback for the object
|
# Create and register a callback for the object
|
||||||
# only emit the notification when the call was registered by the root object
|
# only emit the notification when the call was registered by the root object
|
||||||
callback: Callable[[str, Any], None] = (
|
def callback(attr_name: str, value: Any) -> None:
|
||||||
lambda name, value: obj._callback_manager.emit_notification(
|
"""Emits a notification through the service's callback manager."""
|
||||||
parent_path=parent_path, name=name, value=value
|
# Skip private and protected attrs
|
||||||
)
|
# exlude proerty notifications -> those are handled in separate callbacks
|
||||||
if self.service == obj.__root__
|
if (
|
||||||
and not name.startswith("_") # we are only interested in public attributes
|
self.service == self.service.__root__
|
||||||
and not isinstance(
|
and not attr_name.startswith("_")
|
||||||
getattr(type(obj), name, None), property
|
and not isinstance(getattr(type(obj), attr_name, None), property)
|
||||||
) # exlude proerty notifications -> those are handled in separate callbacks
|
):
|
||||||
else None
|
self.service._callback_manager.emit_notification(
|
||||||
)
|
parent_path=parent_path,
|
||||||
|
name=attr_name,
|
||||||
|
value=value,
|
||||||
|
)
|
||||||
|
|
||||||
obj._callback_manager.callbacks.add(callback)
|
obj._callback_manager.callbacks.add(callback)
|
||||||
|
|
||||||
@ -300,34 +306,46 @@ class CallbackManager:
|
|||||||
if isinstance(
|
if isinstance(
|
||||||
dependency_value, (DataServiceList, AbstractDataService)
|
dependency_value, (DataServiceList, AbstractDataService)
|
||||||
):
|
):
|
||||||
callback = (
|
|
||||||
lambda name, value, dependent_attr=attr_name: obj._callback_manager.emit_notification(
|
def list_or_data_service_callback(
|
||||||
parent_path=parent_path,
|
name: Any, value: Any, dependent_attr: str = attr_name
|
||||||
name=dependent_attr,
|
) -> None:
|
||||||
value=getattr(obj, dependent_attr),
|
"""Emits a notification through the service's callback
|
||||||
)
|
manager.
|
||||||
if self.service == obj.__root__
|
"""
|
||||||
else None
|
if self.service == obj.__root__:
|
||||||
)
|
obj._callback_manager.emit_notification(
|
||||||
|
parent_path=parent_path,
|
||||||
|
name=dependent_attr,
|
||||||
|
value=getattr(obj, dependent_attr),
|
||||||
|
)
|
||||||
|
|
||||||
self.__register_recursive_parameter_callback(
|
self.__register_recursive_parameter_callback(
|
||||||
dependency_value,
|
dependency_value,
|
||||||
callback=callback,
|
callback=list_or_data_service_callback,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
callback = (
|
|
||||||
lambda name, _, dep_attr=attr_name, dep=dependency: obj._callback_manager.emit_notification( # type: ignore
|
def callback(
|
||||||
parent_path=parent_path,
|
name: str,
|
||||||
name=dep_attr,
|
value: Any,
|
||||||
value=getattr(obj, dep_attr),
|
dependent_attr: str = attr_name,
|
||||||
)
|
dep: str = dependency,
|
||||||
if name == dep and self.service == obj.__root__
|
) -> None:
|
||||||
else None
|
"""Emits a notification through the service's callback
|
||||||
)
|
manager.
|
||||||
|
"""
|
||||||
|
if name == dep and self.service == obj.__root__:
|
||||||
|
obj._callback_manager.emit_notification(
|
||||||
|
parent_path=parent_path,
|
||||||
|
name=dependent_attr,
|
||||||
|
value=getattr(obj, dependent_attr),
|
||||||
|
)
|
||||||
|
|
||||||
# Add to callbacks
|
# Add to callbacks
|
||||||
obj._callback_manager.callbacks.add(callback)
|
obj._callback_manager.callbacks.add(callback)
|
||||||
|
|
||||||
def _register_start_stop_task_callbacks(
|
def _register_start_stop_task_callbacks( # noqa
|
||||||
self, obj: "AbstractDataService", parent_path: str
|
self, obj: "AbstractDataService", parent_path: str
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
@ -346,16 +364,22 @@ class CallbackManager:
|
|||||||
|
|
||||||
# Create and register a callback for the object
|
# Create and register a callback for the object
|
||||||
# only emit the notification when the call was registered by the root object
|
# only emit the notification when the call was registered by the root object
|
||||||
callback: Callable[[str, dict[str, Any] | None], None] = (
|
def task_status_change_callback(
|
||||||
lambda name, status: obj._callback_manager.emit_notification(
|
name: str, task_status: dict[str, Any] | None
|
||||||
parent_path=parent_path, name=name, value=status
|
) -> None:
|
||||||
)
|
"""Emits a notification through the service's callback
|
||||||
if self.service == obj.__root__
|
manager.
|
||||||
and not name.startswith("_") # we are only interested in public attributes
|
"""
|
||||||
else None
|
if self.service == obj.__root__ and not name.startswith("_"):
|
||||||
)
|
obj._callback_manager.emit_notification(
|
||||||
|
parent_path=parent_path,
|
||||||
|
name=name,
|
||||||
|
value=task_status,
|
||||||
|
)
|
||||||
|
|
||||||
obj._task_manager.task_status_change_callbacks.append(callback)
|
obj._task_manager.task_status_change_callbacks.append(
|
||||||
|
task_status_change_callback
|
||||||
|
)
|
||||||
|
|
||||||
# Recursively register callbacks for all nested attributes of the object
|
# Recursively register callbacks for all nested attributes of the object
|
||||||
attrs: dict[str, Any] = get_class_and_instance_attributes(obj)
|
attrs: dict[str, Any] = get_class_and_instance_attributes(obj)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user