Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: only construct handlers once #175

Merged
merged 11 commits into from
Dec 8, 2022
4 changes: 2 additions & 2 deletions src/dbus_fast/message_bus.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ def export(self, path: str, interface: ServiceInterface) -> None:
)

self._path_exports[path].append(interface)
ServiceInterface._add_bus(interface, self)
ServiceInterface._add_bus(interface, self, self._make_method_handler)
self._emit_interface_added(path, interface)

def unexport(
Expand Down Expand Up @@ -912,7 +912,7 @@ def _find_message_handler(
and msg.member == method.name
and msg.signature == method.in_signature
):
handler = self._make_method_handler(interface, method)
handler = ServiceInterface._get_handler(interface, method, self)
break
if handler:
break
Expand Down
41 changes: 37 additions & 4 deletions src/dbus_fast/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,15 @@
import copy
import inspect
from functools import wraps
from typing import Any, Dict, List, no_type_check_decorator
from typing import (
TYPE_CHECKING,
Any,
Callable,
Dict,
List,
Set,
no_type_check_decorator,
)

from . import introspection as intr
from ._private.util import (
Expand All @@ -13,8 +21,12 @@
)
from .constants import PropertyAccess
from .errors import SignalDisabledError
from .message import Message
from .signature import SignatureBodyMismatchError, Variant, get_signature_tree

if TYPE_CHECKING:
from .message_bus import BaseMessageBus


class _Method:
def __init__(self, fn, name, disabled=False):
Expand Down Expand Up @@ -331,6 +343,10 @@ def __init__(self, name: str):
self.__properties: List[_Property] = []
self.__signals: List[_Signal] = []
self.__buses = set()
self.__handlers: dict[
BaseMessageBus,
dict[_Method, Callable[[Message, Callable[[Message], None]], None]],
] = {}

for name, member in inspect.getmembers(type(self)):
member_dict = getattr(member, "__dict__", {})
Expand Down Expand Up @@ -437,16 +453,33 @@ def _get_signals(interface: "ServiceInterface") -> List[_Signal]:
return interface.__signals

@staticmethod
def _get_buses(interface: "ServiceInterface"):
def _get_buses(interface: "ServiceInterface") -> Set["BaseMessageBus"]:
return interface.__buses

@staticmethod
def _add_bus(interface: "ServiceInterface", bus) -> None:
def _get_handler(
interface: "ServiceInterface", method: _Method, bus: "BaseMessageBus"
) -> Callable[[Message, Callable[[Message], None]], None]:
return interface.__handlers[bus][method]

@staticmethod
def _add_bus(
interface: "ServiceInterface",
bus: "BaseMessageBus",
maker: Callable[
["ServiceInterface", _Method],
Callable[[Message, Callable[[Message], None]], None],
],
) -> None:
interface.__buses.add(bus)
interface.__handlers[bus] = {
method: maker(interface, method) for method in interface.__methods
}

@staticmethod
def _remove_bus(interface: "ServiceInterface", bus) -> None:
def _remove_bus(interface: "ServiceInterface", bus: "BaseMessageBus") -> None:
interface.__buses.remove(bus)
del interface.__handlers[bus]

@staticmethod
def _msg_body_to_args(msg):
Expand Down