Skip to content
This repository has been archived by the owner on Mar 8, 2022. It is now read-only.

Commit

Permalink
fix map event
Browse files Browse the repository at this point in the history
  • Loading branch information
edenhaus committed Sep 29, 2021
1 parent eefed9b commit 69faaa3
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 12 deletions.
30 changes: 21 additions & 9 deletions deebotozmo/event_emitter.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ class EventListener(Generic[T]):
def __init__(
self, emitter: "EventEmitter", callback: Callable[[T], Awaitable[None]]
) -> None:
self._emitter = emitter
self.callback = callback
self._emitter: Final = emitter
self.callback: Final = callback

def unsubscribe(self) -> None:
"""Unsubscribe from event representation."""
Expand Down Expand Up @@ -94,27 +94,39 @@ def request_refresh(self) -> None:
asyncio.create_task(self._call_refresh_function())


class ThrottleEventEmitter(EventEmitter[T]):
"""An event emitter, which throttle the notifications."""
class DebounceAtMostEventEmitter(EventEmitter[T]):
"""An event emitter, which debounce the event at most the given time."""

def __init__(
self,
refresh_function: Callable[[], Awaitable[None]],
throttle_seconds: int,
notify_on_equal_event: bool = False,
debounce_at_most_seconds: int,
):
super().__init__(refresh_function, notify_on_equal_event)
super().__init__(refresh_function, True)
self._last_event_time: float = 0.0
self._throttle_seconds: Final = throttle_seconds
self._debounce_at_most_seconds: Final = debounce_at_most_seconds
self._timer_task: Optional[asyncio.TimerHandle] = None

def _call_later(self) -> None:
self._timer_task = None
if self._last_event:
super().notify(self._last_event)

def notify(self, event: T) -> bool:
"""Notify subscriber with given event representation."""
if time.time() > self._last_event_time + self._throttle_seconds:
self._last_event = event
if time.time() > self._last_event_time + self._debounce_at_most_seconds:
notified = super().notify(event)
if notified:
self._last_event_time = time.time()
return notified

if self._timer_task:
self._timer_task.cancel()

self._timer_task = asyncio.get_event_loop().call_later(
self._debounce_at_most_seconds, self._call_later
)
return False


Expand Down
5 changes: 2 additions & 3 deletions deebotozmo/map.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
GetPos,
)
from deebotozmo.constants import MAP_TRACE_POINT_COUNT, ROOMS_FROM_ECOVACS
from deebotozmo.event_emitter import EventEmitter, ThrottleEventEmitter
from deebotozmo.event_emitter import DebounceAtMostEventEmitter, EventEmitter
from deebotozmo.events import MapEvent, RoomsEvent
from deebotozmo.models import Coordinate, Room
from deebotozmo.util import get_refresh_function
Expand Down Expand Up @@ -79,12 +79,11 @@ class MapEvents:
"""Map events representation."""

def __init__(self, execute_command: Callable[[Command], Awaitable[None]]) -> None:
self.map: Final[EventEmitter[MapEvent]] = ThrottleEventEmitter[MapEvent](
self.map: Final[EventEmitter[MapEvent]] = DebounceAtMostEventEmitter[MapEvent](
get_refresh_function(
[GetMapTrace(), GetPos(), GetMajorMap()], execute_command
),
5,
True,
)
self.rooms: Final[EventEmitter[RoomsEvent]] = EventEmitter[RoomsEvent](
get_refresh_function([GetCachedMapInfo()], execute_command)
Expand Down

0 comments on commit 69faaa3

Please sign in to comment.