EG/plugins/user/vegetation_ecosystem/utils/eco_utils.py
2025-12-12 16:16:15 +08:00

668 lines
20 KiB
Python

"""
生态系统工具类
提供各种实用工具函数和辅助功能
"""
import time
import json
import math
import random
from typing import Dict, Any, List, Optional, Callable
import hashlib
class EcoUtils:
"""
生态系统工具类
提供各种实用工具函数和辅助功能,包括数据处理、性能监控、日志记录等
"""
def __init__(self, plugin):
"""
初始化生态系统工具类
Args:
plugin: 植被和生态系统插件实例
"""
self.plugin = plugin
self.enabled = False
self.initialized = False
# 性能监控
self.performance_monitor = {
'frame_times': [],
'update_times': [],
'render_times': [],
'memory_usage': 0,
'object_counts': {}
}
# 数据缓存
self.data_cache = {}
self.cache_config = {
'max_size': 1000,
'expiration_time': 300 # 5分钟
}
# 日志配置
self.log_config = {
'level': 'INFO',
'file_logging': True,
'console_logging': True,
'max_log_size': 10 * 1024 * 1024, # 10MB
'log_file': 'eco_system.log'
}
# 随机数生成器
self.random_generator = random.Random()
self.random_seed = 12345
# 数据序列化
self.serialization_config = {
'format': 'json',
'compression': False,
'pretty_print': True
}
print("✓ 生态系统工具类已创建")
def initialize(self) -> bool:
"""
初始化生态系统工具类
Returns:
是否初始化成功
"""
try:
# 设置随机种子
self.random_generator.seed(self.random_seed)
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.data_cache.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._update_performance_monitor(dt)
# 清理缓存
self._cleanup_cache()
except Exception as e:
print(f"✗ 生态系统工具类更新失败: {e}")
import traceback
traceback.print_exc()
def _update_performance_monitor(self, dt: float):
"""更新性能监控数据"""
try:
# 记录帧时间
self.performance_monitor['frame_times'].append(dt)
# 保持最近100帧的数据
if len(self.performance_monitor['frame_times']) > 100:
self.performance_monitor['frame_times'].pop(0)
except Exception as e:
print(f"✗ 性能监控更新失败: {e}")
def _cleanup_cache(self):
"""清理过期缓存"""
try:
current_time = time.time()
expired_keys = []
for key, (timestamp, _) in self.data_cache.items():
if current_time - timestamp > self.cache_config['expiration_time']:
expired_keys.append(key)
for key in expired_keys:
del self.data_cache[key]
except Exception as e:
print(f"✗ 缓存清理失败: {e}")
def log_message(self, message: str, level: str = 'INFO'):
"""
记录日志消息
Args:
message: 日志消息
level: 日志级别
"""
try:
# 检查日志级别
levels = ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']
if levels.index(level) < levels.index(self.log_config['level']):
return
timestamp = time.strftime('%Y-%m-%d %H:%M:%S')
log_entry = f"[{timestamp}] {level}: {message}"
# 控制台输出
if self.log_config['console_logging']:
print(log_entry)
# 文件输出
if self.log_config['file_logging']:
try:
with open(self.log_config['log_file'], 'a', encoding='utf-8') as f:
f.write(log_entry + '\n')
except Exception as e:
print(f"✗ 日志文件写入失败: {e}")
except Exception as e:
print(f"✗ 日志记录失败: {e}")
def set_log_level(self, level: str):
"""
设置日志级别
Args:
level: 日志级别
"""
valid_levels = ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']
if level in valid_levels:
self.log_config['level'] = level
self.log_message(f"日志级别设置为: {level}")
else:
self.log_message(f"无效的日志级别: {level}", 'WARNING')
def get_performance_stats(self) -> Dict[str, Any]:
"""
获取性能统计信息
Returns:
性能统计信息字典
"""
try:
if not self.performance_monitor['frame_times']:
return {'fps': 0, 'avg_frame_time': 0, 'min_frame_time': 0, 'max_frame_time': 0}
frame_times = self.performance_monitor['frame_times']
avg_frame_time = sum(frame_times) / len(frame_times)
fps = 1.0 / avg_frame_time if avg_frame_time > 0 else 0
return {
'fps': fps,
'avg_frame_time': avg_frame_time,
'min_frame_time': min(frame_times),
'max_frame_time': max(frame_times),
'frame_count': len(frame_times)
}
except Exception as e:
self.log_message(f"性能统计获取失败: {e}", 'ERROR')
return {}
def reset_performance_stats(self):
"""重置性能统计信息"""
try:
self.performance_monitor['frame_times'].clear()
self.performance_monitor['update_times'].clear()
self.performance_monitor['render_times'].clear()
self.log_message("性能统计信息已重置")
except Exception as e:
self.log_message(f"性能统计重置失败: {e}", 'ERROR')
def cache_data(self, key: str, data: Any):
"""
缓存数据
Args:
key: 缓存键
data: 要缓存的数据
"""
try:
# 检查缓存大小
if len(self.data_cache) >= self.cache_config['max_size']:
# 移除最旧的条目
oldest_key = min(self.data_cache.keys(),
key=lambda k: self.data_cache[k][0])
del self.data_cache[oldest_key]
# 缓存数据
self.data_cache[key] = (time.time(), data)
except Exception as e:
self.log_message(f"数据缓存失败: {e}", 'ERROR')
def get_cached_data(self, key: str) -> Optional[Any]:
"""
获取缓存数据
Args:
key: 缓存键
Returns:
缓存的数据或None
"""
try:
if key in self.data_cache:
timestamp, data = self.data_cache[key]
if time.time() - timestamp < self.cache_config['expiration_time']:
return data
else:
# 缓存过期,删除条目
del self.data_cache[key]
return None
except Exception as e:
self.log_message(f"缓存数据获取失败: {e}", 'ERROR')
return None
def clear_cache(self):
"""清空缓存"""
try:
self.data_cache.clear()
self.log_message("缓存已清空")
except Exception as e:
self.log_message(f"缓存清空失败: {e}", 'ERROR')
def serialize_data(self, data: Any, filename: str = None) -> str:
"""
序列化数据
Args:
data: 要序列化的数据
filename: 文件名(可选)
Returns:
序列化后的字符串
"""
try:
if self.serialization_config['format'] == 'json':
serialized_data = json.dumps(
data,
ensure_ascii=False,
indent=2 if self.serialization_config['pretty_print'] else None
)
if filename:
with open(filename, 'w', encoding='utf-8') as f:
f.write(serialized_data)
return serialized_data
except Exception as e:
self.log_message(f"数据序列化失败: {e}", 'ERROR')
return ""
def deserialize_data(self, data_str: str) -> Any:
"""
反序列化数据
Args:
data_str: 序列化后的字符串
Returns:
反序列化的数据
"""
try:
if self.serialization_config['format'] == 'json':
return json.loads(data_str)
except Exception as e:
self.log_message(f"数据反序列化失败: {e}", 'ERROR')
return None
def load_data_from_file(self, filename: str) -> Any:
"""
从文件加载数据
Args:
filename: 文件名
Returns:
加载的数据
"""
try:
with open(filename, 'r', encoding='utf-8') as f:
data_str = f.read()
return self.deserialize_data(data_str)
except Exception as e:
self.log_message(f"文件数据加载失败: {e}", 'ERROR')
return None
def save_data_to_file(self, data: Any, filename: str) -> bool:
"""
保存数据到文件
Args:
data: 要保存的数据
filename: 文件名
Returns:
是否保存成功
"""
try:
self.serialize_data(data, filename)
self.log_message(f"数据已保存到文件: {filename}")
return True
except Exception as e:
self.log_message(f"文件数据保存失败: {e}", 'ERROR')
return False
def generate_hash(self, data: Any) -> str:
"""
生成数据哈希值
Args:
data: 要生成哈希的数据
Returns:
哈希值字符串
"""
try:
data_str = str(data).encode('utf-8')
return hashlib.md5(data_str).hexdigest()
except Exception as e:
self.log_message(f"哈希值生成失败: {e}", 'ERROR')
return ""
def interpolate_values(self, start_value: float, end_value: float, progress: float) -> float:
"""
插值计算
Args:
start_value: 起始值
end_value: 结束值
progress: 进度 (0.0-1.0)
Returns:
插值结果
"""
try:
return start_value + (end_value - start_value) * max(0.0, min(1.0, progress))
except Exception as e:
self.log_message(f"插值计算失败: {e}", 'ERROR')
return start_value
def clamp_value(self, value: float, min_value: float, max_value: float) -> float:
"""
限制值范围
Args:
value: 值
min_value: 最小值
max_value: 最大值
Returns:
限制后的值
"""
try:
return max(min_value, min(max_value, value))
except Exception as e:
self.log_message(f"值范围限制失败: {e}", 'ERROR')
return value
def normalize_vector(self, vector: tuple) -> tuple:
"""
标准化向量
Args:
vector: 向量 (x, y, z)
Returns:
标准化后的向量
"""
try:
length = math.sqrt(vector[0]**2 + vector[1]**2 + vector[2]**2)
if length > 0:
return (vector[0] / length, vector[1] / length, vector[2] / length)
return (0, 0, 0)
except Exception as e:
self.log_message(f"向量标准化失败: {e}", 'ERROR')
return (0, 0, 0)
def distance_3d(self, pos1: tuple, pos2: tuple) -> float:
"""
计算3D空间中两点间的距离
Args:
pos1: 位置1 (x, y, z)
pos2: 位置2 (x, y, z)
Returns:
距离
"""
try:
return math.sqrt((pos1[0] - pos2[0])**2 +
(pos1[1] - pos2[1])**2 +
(pos1[2] - pos2[2])**2)
except Exception as e:
self.log_message(f"距离计算失败: {e}", 'ERROR')
return 0.0
def random_float(self, min_value: float, max_value: float) -> float:
"""
生成随机浮点数
Args:
min_value: 最小值
max_value: 最大值
Returns:
随机浮点数
"""
try:
return self.random_generator.uniform(min_value, max_value)
except Exception as e:
self.log_message(f"随机数生成失败: {e}", 'ERROR')
return 0.0
def random_int(self, min_value: int, max_value: int) -> int:
"""
生成随机整数
Args:
min_value: 最小值
max_value: 最大值
Returns:
随机整数
"""
try:
return self.random_generator.randint(min_value, max_value)
except Exception as e:
self.log_message(f"随机整数生成失败: {e}", 'ERROR')
return 0
def set_random_seed(self, seed: int):
"""
设置随机种子
Args:
seed: 随机种子
"""
try:
self.random_seed = seed
self.random_generator.seed(seed)
self.log_message(f"随机种子设置为: {seed}")
except Exception as e:
self.log_message(f"随机种子设置失败: {e}", 'ERROR')
def get_system_info(self) -> Dict[str, Any]:
"""
获取系统信息
Returns:
系统信息字典
"""
try:
return {
'plugin_version': getattr(self.plugin, 'version', 'Unknown'),
'plugin_name': getattr(self.plugin, 'name', 'Unknown'),
'cache_size': len(self.data_cache),
'log_level': self.log_config['level'],
'random_seed': self.random_seed
}
except Exception as e:
self.log_message(f"系统信息获取失败: {e}", 'ERROR')
return {}
def create_timer(self) -> Callable[[], float]:
"""
创建计时器
Returns:
计时器函数,调用时返回经过的时间(秒)
"""
try:
start_time = time.time()
def get_elapsed_time():
return time.time() - start_time
return get_elapsed_time
except Exception as e:
self.log_message(f"计时器创建失败: {e}", 'ERROR')
def dummy_timer():
return 0.0
return dummy_timer
def format_time(self, seconds: float) -> str:
"""
格式化时间显示
Args:
seconds: 秒数
Returns:
格式化后的时间字符串
"""
try:
hours = int(seconds // 3600)
minutes = int((seconds % 3600) // 60)
secs = int(seconds % 60)
if hours > 0:
return f"{hours:02d}:{minutes:02d}:{secs:02d}"
else:
return f"{minutes:02d}:{secs:02d}"
except Exception as e:
self.log_message(f"时间格式化失败: {e}", 'ERROR')
return "00:00"
def get_memory_usage(self) -> int:
"""
获取内存使用情况(简化实现)
Returns:
内存使用量(字节)
"""
try:
# 简化实现,实际项目中可能需要使用更精确的方法
import sys
return sys.getsizeof(self)
except Exception as e:
self.log_message(f"内存使用量获取失败: {e}", 'ERROR')
return 0
def benchmark_function(self, func: Callable, *args, **kwargs) -> Dict[str, Any]:
"""
基准测试函数
Args:
func: 要测试的函数
*args: 函数参数
**kwargs: 函数关键字参数
Returns:
测试结果字典
"""
try:
timer = self.create_timer()
result = func(*args, **kwargs)
elapsed_time = timer()
return {
'result': result,
'execution_time': elapsed_time,
'success': True
}
except Exception as e:
self.log_message(f"函数基准测试失败: {e}", 'ERROR')
return {
'result': None,
'execution_time': 0,
'success': False,
'error': str(e)
}