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