EG/plugins/user/voice_control/events/event_handler.py
2025-10-30 11:46:41 +08:00

739 lines
24 KiB
Python

"""
事件处理器模块
负责处理语音控制相关的事件
"""
import time
from typing import Dict, Any, List, Optional, Callable
import threading
import queue
class VoiceEventHandler:
"""
事件处理器
负责处理语音控制相关的事件
"""
def __init__(self, plugin):
"""
初始化事件处理器
Args:
plugin: 语音控制插件实例
"""
self.plugin = plugin
self.enabled = False
self.initialized = False
# 事件队列
self.event_queue = queue.Queue(maxsize=100)
# 事件监听器
self.event_listeners = {}
# 事件配置
self.event_config = {
'enable_event_queue': True,
'max_queue_size': 100,
'enable_event_filtering': True,
'filter_duplicate_events': True,
'duplicate_time_window': 1.0,
'enable_async_processing': True,
'max_processing_threads': 4
}
# 事件统计
self.event_stats = {
'events_received': 0,
'events_processed': 0,
'events_dropped': 0,
'events_filtered': 0,
'processing_errors': 0,
'average_processing_time': 0.0
}
# 事件历史
self.event_history = []
self.max_history_size = 1000
# 线程管理
self.processing_threads = []
self.running = False
# 回调函数
self.event_callbacks = {
'event_received': [],
'event_processed': [],
'event_error': [],
'event_queue_full': []
}
# 时间戳记录
self.last_event_time = 0.0
self.last_processing_time = 0.0
# 重复事件跟踪
self.recent_events = {}
print("✓ 事件处理器已创建")
def initialize(self) -> bool:
"""
初始化事件处理器
Returns:
是否初始化成功
"""
try:
self.initialized = True
print("✓ 事件处理器初始化完成")
return True
except Exception as e:
print(f"✗ 事件处理器初始化失败: {e}")
import traceback
traceback.print_exc()
return False
def enable(self) -> bool:
"""
启用事件处理器
Returns:
是否启用成功
"""
try:
if not self.initialized:
print("✗ 事件处理器未初始化")
return False
self.enabled = True
self.running = True
# 启动处理线程
if self.event_config['enable_async_processing']:
thread_count = min(self.event_config['max_processing_threads'], 4)
for i in range(thread_count):
thread = threading.Thread(target=self._processing_loop, daemon=True,
name=f"EventProcessor-{i}")
self.processing_threads.append(thread)
thread.start()
print("✓ 事件处理器已启用")
return True
except Exception as e:
print(f"✗ 事件处理器启用失败: {e}")
import traceback
traceback.print_exc()
return False
def disable(self):
"""禁用事件处理器"""
try:
self.enabled = False
self.running = False
# 等待处理线程结束
for thread in self.processing_threads:
if thread.is_alive():
thread.join(timeout=1.0)
self.processing_threads.clear()
print("✓ 事件处理器已禁用")
except Exception as e:
print(f"✗ 事件处理器禁用失败: {e}")
import traceback
traceback.print_exc()
def finalize(self):
"""清理事件处理器资源"""
try:
self.disable()
self.event_listeners.clear()
self.event_callbacks.clear()
# 清空事件队列
while not self.event_queue.empty():
try:
self.event_queue.get_nowait()
except queue.Empty:
break
self.event_history.clear()
self.recent_events.clear()
self.initialized = False
print("✓ 事件处理器资源已清理")
except Exception as e:
print(f"✗ 事件处理器资源清理失败: {e}")
import traceback
traceback.print_exc()
def update(self, dt: float):
"""
更新事件处理器状态
Args:
dt: 时间增量
"""
try:
if not self.enabled:
return
current_time = time.time()
self.last_event_time = current_time
# 清理过期的重复事件记录
self._cleanup_recent_events(current_time)
except Exception as e:
print(f"✗ 事件处理器更新失败: {e}")
import traceback
traceback.print_exc()
def _processing_loop(self):
"""事件处理循环"""
try:
while self.running and self.enabled:
try:
# 从队列获取事件
if not self.event_queue.empty():
event_data = self.event_queue.get_nowait()
self._process_event(event_data)
else:
time.sleep(0.01)
except queue.Empty:
time.sleep(0.01)
except Exception as e:
print(f"✗ 事件处理循环错误: {e}")
time.sleep(0.1)
except Exception as e:
print(f"✗ 事件处理循环失败: {e}")
def _cleanup_recent_events(self, current_time: float):
"""清理过期的重复事件记录"""
try:
expired_events = [
event_key for event_key, event_time in self.recent_events.items()
if current_time - event_time > self.event_config['duplicate_time_window']
]
for event_key in expired_events:
del self.recent_events[event_key]
except Exception as e:
print(f"✗ 重复事件清理失败: {e}")
def post_event(self, event_type: str, event_data: Dict[str, Any] = None) -> bool:
"""
发布事件
Args:
event_type: 事件类型
event_data: 事件数据
Returns:
是否发布成功
"""
try:
if not self.enabled:
print("✗ 事件处理器未启用")
return False
# 创建事件对象
event = {
'type': event_type,
'data': event_data or {},
'timestamp': time.time(),
'id': f"{event_type}_{int(time.time() * 1000000)}"
}
# 触发事件接收回调
self._trigger_event_callback('event_received', event)
# 更新统计信息
self.event_stats['events_received'] += 1
# 事件过滤
if self.event_config['enable_event_filtering']:
if not self._filter_event(event):
self.event_stats['events_filtered'] += 1
return True
# 检查重复事件
if self.event_config['filter_duplicate_events']:
if self._is_duplicate_event(event):
self.event_stats['events_filtered'] += 1
return True
# 添加到事件队列
if self.event_config['enable_event_queue']:
try:
self.event_queue.put_nowait(event)
# 记录事件历史
self._record_event_history(event)
return True
except queue.Full:
self.event_stats['events_dropped'] += 1
print("✗ 事件队列已满,丢弃事件")
# 触发队列满回调
self._trigger_event_callback('event_queue_full', {
'event': event,
'queue_size': self.event_queue.qsize()
})
return False
else:
# 直接处理事件
return self._process_event(event)
except Exception as e:
print(f"✗ 事件发布失败: {e}")
import traceback
traceback.print_exc()
return False
def _filter_event(self, event: Dict[str, Any]) -> bool:
"""
过滤事件
Args:
event: 事件对象
Returns:
是否通过过滤
"""
try:
# 这里可以实现具体的事件过滤逻辑
# 例如:根据事件类型、优先级等进行过滤
# 示例:过滤掉低置信度的语音识别事件
if event['type'] == 'speech_recognized':
confidence = event['data'].get('confidence', 1.0)
if confidence < 0.3: # 置信度阈值
return False
return True
except Exception as e:
print(f"✗ 事件过滤失败: {e}")
return True # 默认通过过滤
def _is_duplicate_event(self, event: Dict[str, Any]) -> bool:
"""
检查是否为重复事件
Args:
event: 事件对象
Returns:
是否为重复事件
"""
try:
# 创建事件键
event_key = f"{event['type']}_{hash(str(event['data']))}"
current_time = time.time()
# 检查是否在时间窗口内已存在相同事件
if event_key in self.recent_events:
last_time = self.recent_events[event_key]
if current_time - last_time < self.event_config['duplicate_time_window']:
return True
# 记录当前事件时间
self.recent_events[event_key] = current_time
return False
except Exception as e:
print(f"✗ 重复事件检查失败: {e}")
return False
def _process_event(self, event: Dict[str, Any]) -> bool:
"""
处理事件
Args:
event: 事件对象
Returns:
是否处理成功
"""
try:
start_time = time.time()
event_type = event['type']
event_data = event['data']
# 查找事件监听器
listeners = self.event_listeners.get(event_type, [])
if listeners:
# 调用所有监听器
for listener in listeners:
try:
listener(event_type, event_data)
except Exception as e:
print(f"✗ 事件监听器执行失败: {e}")
self.event_stats['processing_errors'] += 1
# 触发事件错误回调
self._trigger_event_callback('event_error', {
'event': event,
'error': str(e),
'listener': listener.__name__ if hasattr(listener, '__name__') else 'unknown'
})
# 更新统计信息
self.event_stats['events_processed'] += 1
# 触发事件处理回调
self._trigger_event_callback('event_processed', event)
# 计算处理时间
processing_time = time.time() - start_time
self.event_stats['average_processing_time'] = (
(self.event_stats['average_processing_time'] * (self.event_stats['events_processed'] - 1) +
processing_time) / self.event_stats['events_processed']
)
return True
else:
# 没有监听器,但事件仍被处理
self.event_stats['events_processed'] += 1
self._trigger_event_callback('event_processed', event)
return True
except Exception as e:
print(f"✗ 事件处理失败: {e}")
import traceback
traceback.print_exc()
self.event_stats['processing_errors'] += 1
# 触发事件错误回调
self._trigger_event_callback('event_error', {
'event': event,
'error': str(e),
'listener': 'processor'
})
return False
def _record_event_history(self, event: Dict[str, Any]):
"""
记录事件历史
Args:
event: 事件对象
"""
try:
self.event_history.append(event)
# 保持历史记录大小
if len(self.event_history) > self.max_history_size:
self.event_history.pop(0)
except Exception as e:
print(f"✗ 事件历史记录失败: {e}")
def register_event_listener(self, event_type: str, listener: Callable) -> bool:
"""
注册事件监听器
Args:
event_type: 事件类型
listener: 监听器函数
Returns:
是否注册成功
"""
try:
if event_type not in self.event_listeners:
self.event_listeners[event_type] = []
self.event_listeners[event_type].append(listener)
print(f"✓ 事件监听器已注册: {event_type}")
return True
except Exception as e:
print(f"✗ 事件监听器注册失败: {e}")
return False
def unregister_event_listener(self, event_type: str, listener: Callable) -> bool:
"""
注销事件监听器
Args:
event_type: 事件类型
listener: 监听器函数
Returns:
是否注销成功
"""
try:
if event_type in self.event_listeners:
if listener in self.event_listeners[event_type]:
self.event_listeners[event_type].remove(listener)
print(f"✓ 事件监听器已注销: {event_type}")
return True
print(f"✗ 事件监听器不存在: {event_type}")
return False
except Exception as e:
print(f"✗ 事件监听器注销失败: {e}")
return False
def get_event_listeners(self) -> Dict[str, List[Callable]]:
"""
获取事件监听器
Returns:
事件监听器字典
"""
return {k: v.copy() for k, v in self.event_listeners.items()}
def get_event_queue_size(self) -> int:
"""
获取事件队列大小
Returns:
队列大小
"""
return self.event_queue.qsize()
def clear_event_queue(self) -> bool:
"""
清空事件队列
Returns:
是否清空成功
"""
try:
while not self.event_queue.empty():
try:
self.event_queue.get_nowait()
except queue.Empty:
break
print("✓ 事件队列已清空")
return True
except Exception as e:
print(f"✗ 事件队列清空失败: {e}")
return False
def get_event_history(self) -> List[Dict[str, Any]]:
"""
获取事件历史
Returns:
事件历史列表
"""
return self.event_history.copy()
def clear_event_history(self):
"""清空事件历史"""
try:
self.event_history.clear()
print("✓ 事件历史已清空")
except Exception as e:
print(f"✗ 事件历史清空失败: {e}")
def set_event_config(self, config: Dict[str, Any]) -> bool:
"""
设置事件配置
Args:
config: 配置字典
Returns:
是否设置成功
"""
try:
self.event_config.update(config)
print(f"✓ 事件配置已更新: {self.event_config}")
return True
except Exception as e:
print(f"✗ 事件配置设置失败: {e}")
return False
def get_event_config(self) -> Dict[str, Any]:
"""
获取事件配置
Returns:
配置字典
"""
return self.event_config.copy()
def _trigger_event_callback(self, callback_type: str, data: Dict[str, Any]):
"""
触发事件回调
Args:
callback_type: 回调类型
data: 回调数据
"""
try:
if callback_type in self.event_callbacks:
for callback in self.event_callbacks[callback_type]:
try:
callback(data)
except Exception as e:
print(f"✗ 事件回调执行失败: {e}")
except Exception as e:
print(f"✗ 事件回调触发失败: {e}")
def register_event_callback(self, callback_type: str, callback: Callable):
"""
注册事件回调
Args:
callback_type: 回调类型
callback: 回调函数
"""
try:
if callback_type in self.event_callbacks:
self.event_callbacks[callback_type].append(callback)
print(f"✓ 事件回调已注册: {callback_type}")
else:
print(f"✗ 无效的回调类型: {callback_type}")
except Exception as e:
print(f"✗ 事件回调注册失败: {e}")
def unregister_event_callback(self, callback_type: str, callback: Callable):
"""
注销事件回调
Args:
callback_type: 回调类型
callback: 回调函数
"""
try:
if callback_type in self.event_callbacks:
if callback in self.event_callbacks[callback_type]:
self.event_callbacks[callback_type].remove(callback)
print(f"✓ 事件回调已注销: {callback_type}")
except Exception as e:
print(f"✗ 事件回调注销失败: {e}")
def get_stats(self) -> Dict[str, Any]:
"""
获取统计信息
Returns:
统计信息字典
"""
return self.event_stats.copy()
def reset_stats(self):
"""重置统计信息"""
try:
self.event_stats = {
'events_received': 0,
'events_processed': 0,
'events_dropped': 0,
'events_filtered': 0,
'processing_errors': 0,
'average_processing_time': 0.0
}
print("✓ 事件处理器统计信息已重置")
except Exception as e:
print(f"✗ 事件处理器统计信息重置失败: {e}")
# 常用事件处理方法
def handle_speech_recognized(self, event_type: str, event_data: Dict[str, Any]):
"""
处理语音识别事件
Args:
event_type: 事件类型
event_data: 事件数据
"""
try:
text = event_data.get('text', '')
confidence = event_data.get('confidence', 0.0)
print(f"🎤 语音识别事件: '{text}' (置信度: {confidence:.2f})")
# 传递给命令处理器
if self.plugin.command_processor:
self.plugin.command_processor.process_command(text, confidence)
except Exception as e:
print(f"✗ 语音识别事件处理失败: {e}")
def handle_speech_synthesis_started(self, event_type: str, event_data: Dict[str, Any]):
"""
处理语音合成开始事件
Args:
event_type: 事件类型
event_data: 事件数据
"""
try:
text = event_data.get('text', '')
print(f"🔊 语音合成开始: '{text}'")
except Exception as e:
print(f"✗ 语音合成开始事件处理失败: {e}")
def handle_speech_synthesis_completed(self, event_type: str, event_data: Dict[str, Any]):
"""
处理语音合成完成事件
Args:
event_type: 事件类型
event_data: 事件数据
"""
try:
text = event_data.get('text', '')
print(f"✅ 语音合成完成: '{text}'")
except Exception as e:
print(f"✗ 语音合成完成事件处理失败: {e}")
def handle_wake_word_detected(self, event_type: str, event_data: Dict[str, Any]):
"""
处理唤醒词检测事件
Args:
event_type: 事件类型
event_data: 事件数据
"""
try:
text = event_data.get('text', '')
confidence = event_data.get('confidence', 0.0)
print(f"🔔 唤醒词检测: '{text}' (置信度: {confidence:.2f})")
# 可以在这里添加特殊处理逻辑
if self.plugin.speech_synthesizer:
# 简单确认音
pass
except Exception as e:
print(f"✗ 唤醒词检测事件处理失败: {e}")
def handle_command_processed(self, event_type: str, event_data: Dict[str, Any]):
"""
处理命令处理事件
Args:
event_type: 事件类型
event_data: 事件数据
"""
try:
command_text = event_data.get('command_text', '')
original_text = event_data.get('original_text', '')
confidence = event_data.get('confidence', 0.0)
match_type = event_data.get('match_type', 'unknown')
print(f"⚙️ 命令处理: '{command_text}' (原始: '{original_text}', 匹配: {match_type}, 置信度: {confidence:.2f})")
except Exception as e:
print(f"✗ 命令处理事件处理失败: {e}")