adds an event object and listens until its set

sets the event object on WebSocketConnectionClosedException

adds __enter__(), __exit__() methods

adds disconnect() to event client. aliases it as unsubscribe

checks for non-empty response with:
`if r := self.base_client.ws.recv()`
before attempting to json.load() it.
This commit is contained in:
onyx-and-iris 2024-01-05 09:57:08 +00:00
parent f1c2efa4a1
commit 6aa6db09eb

View File

@ -1,9 +1,8 @@
import json import json
import logging import logging
import time import threading
from threading import Thread
from websocket import WebSocketTimeoutException from websocket import WebSocketConnectionClosedException, WebSocketTimeoutException
from .baseclient import ObsClient from .baseclient import ObsClient
from .callback import Callback from .callback import Callback
@ -20,8 +19,6 @@ logger = logging.getLogger(__name__)
class EventClient: class EventClient:
DELAY = 0.001
def __init__(self, **kwargs): def __init__(self, **kwargs):
self.logger = logger.getChild(self.__class__.__name__) self.logger = logger.getChild(self.__class__.__name__)
defaultkwargs = {"subs": Subs.LOW_VOLUME} defaultkwargs = {"subs": Subs.LOW_VOLUME}
@ -38,6 +35,12 @@ class EventClient:
self.callback = Callback() self.callback = Callback()
self.subscribe() self.subscribe()
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, exc_traceback):
self.disconnect()
def __repr__(self): def __repr__(self):
return type( return type(
self self
@ -49,33 +52,39 @@ class EventClient:
return type(self).__name__ return type(self).__name__
def subscribe(self): def subscribe(self):
worker = Thread(target=self.trigger, daemon=True) stop_event = threading.Event()
worker.start() self.worker = threading.Thread(
target=self.trigger, daemon=True, args=(stop_event,)
)
self.worker.start()
def trigger(self): def trigger(self, stop_event):
""" """
Continuously listen for events. Continuously listen for events.
Triggers a callback on event received. Triggers a callback on event received.
""" """
self.running = True while not stop_event.is_set():
while self.running:
try: try:
event = json.loads(self.base_client.ws.recv()) if r := self.base_client.ws.recv():
except WebSocketTimeoutException as e: event = json.loads(r)
self.logger.exception(f"{type(e).__name__}: {e}")
raise OBSSDKTimeoutError("Timeout while waiting for event") from e
self.logger.debug(f"Event received {event}") self.logger.debug(f"Event received {event}")
type_, data = ( type_, data = (
event["d"].get("eventType"), event["d"].get("eventType"),
event["d"].get("eventData"), event["d"].get("eventData"),
) )
self.callback.trigger(type_, data if data else {}) self.callback.trigger(type_, data if data else {})
time.sleep(self.DELAY) except WebSocketTimeoutException as e:
self.logger.exception(f"{type(e).__name__}: {e}")
raise OBSSDKTimeoutError("Timeout while waiting for event") from e
except WebSocketConnectionClosedException as e:
self.logger.debug(f"{type(e).__name__} terminating the event thread")
stop_event.set()
def disconnect(self):
"""stop listening for events"""
def unsubscribe(self):
"""
stop listening for events
"""
self.running = False
self.base_client.ws.close() self.base_client.ws.close()
self.worker.join()
unsubscribe = disconnect