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

708 lines
22 KiB
Python

"""
事件处理器模块
负责处理游戏事件并触发相应的触觉反馈
"""
import time
from typing import Dict, Any, List, Optional, Callable
import threading
class HapticEventHandler:
"""
触觉事件处理器
负责处理游戏事件并触发相应的触觉反馈
"""
def __init__(self, plugin):
"""
初始化触觉事件处理器
Args:
plugin: 触觉反馈系统插件实例
"""
self.plugin = plugin
self.enabled = False
self.initialized = False
# 事件映射配置
self.event_mapping = {
# 游戏事件到触觉效果的映射
'player_jump': {
'effect': 'impulse',
'intensity': 0.6,
'frequency': 40.0,
'duration': 0.1,
'device': 'feet'
},
'player_land': {
'effect': 'rumble',
'intensity': 0.8,
'frequency': 30.0,
'duration': 0.2,
'device': 'feet'
},
'player_take_damage': {
'effect': 'explosion',
'intensity': 1.0,
'frequency': 50.0,
'duration': 0.5,
'device': 'body'
},
'player_heal': {
'effect': 'pulse',
'intensity': 0.5,
'frequency': 25.0,
'duration': 0.3,
'device': 'chest'
},
'weapon_fire': {
'effect': 'click',
'intensity': 0.7,
'frequency': 80.0,
'duration': 0.05,
'device': 'hands'
},
'weapon_reload': {
'effect': 'buzz',
'intensity': 0.4,
'frequency': 35.0,
'duration': 0.4,
'device': 'hands'
},
'enemy_hit': {
'effect': 'click',
'intensity': 0.5,
'frequency': 60.0,
'duration': 0.08,
'device': 'hands'
},
'enemy_death': {
'effect': 'explosion',
'intensity': 0.9,
'frequency': 45.0,
'duration': 0.6,
'device': 'body'
},
'pickup_item': {
'effect': 'pulse',
'intensity': 0.3,
'frequency': 20.0,
'duration': 0.2,
'device': 'hands'
},
'door_open': {
'effect': 'buzz',
'intensity': 0.3,
'frequency': 15.0,
'duration': 0.3,
'device': 'hands'
},
'door_close': {
'effect': 'click',
'intensity': 0.4,
'frequency': 25.0,
'duration': 0.1,
'device': 'hands'
},
'explosion': {
'effect': 'explosion',
'intensity': 1.0,
'frequency': 35.0,
'duration': 1.0,
'device': 'body'
},
'ui_button_click': {
'effect': 'click',
'intensity': 0.3,
'frequency': 100.0,
'duration': 0.05,
'device': 'hands'
},
'ui_button_hover': {
'effect': 'soft_rumble',
'intensity': 0.1,
'frequency': 10.0,
'duration': 0.1,
'device': 'hands'
}
}
# 事件优先级配置
self.event_priority = {
'player_take_damage': 100,
'explosion': 90,
'enemy_death': 80,
'player_land': 70,
'weapon_fire': 60,
'player_jump': 50,
'enemy_hit': 40,
'pickup_item': 30,
'door_open': 20,
'door_close': 20,
'ui_button_click': 10,
'ui_button_hover': 5,
'player_heal': 40,
'weapon_reload': 30
}
# 事件队列
self.event_queue = []
self.event_queue_lock = threading.Lock()
# 事件抑制配置
self.event_suppression = {
'enable_suppression': True,
'suppression_time': 0.1, # 秒
'suppressed_events': set()
}
# 事件组合配置
self.event_combination = {
'enable_combination': True,
'combination_window': 0.5, # 秒
'max_combined_events': 5
}
# 状态跟踪
self.event_state = {
'last_event_time': {},
'combined_events': [],
'active_events': {}
}
# 统计信息
self.stats = {
'events_received': 0,
'events_processed': 0,
'events_suppressed': 0,
'events_combined': 0,
'haptic_effects_triggered': 0
}
# 回调函数
self.event_callbacks = {
'event_received': [],
'event_processed': [],
'event_suppressed': [],
'event_combined': []
}
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
print("✓ 触觉事件处理器已启用")
return True
except Exception as e:
print(f"✗ 触觉事件处理器启用失败: {e}")
import traceback
traceback.print_exc()
return False
def disable(self):
"""禁用触觉事件处理器"""
try:
self.enabled = False
print("✓ 触觉事件处理器已禁用")
except Exception as e:
print(f"✗ 触觉事件处理器禁用失败: {e}")
import traceback
traceback.print_exc()
def finalize(self):
"""清理触觉事件处理器资源"""
try:
self.disable()
self.event_mapping.clear()
self.event_queue.clear()
self.event_state.clear()
self.event_callbacks.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
# 处理事件队列
self._process_event_queue()
# 更新事件状态
self._update_event_state()
except Exception as e:
print(f"✗ 触觉事件处理器更新失败: {e}")
import traceback
traceback.print_exc()
def _process_event_queue(self):
"""处理事件队列"""
try:
with self.event_queue_lock:
if not self.event_queue:
return
# 获取事件并清空队列
events_to_process = self.event_queue[:]
self.event_queue.clear()
# 处理每个事件
for event in events_to_process:
self._process_event(event)
except Exception as e:
print(f"✗ 事件队列处理失败: {e}")
def _update_event_state(self):
"""更新事件状态"""
try:
current_time = time.time()
# 清理过期的抑制事件
suppression_time = self.event_suppression['suppression_time']
expired_suppressions = [
event_type for event_type, timestamp in
self.event_suppression['suppressed_events']
if current_time - timestamp > suppression_time
]
for event_type in expired_suppressions:
self.event_suppression['suppressed_events'].discard(event_type)
# 清理过期的组合事件
combination_window = self.event_combination['combination_window']
self.event_state['combined_events'] = [
event for event in self.event_state['combined_events']
if current_time - event.get('timestamp', 0) <= combination_window
]
except Exception as e:
print(f"✗ 事件状态更新失败: {e}")
def handle_event(self, event_type: str, event_data: Dict[str, Any] = None) -> bool:
"""
处理事件
Args:
event_type: 事件类型
event_data: 事件数据
Returns:
是否处理成功
"""
try:
if not self.enabled:
return False
# 创建事件对象
event = {
'type': event_type,
'data': event_data or {},
'timestamp': time.time(),
'priority': self.event_priority.get(event_type, 50)
}
# 添加到事件队列
with self.event_queue_lock:
self.event_queue.append(event)
# 触发事件接收回调
self._trigger_event_callback('event_received', {
'event': event
})
self.stats['events_received'] += 1
return True
except Exception as e:
print(f"✗ 事件处理失败: {e}")
return False
def _process_event(self, event: Dict[str, Any]):
"""
处理单个事件
Args:
event: 事件对象
"""
try:
event_type = event['type']
event_data = event['data']
timestamp = event['timestamp']
# 检查事件抑制
if self.event_suppression['enable_suppression']:
if event_type in [e[0] for e in self.event_suppression['suppressed_events']]:
# 事件被抑制
self.stats['events_suppressed'] += 1
# 触发抑制回调
self._trigger_event_callback('event_suppressed', {
'event': event
})
return
# 添加到抑制列表
self.event_suppression['suppressed_events'].add((event_type, timestamp))
# 检查事件组合
if self.event_combination['enable_combination']:
self._handle_event_combination(event)
# 处理事件映射
if event_type in self.event_mapping:
self._trigger_haptic_effect(event_type, event_data)
# 触发事件处理回调
self._trigger_event_callback('event_processed', {
'event': event
})
self.stats['events_processed'] += 1
except Exception as e:
print(f"✗ 单个事件处理失败: {e}")
def _handle_event_combination(self, event: Dict[str, Any]):
"""
处理事件组合
Args:
event: 事件对象
"""
try:
current_time = time.time()
combination_window = self.event_combination['combination_window']
# 添加到组合事件列表
self.event_state['combined_events'].append(event)
# 保持列表大小
if len(self.event_state['combined_events']) > self.event_combination['max_combined_events']:
self.event_state['combined_events'].pop(0)
# 检查是否达到组合条件
if len(self.event_state['combined_events']) >= 3:
# 检查时间窗口
oldest_event = self.event_state['combined_events'][0]
if current_time - oldest_event['timestamp'] <= combination_window:
# 触发组合事件回调
self._trigger_event_callback('event_combined', {
'events': self.event_state['combined_events'].copy()
})
self.stats['events_combined'] += 1
# 清空组合事件列表
self.event_state['combined_events'].clear()
except Exception as e:
print(f"✗ 事件组合处理失败: {e}")
def _trigger_haptic_effect(self, event_type: str, event_data: Dict[str, Any]):
"""
触发触觉效果
Args:
event_type: 事件类型
event_data: 事件数据
"""
try:
if not self.plugin.haptic_manager:
return
# 获取效果配置
effect_config = self.event_mapping.get(event_type)
if not effect_config:
return
# 提取效果参数
effect_type = effect_config['effect']
intensity = effect_config['intensity']
frequency = effect_config['frequency']
duration = effect_config['duration']
device_type = effect_config.get('device')
# 获取设备ID
device_id = None
if device_type and self.plugin.device_manager:
devices = self.plugin.device_manager.get_devices_by_type(device_type)
if devices:
device_id = devices[0]['id']
# 应用事件数据中的参数覆盖
if 'intensity' in event_data:
intensity *= event_data['intensity']
if 'frequency' in event_data:
frequency *= event_data['frequency']
if 'duration' in event_data:
duration *= event_data['duration']
# 播放触觉效果
effect_id = self.plugin.haptic_manager.play_effect(
effect_type=effect_type,
device_id=device_id,
intensity=intensity,
duration=duration,
frequency=frequency,
parameters={
'event_type': event_type,
'event_data': event_data
}
)
if effect_id >= 0:
self.stats['haptic_effects_triggered'] += 1
print(f"✓ 触觉效果已触发: {event_type} -> {effect_type}")
except Exception as e:
print(f"✗ 触觉效果触发失败: {e}")
def register_event_mapping(self, event_type: str, effect_config: Dict[str, Any]) -> bool:
"""
注册事件映射
Args:
event_type: 事件类型
effect_config: 效果配置
Returns:
是否注册成功
"""
try:
self.event_mapping[event_type] = effect_config
print(f"✓ 事件映射已注册: {event_type}")
return True
except Exception as e:
print(f"✗ 事件映射注册失败: {e}")
return False
def unregister_event_mapping(self, event_type: str) -> bool:
"""
注销事件映射
Args:
event_type: 事件类型
Returns:
是否注销成功
"""
try:
if event_type in self.event_mapping:
del self.event_mapping[event_type]
print(f"✓ 事件映射已注销: {event_type}")
return True
else:
print(f"✗ 事件映射不存在: {event_type}")
return False
except Exception as e:
print(f"✗ 事件映射注销失败: {e}")
return False
def set_event_priority(self, event_type: str, priority: int) -> bool:
"""
设置事件优先级
Args:
event_type: 事件类型
priority: 优先级值
Returns:
是否设置成功
"""
try:
self.event_priority[event_type] = priority
print(f"✓ 事件优先级已设置: {event_type} = {priority}")
return True
except Exception as e:
print(f"✗ 事件优先级设置失败: {e}")
return False
def set_event_suppression(self, config: Dict[str, Any]) -> bool:
"""
设置事件抑制配置
Args:
config: 配置字典
Returns:
是否设置成功
"""
try:
self.event_suppression.update(config)
print(f"✓ 事件抑制配置已更新: {self.event_suppression}")
return True
except Exception as e:
print(f"✗ 事件抑制配置设置失败: {e}")
return False
def set_event_combination(self, config: Dict[str, Any]) -> bool:
"""
设置事件组合配置
Args:
config: 配置字典
Returns:
是否设置成功
"""
try:
self.event_combination.update(config)
print(f"✓ 事件组合配置已更新: {self.event_combination}")
return True
except Exception as e:
print(f"✗ 事件组合配置设置失败: {e}")
return False
def get_event_mapping(self) -> Dict[str, Dict[str, Any]]:
"""
获取事件映射
Returns:
事件映射字典
"""
return self.event_mapping.copy()
def get_event_priority(self) -> Dict[str, int]:
"""
获取事件优先级
Returns:
事件优先级字典
"""
return self.event_priority.copy()
def get_event_suppression_config(self) -> Dict[str, Any]:
"""
获取事件抑制配置
Returns:
配置字典
"""
return self.event_suppression.copy()
def get_event_combination_config(self) -> Dict[str, Any]:
"""
获取事件组合配置
Returns:
配置字典
"""
return self.event_combination.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, int]:
"""
获取统计信息
Returns:
统计信息字典
"""
return self.stats.copy()
def reset_stats(self):
"""重置统计信息"""
try:
self.stats = {
'events_received': 0,
'events_processed': 0,
'events_suppressed': 0,
'events_combined': 0,
'haptic_effects_triggered': 0
}
print("✓ 事件处理器统计信息已重置")
except Exception as e:
print(f"✗ 事件处理器统计信息重置失败: {e}")