Spaces:
Runtime error
Runtime error
File size: 5,178 Bytes
cc0dd3c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# Copyright (c) OpenMMLab. All rights reserved.
import logging
from collections import defaultdict
from contextlib import contextmanager
from threading import Event
from typing import Optional
logger = logging.getLogger('Event')
class EventManager():
"""A helper class to manage events.
:class:`EventManager` provides interfaces to register, set, clear and
check events by name.
"""
def __init__(self):
self._events = defaultdict(Event)
def register_event(self, event_name: str, is_keyboard: bool = False):
"""Register an event. A event must be registered first before being
set, cleared or checked.
Args:
event_name (str): The indicator of the event. The name should be
unique in one :class:`EventManager` instance
is_keyboard (bool): Specify weather it is a keyboard event. If so,
the ``event_name`` should be the key value, and the indicator
will be set as ``'_keyboard_{event_name}'``. Otherwise, the
``event_name`` will be directly used as the indicator.
Default: ``False``
"""
if is_keyboard:
event_name = self._get_keyboard_event_name(event_name)
self._events[event_name] = Event()
def set(self, event_name: str, is_keyboard: bool = False):
"""Set the internal flag of an event to ``True``.
Args:
event_name (str): The indicator of the event
is_keyboard (bool): Specify weather it is a keyboard event. See
``register_event()`` for details. Default: False
"""
if is_keyboard:
event_name = self._get_keyboard_event_name(event_name)
self._events[event_name].set()
logger.info(f'Event {event_name} is set.')
def wait(self,
event_name: str = None,
is_keyboard: bool = False,
timeout: Optional[float] = None) -> bool:
"""Block until the internal flag of an event is ``True``.
Args:
event_name (str): The indicator of the event
is_keyboard (bool): Specify weather it is a keyboard event. See
``register_event()`` for details. Default: False
timeout (float, optional): The optional maximum blocking time in
seconds. Default: ``None``
Returns:
bool: The internal event flag on exit.
"""
if is_keyboard:
event_name = self._get_keyboard_event_name(event_name)
return self._events[event_name].wait(timeout)
def is_set(self,
event_name: str = None,
is_keyboard: Optional[bool] = False) -> bool:
"""Check weather the internal flag of an event is ``True``.
Args:
event_name (str): The indicator of the event
is_keyboard (bool): Specify weather it is a keyboard event. See
``register_event()`` for details. Default: False
Returns:
bool: The internal event flag.
"""
if is_keyboard:
event_name = self._get_keyboard_event_name(event_name)
return self._events[event_name].is_set()
def clear(self,
event_name: str = None,
is_keyboard: Optional[bool] = False):
"""Reset the internal flag of en event to False.
Args:
event_name (str): The indicator of the event
is_keyboard (bool): Specify weather it is a keyboard event. See
``register_event()`` for details. Default: False
"""
if is_keyboard:
event_name = self._get_keyboard_event_name(event_name)
self._events[event_name].clear()
logger.info(f'Event {event_name} is cleared.')
@staticmethod
def _get_keyboard_event_name(key):
"""Get keyboard event name from the key value."""
return f'_keyboard_{chr(key) if isinstance(key,int) else key}'
@contextmanager
def wait_and_handle(self,
event_name: str = None,
is_keyboard: Optional[bool] = False):
"""Context manager that blocks until an evenet is set ``True`` and then
goes into the context.
The internal event flag will be reset ``False`` automatically before
entering the context.
Args:
event_name (str): The indicator of the event
is_keyboard (bool): Specify weather it is a keyboard event. See
``register_event()`` for details. Default: False
Example::
>>> from mmpose.apis.webcam.utils import EventManager
>>> manager = EventManager()
>>> manager.register_event('q', is_keybard=True)
>>> # Once the keyboard event `q` is set, ``wait_and_handle``
>>> # will reset the event and enter the context to invoke
>>> # ``foo()``
>>> with manager.wait_and_handle('q', is_keybard=True):
... foo()
"""
self.wait(event_name, is_keyboard)
try:
yield
finally:
self.clear(event_name, is_keyboard)
|