|
|
|
|
@ -64,14 +64,16 @@ nmSubWndGrid::nmSubWndGrid(QWidget *parent,
|
|
|
|
|
m_vtkWidget(nullptr),
|
|
|
|
|
m_pGridLoadingLabel(nullptr),
|
|
|
|
|
m_pDebounceTimer(nullptr),
|
|
|
|
|
m_pDataManager(pDataManager),
|
|
|
|
|
m_pDataManager(nullptr),
|
|
|
|
|
m_pGridTask(nullptr),
|
|
|
|
|
m_pGridTaskDataManager(nullptr),
|
|
|
|
|
m_bGridUpdatePending(false),
|
|
|
|
|
m_dPebiGridControl(pebiGridControl),
|
|
|
|
|
m_bGeneratePebiGrid(bGeneratePebiGrid)
|
|
|
|
|
{
|
|
|
|
|
m_sMdiWndType = s_MdiType_DataAnal;
|
|
|
|
|
setWindowTitle(tr("nmSubWndGrid"));
|
|
|
|
|
setDataManager(pDataManager);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -84,6 +86,65 @@ nmSubWndGrid::~nmSubWndGrid()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::setDataManager(nmDataAnalyzeManager* pDataManager)
|
|
|
|
|
{
|
|
|
|
|
nmDataAnalyzeManager* pOldDataManager = m_pDataManager.data();
|
|
|
|
|
if(pOldDataManager == pDataManager) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 第一步:只解除旧分析与本窗口的连接,避免切换多次后旧分析继续触发重建。
|
|
|
|
|
if(pOldDataManager != nullptr) {
|
|
|
|
|
disconnect(pOldDataManager, SIGNAL(dataChanged()),
|
|
|
|
|
this, SLOT(onDataManagerChanged()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_pDataManager = pDataManager;
|
|
|
|
|
if(pDataManager != nullptr) {
|
|
|
|
|
connect(pDataManager, SIGNAL(dataChanged()),
|
|
|
|
|
this, SLOT(onDataManagerChanged()),
|
|
|
|
|
static_cast<Qt::ConnectionType>(
|
|
|
|
|
Qt::QueuedConnection | Qt::UniqueConnection));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 构造阶段保留对话框传入的控制参数;窗口创建完成后的分析切换使用新分析自己的值。
|
|
|
|
|
if(m_mainLayout != nullptr && pDataManager != nullptr) {
|
|
|
|
|
m_dPebiGridControl = pDataManager->getPebiGridControl();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(m_pDebounceTimer != nullptr) {
|
|
|
|
|
m_pDebounceTimer->stop();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 第二步:旧 VTK 页不能作为新分析的失败回退页,否则会继续显示上一分析的网格。
|
|
|
|
|
clearGridResultView();
|
|
|
|
|
if(m_mainLayout == nullptr) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(pDataManager == nullptr) {
|
|
|
|
|
m_bGridUpdatePending = false;
|
|
|
|
|
showGridFailure();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(pDataManager->isPebiGridValid()) {
|
|
|
|
|
m_bGridUpdatePending = false;
|
|
|
|
|
showGridResult();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
showGridLoading();
|
|
|
|
|
if(!m_pGridTask.isNull()) {
|
|
|
|
|
// 外部 DLL 不能安全中止;旧任务自然结束后只补做当前分析的最后一次更新。
|
|
|
|
|
m_bGridUpdatePending = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_bGridUpdatePending = false;
|
|
|
|
|
updateGrid();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::configWnd(QString sPrevInfo)
|
|
|
|
|
{
|
|
|
|
|
iSubWndBaseFit::configWnd(sPrevInfo);
|
|
|
|
|
@ -204,6 +265,15 @@ bool nmSubWndGrid::generatePebiGrid()
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::onDataManagerChanged()
|
|
|
|
|
{
|
|
|
|
|
// 旧分析在断开前可能已经把信号排入主线程队列,发送者不匹配时不得刷新当前分析。
|
|
|
|
|
if(sender() != m_pDataManager.data()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
updateGrid();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::updateGrid()
|
|
|
|
|
{
|
|
|
|
|
// 角色、产量等只影响求解的变化也会发送 dataChanged;网格仍有效时无需重划。
|
|
|
|
|
@ -226,8 +296,8 @@ void nmSubWndGrid::updateGrid()
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::onDebounceTimeout()
|
|
|
|
|
{
|
|
|
|
|
// 第一步:同一窗口只允许一个网格线程运行,连续编辑合并为下一次重建。
|
|
|
|
|
if(!m_pGridTask.isNull() && m_pGridTask->isRunning()) {
|
|
|
|
|
// 第一步:任务结束信号回到主线程前仍视为占用,避免覆盖尚未处理的任务指针。
|
|
|
|
|
if(!m_pGridTask.isNull()) {
|
|
|
|
|
m_bGridUpdatePending = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@ -240,6 +310,7 @@ void nmSubWndGrid::onDebounceTimeout()
|
|
|
|
|
// 第二步:把窗口参数写回所属分析方案,再启动绑定同一管理器的后台任务。
|
|
|
|
|
nmCalculationPebiGrid::getInstance()->setGridControl(
|
|
|
|
|
m_dPebiGridControl, pDataManager);
|
|
|
|
|
m_pGridTaskDataManager = pDataManager;
|
|
|
|
|
m_pGridTask = new nmCalculationPebiGridTask(pDataManager, this);
|
|
|
|
|
connect(m_pGridTask, SIGNAL(pebiGridGenerated(bool)),
|
|
|
|
|
this, SLOT(onPebiGridGenerated(bool)), Qt::QueuedConnection);
|
|
|
|
|
@ -256,9 +327,18 @@ void nmSubWndGrid::onPebiGridGenerated(bool success)
|
|
|
|
|
// 局部结果;如果用户在划分期间修改了输入,commitResult() 会按版本拒绝。
|
|
|
|
|
nmCalculationPebiGridTask* pCompletedTask =
|
|
|
|
|
qobject_cast<nmCalculationPebiGridTask*>(sender());
|
|
|
|
|
nmDataAnalyzeManager* pDataManager = m_pDataManager.data();
|
|
|
|
|
if(success && pCompletedTask != nullptr && pDataManager != nullptr) {
|
|
|
|
|
success = pCompletedTask->commitResult(pDataManager);
|
|
|
|
|
nmDataAnalyzeManager* pTaskDataManager =
|
|
|
|
|
m_pGridTaskDataManager.data();
|
|
|
|
|
|
|
|
|
|
// 只处理窗口当前持有且仍属于当前分析的任务;切换前启动的旧任务直接丢弃。
|
|
|
|
|
if(pCompletedTask != m_pGridTask.data() ||
|
|
|
|
|
pTaskDataManager == nullptr ||
|
|
|
|
|
pTaskDataManager != m_pDataManager.data()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(success) {
|
|
|
|
|
success = pCompletedTask->commitResult(pTaskDataManager);
|
|
|
|
|
} else {
|
|
|
|
|
success = false;
|
|
|
|
|
}
|
|
|
|
|
@ -275,13 +355,22 @@ void nmSubWndGrid::onPebiGridGenerated(bool success)
|
|
|
|
|
void nmSubWndGrid::onPebiGridTaskFinished()
|
|
|
|
|
{
|
|
|
|
|
// 第一步:只清理由当前窗口持有的任务,避免旧 finished 信号覆盖新任务指针。
|
|
|
|
|
if(sender() == m_pGridTask.data()) {
|
|
|
|
|
m_pGridTask = nullptr;
|
|
|
|
|
if(sender() != m_pGridTask.data()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
m_pGridTask = nullptr;
|
|
|
|
|
m_pGridTaskDataManager = nullptr;
|
|
|
|
|
|
|
|
|
|
// 第二步:运行期间若又有数据变化,重新启动防抖计时,只补做最后一次网格。
|
|
|
|
|
if(m_bGridUpdatePending) {
|
|
|
|
|
m_bGridUpdatePending = false;
|
|
|
|
|
nmDataAnalyzeManager* pDataManager = m_pDataManager.data();
|
|
|
|
|
if(pDataManager != nullptr &&
|
|
|
|
|
pDataManager->isPebiGridValid() &&
|
|
|
|
|
m_vtkWidget == nullptr) {
|
|
|
|
|
showGridResult();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
updateGrid();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -304,11 +393,7 @@ void nmSubWndGrid::showGridResult()
|
|
|
|
|
|
|
|
|
|
// 网格已经在主线程完整提交,此处一次创建新的 VTK 页,不会向用户暴露
|
|
|
|
|
// 没有 RenderWindow 的中间状态。
|
|
|
|
|
if(m_vtkWidget != nullptr) {
|
|
|
|
|
m_mainLayout->removeWidget(m_vtkWidget);
|
|
|
|
|
delete m_vtkWidget;
|
|
|
|
|
m_vtkWidget = nullptr;
|
|
|
|
|
}
|
|
|
|
|
clearGridResultView();
|
|
|
|
|
|
|
|
|
|
m_vtkWidget = new nmWxGridVTKContainerWidget(
|
|
|
|
|
m_pDataManager.data(), centralWidget());
|
|
|
|
|
@ -318,6 +403,19 @@ void nmSubWndGrid::showGridResult()
|
|
|
|
|
m_mainLayout->setCurrentWidget(m_vtkWidget);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::clearGridResultView()
|
|
|
|
|
{
|
|
|
|
|
if(m_vtkWidget == nullptr) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(m_mainLayout != nullptr) {
|
|
|
|
|
m_mainLayout->removeWidget(m_vtkWidget);
|
|
|
|
|
}
|
|
|
|
|
delete m_vtkWidget;
|
|
|
|
|
m_vtkWidget = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::showGridFailure()
|
|
|
|
|
{
|
|
|
|
|
if(m_mainLayout == nullptr) {
|
|
|
|
|
|