1083 lines
37 KiB
Python
1083 lines
37 KiB
Python
"""
|
||
预设管理器
|
||
管理植被和生态系统插件的预设配置
|
||
"""
|
||
|
||
import json
|
||
import os
|
||
from typing import Dict, Any, List, Optional
|
||
import time
|
||
|
||
class PresetManager:
|
||
"""
|
||
预设管理器
|
||
管理植被和生态系统插件的预设配置,包括创建、保存、加载和应用预设
|
||
"""
|
||
|
||
def __init__(self, plugin):
|
||
"""
|
||
初始化预设管理器
|
||
|
||
Args:
|
||
plugin: 植被和生态系统插件实例
|
||
"""
|
||
self.plugin = plugin
|
||
self.enabled = False
|
||
self.initialized = False
|
||
|
||
# 预设配置
|
||
self.preset_config = {
|
||
'presets_directory': 'presets/ecosystem',
|
||
'default_preset': 'default',
|
||
'auto_save_enabled': True,
|
||
'max_presets': 100
|
||
}
|
||
|
||
# 预设数据
|
||
self.presets = {}
|
||
self.current_preset = None
|
||
|
||
# 预设类别
|
||
self.preset_categories = {
|
||
'vegetation': {'name': '植被', 'description': '植被配置预设'},
|
||
'animals': {'name': '动物', 'description': '动物配置预设'},
|
||
'environment': {'name': '环境', 'description': '环境配置预设'},
|
||
'ecosystem': {'name': '生态系统', 'description': '生态系统配置预设'},
|
||
'seasons': {'name': '季节', 'description': '季节配置预设'},
|
||
'mixed': {'name': '混合', 'description': '混合配置预设'}
|
||
}
|
||
|
||
# 统计信息
|
||
self.stats = {
|
||
'presets_loaded': 0,
|
||
'presets_saved': 0,
|
||
'presets_applied': 0,
|
||
'total_load_time': 0.0,
|
||
'total_save_time': 0.0
|
||
}
|
||
|
||
print("✓ 预设管理器已创建")
|
||
|
||
def initialize(self) -> bool:
|
||
"""
|
||
初始化预设管理器
|
||
|
||
Returns:
|
||
是否初始化成功
|
||
"""
|
||
try:
|
||
# 创建预设目录
|
||
presets_dir = self.preset_config['presets_directory']
|
||
if not os.path.exists(presets_dir):
|
||
os.makedirs(presets_dir)
|
||
|
||
# 加载默认预设
|
||
self._load_default_presets()
|
||
|
||
# 加载用户预设
|
||
self._load_user_presets()
|
||
|
||
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()
|
||
|
||
# 自动保存当前预设
|
||
if self.preset_config['auto_save_enabled'] and self.current_preset:
|
||
self.save_preset(self.current_preset)
|
||
|
||
self.initialized = False
|
||
print("✓ 预设管理器资源已清理")
|
||
|
||
except Exception as e:
|
||
print(f"✗ 预设管理器资源清理失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
|
||
def update(self, dt: float):
|
||
"""
|
||
更新预设管理器状态
|
||
|
||
Args:
|
||
dt: 时间增量
|
||
"""
|
||
# 处理更新逻辑
|
||
pass
|
||
|
||
def _load_default_presets(self):
|
||
"""加载默认预设"""
|
||
try:
|
||
# 创建默认植被预设
|
||
self.presets['default_vegetation'] = {
|
||
'name': '默认植被',
|
||
'category': 'vegetation',
|
||
'description': '默认的植被配置参数',
|
||
'parameters': {
|
||
'grass_density': 0.8,
|
||
'tree_density': 0.3,
|
||
'flower_density': 0.2
|
||
},
|
||
'timestamp': time.time(),
|
||
'is_default': True
|
||
}
|
||
|
||
# 创建默认动物预设
|
||
self.presets['default_animals'] = {
|
||
'name': '默认动物',
|
||
'category': 'animals',
|
||
'description': '默认的动物配置参数',
|
||
'parameters': {
|
||
'rabbit_population': 20,
|
||
'deer_population': 5,
|
||
'bird_population': 30
|
||
},
|
||
'timestamp': time.time(),
|
||
'is_default': True
|
||
}
|
||
|
||
# 创建默认环境预设
|
||
self.presets['default_environment'] = {
|
||
'name': '默认环境',
|
||
'category': 'environment',
|
||
'description': '默认的环境配置参数',
|
||
'parameters': {
|
||
'temperature': 20.0,
|
||
'humidity': 60.0,
|
||
'soil_fertility': 0.5
|
||
},
|
||
'timestamp': time.time(),
|
||
'is_default': True
|
||
}
|
||
|
||
# 创建默认生态系统预设
|
||
self.presets['default_ecosystem'] = {
|
||
'name': '默认生态系统',
|
||
'category': 'ecosystem',
|
||
'description': '默认的生态系统配置参数',
|
||
'parameters': {
|
||
'biodiversity_index': 0.6,
|
||
'stability_index': 0.7,
|
||
'productivity_rate': 1.0
|
||
},
|
||
'timestamp': time.time(),
|
||
'is_default': True
|
||
}
|
||
|
||
# 创建默认季节预设
|
||
self.presets['default_seasons'] = {
|
||
'name': '默认季节',
|
||
'category': 'seasons',
|
||
'description': '默认的季节配置参数',
|
||
'parameters': {
|
||
'spring_duration': 90,
|
||
'summer_duration': 90,
|
||
'autumn_duration': 90,
|
||
'winter_duration': 90
|
||
},
|
||
'timestamp': time.time(),
|
||
'is_default': True
|
||
}
|
||
|
||
# 创建默认混合预设
|
||
self.presets['default_mixed'] = {
|
||
'name': '默认混合',
|
||
'category': 'mixed',
|
||
'description': '默认的混合配置参数',
|
||
'parameters': {
|
||
'vegetation_config': 'default_vegetation',
|
||
'animal_config': 'default_animals',
|
||
'environment_config': 'default_environment'
|
||
},
|
||
'timestamp': time.time(),
|
||
'is_default': True
|
||
}
|
||
|
||
print("✓ 默认预设加载完成")
|
||
|
||
except Exception as e:
|
||
print(f"✗ 默认预设加载失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
|
||
def _load_user_presets(self):
|
||
"""加载用户预设"""
|
||
try:
|
||
load_start_time = time.time()
|
||
|
||
presets_dir = self.preset_config['presets_directory']
|
||
if not os.path.exists(presets_dir):
|
||
print("✓ 用户预设目录不存在,跳过加载")
|
||
return
|
||
|
||
# 遍历预设目录
|
||
for filename in os.listdir(presets_dir):
|
||
if filename.endswith('.json'):
|
||
try:
|
||
filepath = os.path.join(presets_dir, filename)
|
||
with open(filepath, 'r', encoding='utf-8') as f:
|
||
preset_data = json.load(f)
|
||
|
||
# 使用文件名(不含扩展名)作为预设ID
|
||
preset_id = os.path.splitext(filename)[0]
|
||
self.presets[preset_id] = preset_data
|
||
|
||
except Exception as e:
|
||
print(f"✗ 预设文件加载失败 {filename}: {e}")
|
||
|
||
load_time = time.time() - load_start_time
|
||
self.stats['presets_loaded'] = len(self.presets)
|
||
self.stats['total_load_time'] = load_time
|
||
|
||
print(f"✓ 用户预设加载完成,共加载 {len(self.presets)} 个预设,耗时: {load_time:.3f}秒")
|
||
|
||
except Exception as e:
|
||
print(f"✗ 用户预设加载失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
|
||
def save_preset(self, preset_id: str, preset_data: Dict[str, Any] = None) -> bool:
|
||
"""
|
||
保存预设
|
||
|
||
Args:
|
||
preset_id: 预设ID
|
||
preset_data: 预设数据(如果为None,则保存当前配置)
|
||
|
||
Returns:
|
||
是否保存成功
|
||
"""
|
||
try:
|
||
save_start_time = time.time()
|
||
|
||
if not self.enabled:
|
||
print("✗ 预设管理器未启用")
|
||
return False
|
||
|
||
# 如果未提供预设数据,则创建当前配置的快照
|
||
if preset_data is None:
|
||
preset_data = self._create_current_preset_snapshot(preset_id)
|
||
|
||
# 保存预设数据
|
||
self.presets[preset_id] = preset_data
|
||
|
||
# 保存到文件
|
||
presets_dir = self.preset_config['presets_directory']
|
||
filepath = os.path.join(presets_dir, f"{preset_id}.json")
|
||
|
||
with open(filepath, 'w', encoding='utf-8') as f:
|
||
json.dump(preset_data, f, ensure_ascii=False, indent=2)
|
||
|
||
# 更新统计信息
|
||
save_time = time.time() - save_start_time
|
||
self.stats['presets_saved'] += 1
|
||
self.stats['total_save_time'] += save_time
|
||
|
||
print(f"✓ 预设 '{preset_id}' 保存完成,耗时: {save_time:.3f}秒")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 预设保存失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
def _create_current_preset_snapshot(self, preset_id: str) -> Dict[str, Any]:
|
||
"""
|
||
创建当前配置的预设快照
|
||
|
||
Args:
|
||
preset_id: 预设ID
|
||
|
||
Returns:
|
||
预设数据字典
|
||
"""
|
||
try:
|
||
# 获取当前插件配置
|
||
preset_data = {
|
||
'name': preset_id,
|
||
'category': 'mixed', # 默认类别
|
||
'description': '用户自定义预设',
|
||
'parameters': {},
|
||
'timestamp': time.time(),
|
||
'is_default': False
|
||
}
|
||
|
||
# 添加植被管理器配置
|
||
if self.plugin.vegetation_manager:
|
||
vm = self.plugin.vegetation_manager
|
||
preset_data['parameters'].update({
|
||
'environment_factors': vm.get_environment_factors(),
|
||
'distribution_config': vm.get_distribution_config()
|
||
})
|
||
|
||
# 添加动物模拟器配置
|
||
if self.plugin.animal_simulator:
|
||
asim = self.plugin.animal_simulator
|
||
preset_data['parameters'].update({
|
||
'animal_environment_factors': asim.get_environment_factors(),
|
||
'animal_behavior_config': asim.get_behavior_config()
|
||
})
|
||
|
||
# 添加生态系统管理器配置
|
||
if self.plugin.ecosystem_manager:
|
||
em = self.plugin.ecosystem_manager
|
||
preset_data['parameters'].update({
|
||
'ecosystem_parameters': em.get_ecosystem_parameters(),
|
||
'time_config': em.get_time_config()
|
||
})
|
||
|
||
# 添加季节效应配置
|
||
if self.plugin.seasonal_effects:
|
||
se = self.plugin.seasonal_effects
|
||
preset_data['parameters'].update({
|
||
'season_config': se.get_time_config(),
|
||
'current_season': se.get_current_season()
|
||
})
|
||
|
||
return preset_data
|
||
|
||
except Exception as e:
|
||
print(f"✗ 预设快照创建失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return {
|
||
'name': preset_id,
|
||
'category': 'mixed',
|
||
'description': '默认预设',
|
||
'parameters': {},
|
||
'timestamp': time.time(),
|
||
'is_default': False
|
||
}
|
||
|
||
def load_preset(self, preset_id: str) -> Optional[Dict[str, Any]]:
|
||
"""
|
||
加载预设
|
||
|
||
Args:
|
||
preset_id: 预设ID
|
||
|
||
Returns:
|
||
预设数据字典或None
|
||
"""
|
||
try:
|
||
if not self.enabled:
|
||
print("✗ 预设管理器未启用")
|
||
return None
|
||
|
||
if preset_id not in self.presets:
|
||
print(f"✗ 预设不存在: {preset_id}")
|
||
return None
|
||
|
||
preset_data = self.presets[preset_id]
|
||
|
||
# 更新统计信息
|
||
self.stats['presets_applied'] += 1
|
||
self.current_preset = preset_id
|
||
|
||
print(f"✓ 预设 '{preset_id}' 加载完成")
|
||
return preset_data
|
||
|
||
except Exception as e:
|
||
print(f"✗ 预设加载失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return None
|
||
|
||
def apply_preset(self, preset_id: str) -> bool:
|
||
"""
|
||
应用预设到当前配置
|
||
|
||
Args:
|
||
preset_id: 预设ID
|
||
|
||
Returns:
|
||
是否应用成功
|
||
"""
|
||
try:
|
||
if not self.enabled:
|
||
print("✗ 预设管理器未启用")
|
||
return False
|
||
|
||
preset_data = self.load_preset(preset_id)
|
||
if preset_data is None:
|
||
return False
|
||
|
||
parameters = preset_data.get('parameters', {})
|
||
|
||
# 应用参数到各个组件
|
||
self._apply_parameters_to_components(parameters)
|
||
|
||
# 更新统计信息
|
||
self.stats['presets_applied'] += 1
|
||
self.current_preset = preset_id
|
||
|
||
print(f"✓ 预设 '{preset_id}' 应用完成")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 预设应用失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
def _apply_parameters_to_components(self, parameters: Dict[str, Any]):
|
||
"""
|
||
应用参数到各个组件
|
||
|
||
Args:
|
||
parameters: 参数字典
|
||
"""
|
||
try:
|
||
# 应用到植被管理器
|
||
if self.plugin.vegetation_manager:
|
||
if 'environment_factors' in parameters:
|
||
self.plugin.vegetation_manager.update_environment_factors(parameters['environment_factors'])
|
||
if 'distribution_config' in parameters:
|
||
self.plugin.vegetation_manager.set_distribution_config(parameters['distribution_config'])
|
||
|
||
# 应用到动物模拟器
|
||
if self.plugin.animal_simulator:
|
||
if 'animal_environment_factors' in parameters:
|
||
self.plugin.animal_simulator.update_environment_factors(parameters['animal_environment_factors'])
|
||
if 'animal_behavior_config' in parameters:
|
||
self.plugin.animal_simulator.set_behavior_config(parameters['animal_behavior_config'])
|
||
|
||
# 应用到生态系统管理器
|
||
if self.plugin.ecosystem_manager:
|
||
if 'ecosystem_parameters' in parameters:
|
||
for param_name, param_value in parameters['ecosystem_parameters'].items():
|
||
self.plugin.ecosystem_manager.set_ecosystem_parameter(param_name, param_value)
|
||
if 'time_config' in parameters:
|
||
self.plugin.ecosystem_manager.set_time_config(parameters['time_config'])
|
||
|
||
# 应用到季节效应系统
|
||
if self.plugin.seasonal_effects:
|
||
if 'season_config' in parameters:
|
||
self.plugin.seasonal_effects.set_time_config(parameters['season_config'])
|
||
if 'current_season' in parameters:
|
||
self.plugin.seasonal_effects.set_current_season(parameters['current_season'])
|
||
|
||
except Exception as e:
|
||
print(f"✗ 参数应用失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
|
||
def delete_preset(self, preset_id: str) -> bool:
|
||
"""
|
||
删除预设
|
||
|
||
Args:
|
||
preset_id: 预设ID
|
||
|
||
Returns:
|
||
是否删除成功
|
||
"""
|
||
try:
|
||
if not self.enabled:
|
||
print("✗ 预设管理器未启用")
|
||
return False
|
||
|
||
if preset_id not in self.presets:
|
||
print(f"✗ 预设不存在: {preset_id}")
|
||
return False
|
||
|
||
# 检查是否为默认预设
|
||
if self.presets[preset_id].get('is_default', False):
|
||
print(f"✗ 无法删除默认预设: {preset_id}")
|
||
return False
|
||
|
||
# 从内存中删除
|
||
del self.presets[preset_id]
|
||
|
||
# 从文件系统中删除
|
||
presets_dir = self.preset_config['presets_directory']
|
||
filepath = os.path.join(presets_dir, f"{preset_id}.json")
|
||
if os.path.exists(filepath):
|
||
os.remove(filepath)
|
||
|
||
# 如果删除的是当前预设,清空当前预设
|
||
if self.current_preset == preset_id:
|
||
self.current_preset = None
|
||
|
||
print(f"✓ 预设 '{preset_id}' 删除完成")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 预设删除失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
def list_presets(self, category: str = None) -> List[str]:
|
||
"""
|
||
列出预设
|
||
|
||
Args:
|
||
category: 预设类别(如果为None,则列出所有预设)
|
||
|
||
Returns:
|
||
预设ID列表
|
||
"""
|
||
try:
|
||
if category is None:
|
||
return list(self.presets.keys())
|
||
else:
|
||
return [preset_id for preset_id, preset_data in self.presets.items()
|
||
if preset_data.get('category') == category]
|
||
|
||
except Exception as e:
|
||
print(f"✗ 预设列表获取失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return []
|
||
|
||
def get_preset_info(self, preset_id: str) -> Optional[Dict[str, Any]]:
|
||
"""
|
||
获取预设信息
|
||
|
||
Args:
|
||
preset_id: 预设ID
|
||
|
||
Returns:
|
||
预设信息字典或None
|
||
"""
|
||
try:
|
||
if preset_id not in self.presets:
|
||
return None
|
||
|
||
preset_data = self.presets[preset_id]
|
||
return {
|
||
'name': preset_data.get('name', preset_id),
|
||
'category': preset_data.get('category', 'unknown'),
|
||
'description': preset_data.get('description', ''),
|
||
'timestamp': preset_data.get('timestamp', 0),
|
||
'is_default': preset_data.get('is_default', False),
|
||
'parameters_count': len(preset_data.get('parameters', {}))
|
||
}
|
||
|
||
except Exception as e:
|
||
print(f"✗ 预设信息获取失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return None
|
||
|
||
def get_preset_categories(self) -> Dict[str, Dict[str, str]]:
|
||
"""
|
||
获取预设类别
|
||
|
||
Returns:
|
||
预设类别字典
|
||
"""
|
||
return self.preset_categories.copy()
|
||
|
||
def create_preset_category(self, category_id: str, name: str, description: str = '') -> bool:
|
||
"""
|
||
创建预设类别
|
||
|
||
Args:
|
||
category_id: 类别ID
|
||
name: 类别名称
|
||
description: 类别描述
|
||
|
||
Returns:
|
||
是否创建成功
|
||
"""
|
||
try:
|
||
self.preset_categories[category_id] = {
|
||
'name': name,
|
||
'description': description
|
||
}
|
||
|
||
print(f"✓ 预设类别 '{name}' 创建完成")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 预设类别创建失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
def export_preset(self, preset_id: str, filepath: str) -> bool:
|
||
"""
|
||
导出预设到文件
|
||
|
||
Args:
|
||
preset_id: 预设ID
|
||
filepath: 导出文件路径
|
||
|
||
Returns:
|
||
是否导出成功
|
||
"""
|
||
try:
|
||
if preset_id not in self.presets:
|
||
print(f"✗ 预设不存在: {preset_id}")
|
||
return False
|
||
|
||
preset_data = self.presets[preset_id]
|
||
|
||
# 保存到指定文件
|
||
with open(filepath, 'w', encoding='utf-8') as f:
|
||
json.dump(preset_data, f, ensure_ascii=False, indent=2)
|
||
|
||
print(f"✓ 预设 '{preset_id}' 导出到 {filepath}")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 预设导出失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
def import_preset(self, filepath: str, preset_id: str = None) -> bool:
|
||
"""
|
||
从文件导入预设
|
||
|
||
Args:
|
||
filepath: 导入文件路径
|
||
preset_id: 预设ID(如果为None,则使用文件名)
|
||
|
||
Returns:
|
||
是否导入成功
|
||
"""
|
||
try:
|
||
# 读取预设文件
|
||
with open(filepath, 'r', encoding='utf-8') as f:
|
||
preset_data = json.load(f)
|
||
|
||
# 确定预设ID
|
||
if preset_id is None:
|
||
preset_id = os.path.splitext(os.path.basename(filepath))[0]
|
||
|
||
# 保存预设
|
||
self.presets[preset_id] = preset_data
|
||
|
||
# 保存到预设目录
|
||
presets_dir = self.preset_config['presets_directory']
|
||
save_filepath = os.path.join(presets_dir, f"{preset_id}.json")
|
||
|
||
with open(save_filepath, 'w', encoding='utf-8') as f:
|
||
json.dump(preset_data, f, ensure_ascii=False, indent=2)
|
||
|
||
print(f"✓ 预设从 {filepath} 导入完成,ID: {preset_id}")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 预设导入失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
def set_preset_config(self, config: Dict[str, Any]):
|
||
"""
|
||
设置预设配置
|
||
|
||
Args:
|
||
config: 配置字典
|
||
"""
|
||
self.preset_config.update(config)
|
||
print(f"✓ 预设配置已更新: {self.preset_config}")
|
||
|
||
def get_stats(self) -> Dict[str, Any]:
|
||
"""
|
||
获取统计信息
|
||
|
||
Returns:
|
||
统计信息字典
|
||
"""
|
||
return self.stats.copy()
|
||
|
||
def reset_stats(self):
|
||
"""重置统计信息"""
|
||
self.stats = {
|
||
'presets_loaded': 0,
|
||
'presets_saved': 0,
|
||
'presets_applied': 0,
|
||
'total_load_time': 0.0,
|
||
'total_save_time': 0.0
|
||
}
|
||
print("✓ 预设管理器统计信息已重置")
|
||
|
||
def get_current_preset(self) -> Optional[str]:
|
||
"""
|
||
获取当前预设
|
||
|
||
Returns:
|
||
当前预设ID或None
|
||
"""
|
||
return self.current_preset
|
||
|
||
def set_current_preset(self, preset_id: str):
|
||
"""
|
||
设置当前预设
|
||
|
||
Args:
|
||
preset_id: 预设ID
|
||
"""
|
||
if preset_id in self.presets:
|
||
self.current_preset = preset_id
|
||
print(f"✓ 当前预设设置为: {preset_id}")
|
||
else:
|
||
print(f"✗ 预设不存在: {preset_id}")
|
||
|
||
def create_terrain_preset_from_current(self, preset_name: str, description: str = '') -> str:
|
||
"""
|
||
从当前配置创建预设
|
||
|
||
Args:
|
||
preset_name: 预设名称
|
||
description: 预设描述
|
||
|
||
Returns:
|
||
预设ID
|
||
"""
|
||
try:
|
||
# 生成预设ID
|
||
preset_id = preset_name.lower().replace(' ', '_')
|
||
|
||
# 创建预设数据
|
||
preset_data = {
|
||
'name': preset_name,
|
||
'category': 'mixed',
|
||
'description': description,
|
||
'parameters': {},
|
||
'timestamp': time.time(),
|
||
'is_default': False
|
||
}
|
||
|
||
# 获取当前配置参数
|
||
if self.plugin.vegetation_manager:
|
||
vm = self.plugin.vegetation_manager
|
||
preset_data['parameters'].update({
|
||
'environment_factors': vm.get_environment_factors(),
|
||
'distribution_config': vm.get_distribution_config()
|
||
})
|
||
|
||
if self.plugin.ecosystem_manager:
|
||
em = self.plugin.ecosystem_manager
|
||
preset_data['parameters'].update({
|
||
'ecosystem_parameters': em.get_ecosystem_parameters()
|
||
})
|
||
|
||
# 保存预设
|
||
self.save_preset(preset_id, preset_data)
|
||
|
||
print(f"✓ 从当前配置创建预设: {preset_name}")
|
||
return preset_id
|
||
|
||
except Exception as e:
|
||
print(f"✗ 从当前配置创建预设失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return ''
|
||
|
||
def batch_apply_presets(self, preset_ids: List[str]) -> bool:
|
||
"""
|
||
批量应用预设
|
||
|
||
Args:
|
||
preset_ids: 预设ID列表
|
||
|
||
Returns:
|
||
是否应用成功
|
||
"""
|
||
try:
|
||
if not self.enabled:
|
||
print("✗ 预设管理器未启用")
|
||
return False
|
||
|
||
success_count = 0
|
||
for preset_id in preset_ids:
|
||
if self.apply_preset(preset_id):
|
||
success_count += 1
|
||
|
||
print(f"✓ 批量应用预设完成: {success_count}/{len(preset_ids)} 个预设应用成功")
|
||
return success_count == len(preset_ids)
|
||
|
||
except Exception as e:
|
||
print(f"✗ 批量应用预设失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
def search_presets(self, keyword: str, category: str = None) -> List[str]:
|
||
"""
|
||
搜索预设
|
||
|
||
Args:
|
||
keyword: 搜索关键词
|
||
category: 预设类别(可选)
|
||
|
||
Returns:
|
||
匹配的预设ID列表
|
||
"""
|
||
try:
|
||
matching_presets = []
|
||
|
||
for preset_id, preset_data in self.presets.items():
|
||
# 检查类别筛选
|
||
if category and preset_data.get('category') != category:
|
||
continue
|
||
|
||
# 检查关键词匹配
|
||
if (keyword.lower() in preset_data.get('name', '').lower() or
|
||
keyword.lower() in preset_data.get('description', '').lower()):
|
||
matching_presets.append(preset_id)
|
||
|
||
return matching_presets
|
||
|
||
except Exception as e:
|
||
print(f"✗ 预设搜索失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return []
|
||
|
||
def duplicate_preset(self, source_preset_id: str, new_preset_id: str, new_name: str = None) -> bool:
|
||
"""
|
||
复制预设
|
||
|
||
Args:
|
||
source_preset_id: 源预设ID
|
||
new_preset_id: 新预设ID
|
||
new_name: 新预设名称(如果为None,则使用源预设名称)
|
||
|
||
Returns:
|
||
是否复制成功
|
||
"""
|
||
try:
|
||
if source_preset_id not in self.presets:
|
||
print(f"✗ 源预设不存在: {source_preset_id}")
|
||
return False
|
||
|
||
# 复制预设数据
|
||
preset_data = self.presets[source_preset_id].copy()
|
||
|
||
# 更新名称
|
||
if new_name:
|
||
preset_data['name'] = new_name
|
||
else:
|
||
preset_data['name'] = f"{preset_data['name']} (副本)"
|
||
|
||
# 更新时间戳
|
||
preset_data['timestamp'] = time.time()
|
||
|
||
# 标记为非默认预设
|
||
preset_data['is_default'] = False
|
||
|
||
# 保存新预设
|
||
return self.save_preset(new_preset_id, preset_data)
|
||
|
||
except Exception as e:
|
||
print(f"✗ 预设复制失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
def update_preset_parameters(self, preset_id: str, parameters: Dict[str, Any]) -> bool:
|
||
"""
|
||
更新预设参数
|
||
|
||
Args:
|
||
preset_id: 预设ID
|
||
parameters: 要更新的参数
|
||
|
||
Returns:
|
||
是否更新成功
|
||
"""
|
||
try:
|
||
if preset_id not in self.presets:
|
||
print(f"✗ 预设不存在: {preset_id}")
|
||
return False
|
||
|
||
# 更新参数
|
||
self.presets[preset_id]['parameters'].update(parameters)
|
||
|
||
# 更新时间戳
|
||
self.presets[preset_id]['timestamp'] = time.time()
|
||
|
||
# 保存到文件
|
||
presets_dir = self.preset_config['presets_directory']
|
||
filepath = os.path.join(presets_dir, f"{preset_id}.json")
|
||
|
||
with open(filepath, 'w', encoding='utf-8') as f:
|
||
json.dump(self.presets[preset_id], f, ensure_ascii=False, indent=2)
|
||
|
||
print(f"✓ 预设 '{preset_id}' 参数更新完成")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 预设参数更新失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
def get_preset_parameters(self, preset_id: str) -> Optional[Dict[str, Any]]:
|
||
"""
|
||
获取预设参数
|
||
|
||
Args:
|
||
preset_id: 预设ID
|
||
|
||
Returns:
|
||
参数字典或None
|
||
"""
|
||
try:
|
||
if preset_id not in self.presets:
|
||
return None
|
||
|
||
return self.presets[preset_id].get('parameters', {}).copy()
|
||
|
||
except Exception as e:
|
||
print(f"✗ 预设参数获取失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return None
|
||
|
||
def validate_preset(self, preset_id: str) -> bool:
|
||
"""
|
||
验证预设完整性
|
||
|
||
Args:
|
||
preset_id: 预设ID
|
||
|
||
Returns:
|
||
预设是否有效
|
||
"""
|
||
try:
|
||
if preset_id not in self.presets:
|
||
return False
|
||
|
||
preset_data = self.presets[preset_id]
|
||
|
||
# 检查必需字段
|
||
required_fields = ['name', 'category', 'parameters']
|
||
for field in required_fields:
|
||
if field not in preset_data:
|
||
print(f"✗ 预设 '{preset_id}' 缺少必需字段: {field}")
|
||
return False
|
||
|
||
# 检查类别有效性
|
||
if preset_data['category'] not in self.preset_categories:
|
||
print(f"✗ 预设 '{preset_id}' 包含无效类别: {preset_data['category']}")
|
||
return False
|
||
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 预设验证失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
def backup_presets(self, backup_dir: str = 'presets_backup') -> bool:
|
||
"""
|
||
备份所有预设
|
||
|
||
Args:
|
||
backup_dir: 备份目录
|
||
|
||
Returns:
|
||
是否备份成功
|
||
"""
|
||
try:
|
||
if not os.path.exists(backup_dir):
|
||
os.makedirs(backup_dir)
|
||
|
||
backup_count = 0
|
||
for preset_id, preset_data in self.presets.items():
|
||
try:
|
||
filepath = os.path.join(backup_dir, f"{preset_id}.json")
|
||
with open(filepath, 'w', encoding='utf-8') as f:
|
||
json.dump(preset_data, f, ensure_ascii=False, indent=2)
|
||
backup_count += 1
|
||
except Exception as e:
|
||
print(f"✗ 预设 '{preset_id}' 备份失败: {e}")
|
||
|
||
print(f"✓ 预设备份完成: {backup_count}/{len(self.presets)} 个预设已备份到 {backup_dir}")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 预设备份失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
def restore_presets(self, backup_dir: str = 'presets_backup') -> bool:
|
||
"""
|
||
从备份恢复预设
|
||
|
||
Args:
|
||
backup_dir: 备份目录
|
||
|
||
Returns:
|
||
是否恢复成功
|
||
"""
|
||
try:
|
||
if not os.path.exists(backup_dir):
|
||
print(f"✗ 备份目录不存在: {backup_dir}")
|
||
return False
|
||
|
||
restore_count = 0
|
||
for filename in os.listdir(backup_dir):
|
||
if filename.endswith('.json'):
|
||
try:
|
||
filepath = os.path.join(backup_dir, filename)
|
||
with open(filepath, 'r', encoding='utf-8') as f:
|
||
preset_data = json.load(f)
|
||
|
||
preset_id = os.path.splitext(filename)[0]
|
||
self.presets[preset_id] = preset_data
|
||
restore_count += 1
|
||
except Exception as e:
|
||
print(f"✗ 预设文件 '{filename}' 恢复失败: {e}")
|
||
|
||
print(f"✓ 预设恢复完成: {restore_count} 个预设已从 {backup_dir} 恢复")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 预设恢复失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False |