1.修复重启后,由于PJ不是列队中,导致无法创建调度任务的问题。
2.修复CPjPage2点Port2的物料类型,Port1也跟着变的问题。
已修改3个文件
73 ■■■■■ 文件已修改
SourceCode/Bond/Servo/CCjPage2.cpp 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CCjPage2.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMaster.cpp 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CCjPage2.cpp
@@ -440,43 +440,29 @@
        m_grid.SetPortAllocated(p, !checked, _T(""));
        GetDlgItem(btnID[p])->EnableWindow(checked);
    }
    // Keep one material type across all selected ports.
    int syncMat = CCarrierSlotGrid::MAT_G1;
    bool hasSyncMat = false;
    for (int p = 0; p < kPortCount && !hasSyncMat; ++p) {
    // 物料类型按 Port 维度独立统一,不跨 Port 联动。
    for (int p = 0; p < kPortCount; ++p) {
        if (!pCurrent->selectedPorts[p]) continue;
        int syncMat = m_grid.GetSlotMaterialType(p, 0);
        for (int s = 0; s < kSlotCount; ++s) {
            if (m_grid.GetSlotChecked(p, s)) {
                syncMat = m_grid.GetSlotMaterialType(p, s);
                hasSyncMat = true;
                break;
            }
        }
        SyncMaterialInPort(p, syncMat);
    }
    if (!hasSyncMat) {
        for (int p = 0; p < kPortCount; ++p) {
            if (!pCurrent->selectedPorts[p]) continue;
            syncMat = m_grid.GetSlotMaterialType(p, 0);
            hasSyncMat = true;
            break;
        }
    }
    SyncMaterialAcrossSelectedPorts(syncMat);
    EnsureWarpDefaults(*pCurrent);
}
void CCjPage2::SyncMaterialAcrossSelectedPorts(int material)
void CCjPage2::SyncMaterialInPort(int port, int material)
{
    if (m_pContext == nullptr) return;
    if (port < 0 || port >= kPortCount) return;
    const int mat = NormalizeMaterial(material);
    PJWarp* pCurrent = (PJWarp*)m_pContext;
    for (int p = 0; p < kPortCount; ++p) {
        if (!pCurrent->selectedPorts[p]) continue;
        for (int s = 0; s < kSlotCount; ++s) {
            m_grid.SetSlotMaterialType(p, s, mat, FALSE);
        }
    for (int s = 0; s < kSlotCount; ++s) {
        m_grid.SetSlotMaterialType(port, s, mat, FALSE);
    }
}
@@ -531,9 +517,10 @@
void CCjPage2::OnGridMatChanged(NMHDR* pNMHDR, LRESULT* pResult)
{
    auto* nm = reinterpret_cast<CSG_MAT_CHANGE*>(pNMHDR);
    const int port = nm->port;
    const int mat = nm->material; // 1/2
    SyncMaterialAcrossSelectedPorts(mat);
    SyncMaterialInPort(port, mat);
    ContentChanged(0);
    *pResult = 0;
SourceCode/Bond/Servo/CCjPage2.h
@@ -26,7 +26,7 @@
private:
    void UpdatePjData();
    void RefreshPortLocksAndButtons();
    void SyncMaterialAcrossSelectedPorts(int material);
    void SyncMaterialInPort(int port, int material);
private:
    CCarrierSlotGrid m_grid;
SourceCode/Bond/Servo/CMaster.cpp
@@ -3769,6 +3769,33 @@
        }
        m_pControlJob->setPJs(tempPjs);
        // 重建运行态缓存,避免重启后仅依赖 Queued 选择导致找不到当前 PJ。
        m_inProcesJobs.clear();
        m_completeProcessJobs.clear();
        m_queueGlasses.clear();
        m_inProcesGlasses.clear();
        m_completeGlasses.clear();
        for (auto pj : tempPjs) {
            if (pj == nullptr) continue;
            switch (pj->state()) {
            case PJState::InProcess:
            case PJState::Paused:
                m_inProcesJobs.push_back(pj);
                break;
            case PJState::Completed:
            case PJState::Aborted:
            case PJState::Failed:
                m_completeProcessJobs.push_back(pj);
                break;
            default:
                break;
            }
        }
        LOGI("<Master>loadState: ProcessJob rebuild done. total=%d, inProcess=%d, complete=%d",
            (int)tempPjs.size(),
            (int)m_inProcesJobs.size(),
            (int)m_completeProcessJobs.size());
        // 更新contexts
        auto pjs = m_pControlJob->getPjs();
@@ -3801,14 +3828,25 @@
    CProcessJob* CMaster::acquireNextProcessJob()
    {
        if (m_pControlJob == nullptr) return nullptr;
        auto& pjs = m_pControlJob->getPjs();
        for (const auto pj : pjs) {
            if (pj->state() == PJState::Queued) {
                LOGI("<Master>acquireNextProcessJob: start queued PJ(%s)", pj->id().c_str());
                pj->start();
                return pj;
            }
        }
        // 若没有 Queued,继续复用已经在制/暂停的 PJ(例如 loadState 恢复后的场景)。
        for (const auto pj : pjs) {
            if (pj->state() == PJState::InProcess || pj->state() == PJState::Paused) {
                LOGI("<Master>acquireNextProcessJob: reuse PJ(%s), state=%d",
                    pj->id().c_str(), (int)pj->state());
                return pj;
            }
        }
        return nullptr;
    }