from threading import Event, Lock from collections import defaultdict from queue import Queue, Empty import threading class EventSystem: def __init__(self): self.listeners = defaultdict(list) self.event_queue = Queue() self.lock = Lock() self._stop_event = Event() self.event_thread = threading.Thread(target=self._process_events) self.event_thread.start() def add_listener(self, event_type, callback): with self.lock: self.listeners[event_type].append(callback) def remove_listener(self, event_type, callback): with self.lock: self.listeners[event_type].remove(callback) def emit(self, event_type, data=None, callback=None): self.event_queue.put((event_type, data, callback)) def emit_sync(self, event_type, data=None): results = [] with self.lock: for listener in self.listeners[event_type]: result = listener(data) results.append(result) return results def call_sync(self, event_type, data=None): with self.lock: if event_type in self.listeners and self.listeners[event_type]: # Call only the first registered listener return self.listeners[event_type][0](data) return None def _process_events(self): while not self._stop_event.is_set(): try: event_type, data, callback = self.event_queue.get(timeout=0.1) results = [] with self.lock: for listener in self.listeners[event_type]: result = listener(data) results.append(result) if callback: callback(results) except Empty: pass def stop(self): self._stop_event.set() self.event_thread.join() event_system = EventSystem()