refactor: 引入 EventBus 事件总线,实现各步骤面板间的去中心化自动参数传导,完成最终解耦
This commit is contained in:
@ -10,6 +10,8 @@
|
||||
import copy
|
||||
from pathlib import Path
|
||||
|
||||
from src.gui.core.event_bus import global_event_bus
|
||||
|
||||
|
||||
class WorkspaceManager:
|
||||
"""管理步骤默认输出路径、文件扫描与配置裁剪"""
|
||||
@ -23,19 +25,40 @@ class WorkspaceManager:
|
||||
|
||||
def __init__(self):
|
||||
self.step_default_outputs = {
|
||||
'step1': "1_water_mask/water_mask_from_ndwi.dat",
|
||||
'step2': "2_Glint_Detection/severe_glint_area.dat",
|
||||
'step3': "3_deglint/deglint_goodman.bsq",
|
||||
'step4_sampling': "4_sampling/sampling_spectra.csv",
|
||||
'step5_clean': "5_Data_Cleaning/processed_data.csv",
|
||||
'step6_feature': "6_Spectral_Feature_Extraction/training_spectra.csv",
|
||||
'step7_index': "7_Water_Quality_Indices/training_spectra_indices.csv",
|
||||
'step8_ml_train': "8_Supervised_Model_Training/",
|
||||
'step9_ml_predict': "9_ML_Prediction/",
|
||||
'step10_watercolor': "10_WaterIndex_Images/",
|
||||
'step11_map': "14_visualization/"
|
||||
'step1': {'water_mask': "1_water_mask/water_mask_from_ndwi.dat"},
|
||||
'step2': {'glint_mask': "2_Glint_Detection/severe_glint_area.dat"},
|
||||
'step3': {'deglint_image': "3_deglint/deglint_goodman.bsq"},
|
||||
'step4_sampling': {'sampling_points': "4_sampling/sampling_spectra.csv"},
|
||||
'step5_clean': {'processed_data': "5_Data_Cleaning/processed_data.csv"},
|
||||
'step6_feature': {'training_spectra': "6_Spectral_Feature_Extraction/training_spectra.csv"},
|
||||
'step7_index': {'training_spectra_indices': "7_Water_Quality_Indices/training_spectra_indices.csv"},
|
||||
'step8_ml_train': {'Supervised_Model_Training': "8_Supervised_Model_Training/"},
|
||||
'step9_ml_predict': {'9_ML_Prediction': "9_ML_Prediction/"},
|
||||
'step10_watercolor': {'WaterIndex_Images': "10_WaterIndex_Images/"},
|
||||
'step11_map': {'14_visualization': "14_visualization/"},
|
||||
}
|
||||
self.step_outputs = {}
|
||||
# pipeline step_id → panel step_id 映射(由 WaterQualityGUI 注入)
|
||||
self._pipeline_to_panel = {}
|
||||
|
||||
def set_step_id_mapping(self, mapping: dict):
|
||||
"""注入 pipeline step_id → panel step_id 映射,用于事件发布时统一 ID。"""
|
||||
self._pipeline_to_panel = mapping
|
||||
|
||||
def _publish_outputs(self, step_id: str, outputs: dict):
|
||||
"""将发现的产出发布到 EventBus。
|
||||
|
||||
Args:
|
||||
step_id: 面板 step_id(如 'step1', 'step5_clean')
|
||||
outputs: {output_type: path_str}
|
||||
"""
|
||||
for output_type, path in outputs.items():
|
||||
if path:
|
||||
global_event_bus.publish('OutputUpdated', {
|
||||
'step_id': step_id,
|
||||
'output_type': output_type,
|
||||
'path': path,
|
||||
})
|
||||
|
||||
@staticmethod
|
||||
def _is_scientific_mask(path_str):
|
||||
@ -177,15 +200,25 @@ class WorkspaceManager:
|
||||
if step_id not in self.step_outputs:
|
||||
self.step_outputs[step_id] = {}
|
||||
self.step_outputs[step_id].update(outputs)
|
||||
# ★ 发布 EventBus 事件,驱动下游面板自动填充
|
||||
self._publish_outputs(step_id, outputs)
|
||||
|
||||
return discovered_outputs
|
||||
|
||||
def update_step_outputs(self, step_name, work_path):
|
||||
"""更新指定步骤的输出路径记录"""
|
||||
if step_name not in self.step_default_outputs:
|
||||
"""更新指定步骤的输出路径记录并发布 EventBus 事件。
|
||||
|
||||
step_name 可能是 pipeline step_id(如 'step4'),
|
||||
会先通过 _pipeline_to_panel 映射为面板 step_id(如 'step5_clean')。
|
||||
"""
|
||||
# 映射 pipeline step_id → panel step_id
|
||||
panel_step_id = self._pipeline_to_panel.get(step_name, step_name)
|
||||
|
||||
if panel_step_id not in self.step_default_outputs:
|
||||
return
|
||||
|
||||
step_outputs = self.step_default_outputs[step_name]
|
||||
step_outputs = self.step_default_outputs[panel_step_id]
|
||||
published = {}
|
||||
|
||||
for output_type, relative_path in step_outputs.items():
|
||||
if '*' in relative_path:
|
||||
@ -193,11 +226,18 @@ class WorkspaceManager:
|
||||
matching_files = list(pattern_path.parent.glob(pattern_path.name))
|
||||
if matching_files:
|
||||
latest_file = max(matching_files, key=lambda p: p.stat().st_mtime)
|
||||
self.step_outputs[step_name][output_type] = str(latest_file)
|
||||
path_str = str(latest_file)
|
||||
self.step_outputs.setdefault(panel_step_id, {})[output_type] = path_str
|
||||
published[output_type] = path_str
|
||||
else:
|
||||
output_path = work_path / relative_path
|
||||
if output_path.exists():
|
||||
self.step_outputs[step_name][output_type] = str(output_path)
|
||||
path_str = str(output_path)
|
||||
self.step_outputs.setdefault(panel_step_id, {})[output_type] = path_str
|
||||
published[output_type] = path_str
|
||||
|
||||
if published:
|
||||
self._publish_outputs(panel_step_id, published)
|
||||
|
||||
@staticmethod
|
||||
def prune_config_for_prediction_mode(config: dict) -> dict:
|
||||
|
||||
Reference in New Issue
Block a user