From 549e14363badd7e33f497897ea5a2454e1a1f7a1 Mon Sep 17 00:00:00 2001
From: LAPTOP-SNT8I5JK\Boounion <Chenluhua@qq.com>
Date: 星期六, 20 九月 2025 16:16:16 +0800
Subject: [PATCH] 1.续费完善批工艺;
---
SourceCode/Bond/Servo/CCjPage2.cpp | 75 ++++++++
SourceCode/Bond/Servo/CControlJobDlg.cpp | 2
SourceCode/Bond/Servo/resource.h | 0
SourceCode/Bond/Servo/Servo.vcxproj.user | 2
SourceCode/Bond/Servo/CCjPage2.h | 4
SourceCode/Bond/Servo/Servo.rc | 0
SourceCode/Bond/Servo/CMaster.cpp | 41 ++++
SourceCode/Bond/Servo/CMaster.h | 3
SourceCode/Bond/Servo/CPageGlassList.cpp | 357 ++++++++++++++++++++++++++++++---------
9 files changed, 395 insertions(+), 89 deletions(-)
diff --git a/SourceCode/Bond/Servo/CCjPage2.cpp b/SourceCode/Bond/Servo/CCjPage2.cpp
index c156c44..2f4d559 100644
--- a/SourceCode/Bond/Servo/CCjPage2.cpp
+++ b/SourceCode/Bond/Servo/CCjPage2.cpp
@@ -8,6 +8,11 @@
#include "RecipeManager.h"
+UINT btnID[] = { IDC_BUTTON_PORT1_PROCESS_START,
+ IDC_BUTTON_PORT2_PROCESS_START,
+ IDC_BUTTON_PORT3_PROCESS_START,
+ IDC_BUTTON_PORT4_PROCESS_START };
+
// CPjPage1 瀵硅瘽妗�
IMPLEMENT_DYNAMIC(CCjPage2, CCjPageBase)
@@ -38,6 +43,10 @@
ON_BN_CLICKED(IDC_RADIO4, &CCjPage2::OnBnClickedRadio4)
ON_NOTIFY(CSGN_SEL_CHANGED, IDC_GRID1, &CCjPage2::OnGridSelChanged)
ON_NOTIFY(CSGN_MAT_CHANGED, IDC_GRID1, &CCjPage2::OnGridMatChanged)
+ ON_BN_CLICKED(IDC_BUTTON_PORT1_PROCESS_START, &CCjPage2::OnBnClickedButtonPort1ProcessStart)
+ ON_BN_CLICKED(IDC_BUTTON_PORT2_PROCESS_START, &CCjPage2::OnBnClickedButtonPort2ProcessStart)
+ ON_BN_CLICKED(IDC_BUTTON_PORT3_PROCESS_START, &CCjPage2::OnBnClickedButtonPort3ProcessStart)
+ ON_BN_CLICKED(IDC_BUTTON_PORT4_PROCESS_START, &CCjPage2::OnBnClickedButtonPort4ProcessStart)
END_MESSAGE_MAP()
@@ -103,12 +112,41 @@
pItem->GetWindowRect(&rcItem);
ScreenToClient(rcItem);
+
+ int x = rcItem.left + 100 + 18;
+ int y = 100;
+
+
// 璁╂帶浠剁獥鍙e昂瀵歌嚜鍔ㄥ尮閰嶅綋鍓嶅垪瀹�/琛屾暟锛堜笉鍑虹幇婊氬姩鏉★級
if (::IsWindow(m_grid.m_hWnd)) {
CSize best = m_grid.CalcBestWindowSize(TRUE, -1, 2, 2);
pItem->MoveWindow(rcItem.left, rcItem.top, best.cx, best.cy);
pItem->Invalidate();
+ pItem->GetWindowRect(&rcItem);
+ ScreenToClient(rcItem);
+ y = rcItem.bottom;
+ y += 18;
}
+
+ pItem = GetDlgItem(IDC_BUTTON_PORT1_PROCESS_START);
+ pItem->GetWindowRect(&rcItem);
+ pItem->MoveWindow(x, y, rcItem.Width(), rcItem.Height());
+ x += 220;
+
+ pItem = GetDlgItem(IDC_BUTTON_PORT2_PROCESS_START);
+ pItem->GetWindowRect(&rcItem);
+ pItem->MoveWindow(x, y, rcItem.Width(), rcItem.Height());
+ x += 220;
+
+ pItem = GetDlgItem(IDC_BUTTON_PORT3_PROCESS_START);
+ pItem->GetWindowRect(&rcItem);
+ pItem->MoveWindow(x, y, rcItem.Width(), rcItem.Height());
+ x += 220;
+
+ pItem = GetDlgItem(IDC_BUTTON_PORT4_PROCESS_START);
+ pItem->GetWindowRect(&rcItem);
+ pItem->MoveWindow(x, y, rcItem.Width(), rcItem.Height());
+ x += 220;
}
int CCjPage2::OnApply()
@@ -225,6 +263,7 @@
pButton->EnableWindow(enable[i]);
m_grid.SetPortAllocated(i, !checked[i], _T(""));
+ GetDlgItem(btnID[i])->EnableWindow(checked[i]);
}
@@ -262,7 +301,6 @@
if (portIndex != -1) {
for (int i = 0; i < 8; i++) {
m_grid.SetSlotChecked(portIndex, i, ((PJWarp*)m_pContext)->checkSlot[i]);
- // m_grid.SetSlotMaterialType(portIndex, i, ((PJWarp*)m_pContext)->material[i]);
}
}
@@ -294,6 +332,7 @@
for (int i = 0; i < 4; i++) {
m_grid.SetPortAllocated(i, lock[i], _T(""));
+ GetDlgItem(btnID[i])->EnableWindow(!lock[i]);
}
ContentChanged(0);
@@ -314,6 +353,7 @@
for (int i = 0; i < 4; i++) {
m_grid.SetPortAllocated(i, lock[i], _T(""));
+ GetDlgItem(btnID[i])->EnableWindow(!lock[i]);
}
ContentChanged(0);
@@ -334,6 +374,7 @@
for (int i = 0; i < 4; i++) {
m_grid.SetPortAllocated(i, lock[i], _T(""));
+ GetDlgItem(btnID[i])->EnableWindow(!lock[i]);
}
ContentChanged(0);
@@ -354,6 +395,7 @@
for (int i = 0; i < 4; i++) {
m_grid.SetPortAllocated(i, lock[i], _T(""));
+ GetDlgItem(btnID[i])->EnableWindow(!lock[i]);
}
ContentChanged(0);
@@ -405,3 +447,34 @@
*pResult = 0;
}
+
+void CCjPage2::OnBnClickedButtonPort1ProcessStart()
+{
+ auto& master = theApp.m_model.getMaster();
+ auto port = (SERVO::CLoadPort*)master.getEquipment(EQ_ID_LOADPORT1);
+ port->sendCassetteCtrlCmd(CCC_PROCESS_START, nullptr, 0, 0, 0, nullptr, nullptr);
+
+}
+
+void CCjPage2::OnBnClickedButtonPort2ProcessStart()
+{
+ auto& master = theApp.m_model.getMaster();
+ auto port = (SERVO::CLoadPort*)master.getEquipment(EQ_ID_LOADPORT2);
+ port->sendCassetteCtrlCmd(CCC_PROCESS_START, nullptr, 0, 0, 0, nullptr, nullptr);
+}
+
+void CCjPage2::OnBnClickedButtonPort3ProcessStart()
+{
+ auto& master = theApp.m_model.getMaster();
+ auto port = (SERVO::CLoadPort*)master.getEquipment(EQ_ID_LOADPORT3);
+ port->sendCassetteCtrlCmd(CCC_PROCESS_START, nullptr, 0, 0, 0, nullptr, nullptr);
+}
+
+void CCjPage2::OnBnClickedButtonPort4ProcessStart()
+{
+ auto& master = theApp.m_model.getMaster();
+ auto port = (SERVO::CLoadPort*)master.getEquipment(EQ_ID_LOADPORT4);
+ port->sendCassetteCtrlCmd(CCC_PROCESS_START, nullptr, 0, 0, 0, nullptr, nullptr);
+}
+
+
diff --git a/SourceCode/Bond/Servo/CCjPage2.h b/SourceCode/Bond/Servo/CCjPage2.h
index 284aeb4..b72fa15 100644
--- a/SourceCode/Bond/Servo/CCjPage2.h
+++ b/SourceCode/Bond/Servo/CCjPage2.h
@@ -59,4 +59,8 @@
afx_msg void OnBnClickedRadio4();
afx_msg void OnGridSelChanged(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnGridMatChanged(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnBnClickedButtonPort1ProcessStart();
+ afx_msg void OnBnClickedButtonPort2ProcessStart();
+ afx_msg void OnBnClickedButtonPort3ProcessStart();
+ afx_msg void OnBnClickedButtonPort4ProcessStart();
};
diff --git a/SourceCode/Bond/Servo/CControlJobDlg.cpp b/SourceCode/Bond/Servo/CControlJobDlg.cpp
index 4cf6bc6..2a57dcd 100644
--- a/SourceCode/Bond/Servo/CControlJobDlg.cpp
+++ b/SourceCode/Bond/Servo/CControlJobDlg.cpp
@@ -380,7 +380,7 @@
void CControlJobDlg::OnBnClickedButtonCompletionBath()
{
- if (theApp.m_model.getMaster().completeControlJob("娴嬭瘯鎵嬪姩缁撴壒")) {
+ if (theApp.m_model.getMaster().forceCompleteControlJob("娴嬭瘯鎵嬪姩缁撴壒")) {
AfxMessageBox("缁撴壒瀹屾垚");
}
diff --git a/SourceCode/Bond/Servo/CMaster.cpp b/SourceCode/Bond/Servo/CMaster.cpp
index 7b2da65..d6831e5 100644
--- a/SourceCode/Bond/Servo/CMaster.cpp
+++ b/SourceCode/Bond/Servo/CMaster.cpp
@@ -1481,7 +1481,7 @@
m_listener.onCjEnd(this, pJob);
}
- completeControlJob("工艺正常完成");
+ completeControlJob();
}
}
}
@@ -1535,6 +1535,7 @@
for (auto pj : pjs) {
auto carrier = pj->getCarrier(pPort->getCassetteId());
if (carrier != nullptr) {
+ carrier->contexts.clear();
for (auto slot : carrier->slots) {
CGlass* pGlass = pPort->getGlassFromSlot(slot);
carrier->contexts.push_back((void*)pGlass);
@@ -2781,7 +2782,43 @@
}
- bool CMaster::completeControlJob(std::string description)
+ bool CMaster::completeControlJob()
+ {
+ if (m_pControlJob == nullptr) {
+ return false;
+ }
+ for (auto item : m_processJobs) {
+ if (item->state() != PJState::Completed) return false;
+ }
+ if (m_pControlJob->state() != CJState::Completed)
+ return false;
+
+
+
+ // 释放Job相关
+ for (auto item : m_processJobs) {
+ delete item;
+ }
+ m_processJobs.clear();
+ if (m_pControlJob != nullptr) {
+ delete m_pControlJob;
+ m_pControlJob = nullptr;
+ }
+
+ // 注意要释放引用
+ m_inProcesJobs.clear();
+ m_completeProcessJobs.clear();
+ m_queueGlasses.clear();
+ m_inProcesGlasses.clear();
+ m_completeGlasses.clear();
+
+
+ saveState();
+
+ return true;
+ }
+
+ bool CMaster::forceCompleteControlJob(std::string description)
{
if (m_pControlJob == nullptr || m_state != SERVO::MASTERSTATE::READY) {
return false;
diff --git a/SourceCode/Bond/Servo/CMaster.h b/SourceCode/Bond/Servo/CMaster.h
index 47bf8cf..e014f7c 100644
--- a/SourceCode/Bond/Servo/CMaster.h
+++ b/SourceCode/Bond/Servo/CMaster.h
@@ -192,7 +192,8 @@
bool checkAndUpdatePjComplete(CProcessJob* pJob);
bool checkAndUpdateCjComplete(CControlJob* pJob);
CProcessJob* getGlassProcessJob(CGlass* pGlass);
- bool completeControlJob(std::string description);
+ bool completeControlJob();
+ bool forceCompleteControlJob(std::string description);
bool canCreateControlJob();
bool canCompleteControlJob();
bool canDeleteControlJob();
diff --git a/SourceCode/Bond/Servo/CPageGlassList.cpp b/SourceCode/Bond/Servo/CPageGlassList.cpp
index 4291a7e..eabdf81 100644
--- a/SourceCode/Bond/Servo/CPageGlassList.cpp
+++ b/SourceCode/Bond/Servo/CPageGlassList.cpp
@@ -661,106 +661,163 @@
auto pageFull = db.queryPaged(m_filters, rawLimit, rawOffset);
#endif
- // 濡傛灉澶氬嚭涓�鏉★紝鐪嬬湅瀹冩槸鍚︽槸鈥滄湰椤垫渶鍚庝竴鏉♀�濈殑 buddy
- std::optional<decltype(pageFull.items)::value_type> lookahead; // 棰勮璁板綍锛堣嫢涓庢渶鍚庝竴鏉¢厤瀵癸級
+#if !USE_FAKE_DB_DEMO
+ // 鈥斺�� 涓夊厓閿伐鍏凤細<classId>|C<cassette>|J<job> 鈥斺�� //
+// 鈥斺�� 涓夊厓閿伐鍏凤細<classId>|C<cassette>|J<job> 鈥斺�� //
+ auto makeKey = [](const std::string& cls, int csn, int jsn) -> std::string {
+ std::string k;
+ k.reserve(cls.size() + 32);
+ k.append(cls);
+ k.push_back('|'); k.push_back('C');
+ k.append(std::to_string(csn));
+ k.push_back('|'); k.push_back('J');
+ k.append(std::to_string(jsn));
+ return k;
+ };
+
+ // 鈽呪槄鈽� 杩欓噷鏄叧閿慨澶嶏細鎺ユ敹鈥渃onst Row&鈥濓紝涓嶈闈� const 寮曠敤
+ using RowT = std::decay<decltype(pageFull.items.front())>::type;
+ auto makeKeyR = [&](const RowT& r) -> std::string {
+ return makeKey(r.classId, r.cassetteSeqNo, r.jobSeqNo);
+ };
+
+ // 涓嶅尯鍒嗗ぇ灏忓啓 classId 鐩哥瓑
auto iEquals = [](const std::string& a, const std::string& b) {
#ifdef _WIN32
return _stricmp(a.c_str(), b.c_str()) == 0;
#else
return strcasecmp(a.c_str(), b.c_str()) == 0;
#endif
- };
+};
+
+ // 鈥斺�� lookahead 棰勮锛氳嫢瓒呭嚭 1 鏉★紝灏濊瘯鎶娾�滄渶鍚庝竴鏉♀�濅笌鈥滈璇烩�濆垽涓轰竴瀵癸紙涓ユ牸浼樺厛锛夆�斺��
+ std::optional<decltype(pageFull.items)::value_type> lookahead;
if (pageFull.items.size() == rawLimit) {
const auto& last = pageFull.items[PAGE_SIZE - 1];
const auto& extra = pageFull.items[PAGE_SIZE];
- bool pair =
+ bool strictPair =
+ (!last.buddyId.empty() && iEquals(last.buddyId, extra.classId)
+ && last.cassetteSeqNo == extra.cassetteSeqNo
+ && last.jobSeqNo == extra.jobSeqNo)
+ || (!extra.buddyId.empty() && iEquals(extra.buddyId, last.classId)
+ && extra.cassetteSeqNo == last.cassetteSeqNo
+ && extra.jobSeqNo == last.jobSeqNo);
+
+ bool loosePair =
(!last.buddyId.empty() && iEquals(last.buddyId, extra.classId)) ||
(!extra.buddyId.empty() && iEquals(extra.buddyId, last.classId));
- if (pair) {
- lookahead = extra; // 鎶婇璇讳繚瀛樹笅鏉ワ紝绋嶅悗琛ユ垚瀛愯
+ if (strictPair || loosePair) {
+ lookahead = extra;
}
- // 鏃犺鏄惁閰嶅锛屽垪琛ㄩ兘缂╁洖 PAGE_SIZE 鏉★紙棰勮涓嶇畻鍏ユ湰椤垫暟鎹泦锛�
+ // 棰勮涓嶇畻鍏ユ湰椤�
pageFull.items.pop_back();
}
// 涔嬪悗姝e父鎸� page 鏋勫缓
- auto& page = pageFull; // 涓轰簡澶嶇敤浣犲師鏈夊彉閲忓悕
+ auto& pageRef = pageFull;
- // 寤虹储寮曪細classId -> index
- std::unordered_map<std::string, size_t> idxById;
- idxById.reserve(page.items.size());
- for (size_t i = 0; i < page.items.size(); ++i) {
- idxById[page.items[i].classId] = i;
+ // 鈥斺�� 寤轰袱涓储寮� 鈥斺�� //
+ // A) byTriple: 涓夊厓閿� -> index锛堝敮涓�/宸叉秷璐逛緷鎹級
+ // B) byClass : classId -> indices锛坆uddy 鍊欓�夋睜锛屽厑璁稿涓級
+ std::unordered_map<std::string, size_t> byTriple;
+ std::unordered_map<std::string, std::vector<size_t>> byClass;
+ byTriple.reserve(pageRef.items.size());
+ byClass.reserve(pageRef.items.size());
+
+ for (size_t i = 0; i < pageRef.items.size(); ++i) {
+ const auto& r = pageRef.items[i];
+ byTriple[makeKeyR(r)] = i;
+ byClass[r.classId].push_back(i);
}
- // 宸叉秷璐癸紙宸叉彃鍏ヤ负鐖舵垨瀛愶級
+ // 鈥斺�� 宸叉秷璐归泦鍚堬紙鐢ㄤ笁鍏冮敭锛夆�斺��
std::unordered_set<std::string> consumed;
+ consumed.reserve(pageRef.items.size());
+
int zebra = 0;
auto zebraBk = [&](int z) -> COLORREF {
return (z % 2 == 0) ? RGB(255, 255, 255) : RGB(235, 235, 235);
};
- // -------- Phase 1: 鍏堝鐞嗏�滄湁 buddyId 鐨勮褰曗�濓紙鑳介厤灏遍厤锛涘崟鍚戜篃閰嶏級 ----------
- for (size_t i = 0; i < page.items.size(); ++i) {
- const auto& r = page.items[i];
- // CopyUtf8ToClipboard(r.pretty);
-
- if (consumed.count(r.classId)) continue;
+ // -------- Phase 1: 鍏堝鐞嗏�滄湁 buddyId 鐨勮褰曗�� ----------
+ for (size_t i = 0; i < pageRef.items.size(); ++i) {
+ const auto& r = pageRef.items[i];
+ if (consumed.count(makeKeyR(r))) continue;
if (r.buddyId.empty()) continue;
- COLORREF bk = zebraBk(zebra);
+ // 鍦ㄥ悓椤甸噷涓� r 鎵� buddy 鍊欓��
+ size_t buddyIdx = (size_t)-1;
+ auto itVec = byClass.find(r.buddyId);
+ if (itVec != byClass.end()) {
+ const auto& vec = itVec->second;
- auto it = idxById.find(r.buddyId);
- if (it != idxById.end()) {
- const auto& br = page.items[it->second];
- if (!consumed.count(br.classId)) {
- // 鈥斺�� 浠モ�滄湁 buddyId 鐨勮繖鏉� r鈥濅负鐖讹紝buddy 浣滀负瀛愶紙鍗曞悜涔熻兘閰嶏級鈥斺��
- std::vector<CString> pcols(colCount);
- pcols[1] = std::to_string(r.id).c_str();
- pcols[2] = std::to_string(r.cassetteSeqNo).c_str();
- pcols[3] = std::to_string(r.jobSeqNo).c_str();
- pcols[4] = r.classId.c_str();
- pcols[5] = SERVO::CServoUtilsTool::getMaterialsTypeText((SERVO::MaterialsType)r.materialType).c_str();
- pcols[6] = SERVO::CServoUtilsTool::getGlassStateText((SERVO::GlsState)r.state).c_str();
- pcols[7] = r.tStart.c_str();
- pcols[8] = r.tEnd.c_str();
- pcols[9] = r.buddyId.c_str();
- pcols[10] = SERVO::CServoUtilsTool::getInspResultText((SERVO::InspResult)r.aoiResult).c_str();
- pcols[11] = r.path.c_str();
- pcols[12] = r.params.c_str();
-
- auto* nParent = m_listCtrl.InsertRoot(pcols);
- MaybeRestoreExpandByKey(nParent, expandedKeys);
- m_listCtrl.SetNodeColor(nParent, RGB(0, 0, 0), bk);
-
- std::vector<CString> ccols(colCount);
- ccols[1] = std::to_string(br.id).c_str();
- ccols[2] = std::to_string(br.cassetteSeqNo).c_str();
- ccols[3] = std::to_string(br.jobSeqNo).c_str();
- ccols[4] = br.classId.c_str();
- ccols[5] = SERVO::CServoUtilsTool::getMaterialsTypeText((SERVO::MaterialsType)br.materialType).c_str();
- ccols[6] = SERVO::CServoUtilsTool::getGlassStateText((SERVO::GlsState)br.state).c_str();
- ccols[7] = br.tStart.c_str();
- ccols[8] = br.tEnd.c_str();
- ccols[9] = br.buddyId.c_str();
- ccols[10] = SERVO::CServoUtilsTool::getInspResultText((SERVO::InspResult)br.aoiResult).c_str();
- ccols[11] = br.path.c_str();
- ccols[12] = br.params.c_str();
-
- auto* nChild = m_listCtrl.InsertChild(nParent, ccols);
- m_listCtrl.SetNodeColor(nChild, RGB(0, 0, 0), bk);
-
- consumed.insert(r.classId);
- consumed.insert(br.classId);
- ++zebra;
- continue;
+ // 1) 涓ユ牸鍖归厤锛欳assette/Job 涓�鑷�
+ for (size_t j : vec) {
+ const auto& br = pageRef.items[j];
+ if (br.cassetteSeqNo == r.cassetteSeqNo && br.jobSeqNo == r.jobSeqNo) {
+ if (!consumed.count(makeKeyR(br))) { buddyIdx = j; break; }
+ }
+ }
+ // 2) 瀹芥澗鍖归厤锛氬悓 classId 鏈秷璐圭殑浠绘剰涓�鏉�
+ if (buddyIdx == (size_t)-1) {
+ for (size_t j : vec) {
+ const auto& br = pageRef.items[j];
+ if (!consumed.count(makeKeyR(br))) { buddyIdx = j; break; }
+ }
}
}
- // 鍚岄〉娌℃壘鍒� buddy锛堟垨宸茶娑堣垂锛夆啋 鎻掑崰浣嶅瓙琛�
+ COLORREF bk = zebraBk(zebra);
+
+ if (buddyIdx != (size_t)-1) {
+ const auto& br = pageRef.items[buddyIdx];
+
+ // 鐖讹細r锛堟湁 buddyId锛夛紝瀛愶細br
+ std::vector<CString> pcols(colCount);
+ pcols[1] = std::to_string(r.id).c_str();
+ pcols[2] = std::to_string(r.cassetteSeqNo).c_str();
+ pcols[3] = std::to_string(r.jobSeqNo).c_str();
+ pcols[4] = r.classId.c_str();
+ pcols[5] = SERVO::CServoUtilsTool::getMaterialsTypeText((SERVO::MaterialsType)r.materialType).c_str();
+ pcols[6] = SERVO::CServoUtilsTool::getGlassStateText((SERVO::GlsState)r.state).c_str();
+ pcols[7] = r.tStart.c_str();
+ pcols[8] = r.tEnd.c_str();
+ pcols[9] = r.buddyId.c_str();
+ pcols[10] = SERVO::CServoUtilsTool::getInspResultText((SERVO::InspResult)r.aoiResult).c_str();
+ pcols[11] = r.path.c_str();
+ pcols[12] = r.params.c_str();
+
+ auto* nParent = m_listCtrl.InsertRoot(pcols);
+ MaybeRestoreExpandByKey(nParent, expandedKeys);
+ m_listCtrl.SetNodeColor(nParent, RGB(0, 0, 0), bk);
+
+ std::vector<CString> ccols(colCount);
+ ccols[1] = std::to_string(br.id).c_str();
+ ccols[2] = std::to_string(br.cassetteSeqNo).c_str();
+ ccols[3] = std::to_string(br.jobSeqNo).c_str();
+ ccols[4] = br.classId.c_str();
+ ccols[5] = SERVO::CServoUtilsTool::getMaterialsTypeText((SERVO::MaterialsType)br.materialType).c_str();
+ ccols[6] = SERVO::CServoUtilsTool::getGlassStateText((SERVO::GlsState)br.state).c_str();
+ ccols[7] = br.tStart.c_str();
+ ccols[8] = br.tEnd.c_str();
+ ccols[9] = br.buddyId.c_str();
+ ccols[10] = SERVO::CServoUtilsTool::getInspResultText((SERVO::InspResult)br.aoiResult).c_str();
+ ccols[11] = br.path.c_str();
+ ccols[12] = br.params.c_str();
+
+ auto* nChild = m_listCtrl.InsertChild(nParent, ccols);
+ m_listCtrl.SetNodeColor(nChild, RGB(0, 0, 0), bk);
+
+ consumed.insert(makeKeyR(r));
+ consumed.insert(makeKeyR(br));
+ ++zebra;
+ continue;
+ }
+
+ // 娌℃壘鍒� buddy 鈫� 鎻掑崰浣嶅瓙琛岋紙鍙啓 ClassID锛�
std::vector<CString> pcols(colCount);
pcols[1] = std::to_string(r.id).c_str();
pcols[2] = std::to_string(r.cassetteSeqNo).c_str();
@@ -777,24 +834,162 @@
auto* nParent = m_listCtrl.InsertRoot(pcols);
MaybeRestoreExpandByKey(nParent, expandedKeys);
- m_listCtrl.SetNodeColor(nParent, RGB(0, 0, 0), bk);
+ m_listCtrl.SetNodeColor(nParent, RGB(0, 0, 0), zebraBk(zebra));
- std::vector<CString> ccols(colCount); // 鍗犱綅鍙啓 ClassID
- ccols[4] = r.buddyId.c_str();
+ std::vector<CString> ccols(colCount);
+ ccols[4] = r.buddyId.c_str(); // 鍗犱綅
auto* nChild = m_listCtrl.InsertChild(nParent, ccols);
- m_listCtrl.SetNodeColor(nChild, RGB(0, 0, 0), bk);
+ m_listCtrl.SetNodeColor(nChild, RGB(0, 0, 0), zebraBk(zebra));
- consumed.insert(r.classId);
+ consumed.insert(makeKeyR(r));
++zebra;
}
// -------- Phase 2: 鍓╀綑鏈秷璐圭殑锛屼綔涓衡�滃崟鏉℃牴琛屸�� ----------
- for (size_t i = 0; i < page.items.size(); ++i) {
- const auto& r = page.items[i];
- if (consumed.count(r.classId)) continue;
+ for (size_t i = 0; i < pageRef.items.size(); ++i) {
+ const auto& r = pageRef.items[i];
+ if (consumed.count(makeKeyR(r))) continue;
COLORREF bk = zebraBk(zebra);
+ std::vector<CString> cols(colCount);
+ cols[1] = std::to_string(r.id).c_str();
+ cols[2] = std::to_string(r.cassetteSeqNo).c_str();
+ cols[3] = std::to_string(r.jobSeqNo).c_str();
+ cols[4] = r.classId.c_str();
+ cols[5] = SERVO::CServoUtilsTool::getMaterialsTypeText((SERVO::MaterialsType)r.materialType).c_str();
+ cols[6] = SERVO::CServoUtilsTool::getGlassStateText((SERVO::GlsState)r.state).c_str();
+ cols[7] = r.tStart.c_str();
+ cols[8] = r.tEnd.c_str();
+ cols[9] = r.buddyId.c_str();
+ cols[10] = SERVO::CServoUtilsTool::getInspResultText((SERVO::InspResult)r.aoiResult).c_str();
+ cols[11] = r.path.c_str();
+ cols[12] = r.params.c_str();
+
+ auto* n = m_listCtrl.InsertRoot(cols);
+ m_listCtrl.SetNodeColor(n, RGB(0, 0, 0), bk);
+
+ consumed.insert(makeKeyR(r));
+ ++zebra;
+ }
+
+ // 涓�娆℃�ч噸缁�
+ m_listCtrl.RebuildVisible();
+
+#else
+ // ===== DEMO 鍒嗘敮锛堜繚鎸佸師鏍凤紱鑻ヨ婕旂ず鍚屾牱閫昏緫锛屽彲浠跨収涓婇潰鏀归�狅級=====
+ // 濡傛灉澶氬嚭涓�鏉★紝鐪嬬湅瀹冩槸鍚︽槸鈥滄湰椤垫渶鍚庝竴鏉♀�濈殑 buddy
+ std::optional<decltype(page.items)::value_type> lookahead;
+ auto iEquals = [](const std::string& a, const std::string& b) {
+#ifdef _WIN32
+ return _stricmp(a.c_str(), b.c_str()) == 0;
+#else
+ return strcasecmp(a.c_str(), b.c_str()) == 0;
+#endif
+ };
+
+ if (page.items.size() == rawLimit) {
+ const auto& last = page.items[PAGE_SIZE - 1];
+ const auto& extra = page.items[PAGE_SIZE];
+ bool pair =
+ (!last.buddyId.empty() && iEquals(last.buddyId, extra.classId)) ||
+ (!extra.buddyId.empty() && iEquals(extra.buddyId, last.classId));
+ if (pair) lookahead = extra;
+ page.items.pop_back();
+ }
+
+ // 浣犲彲浠ユ妸 DEMO 鍒嗘敮涔熷垏鍒颁笁鍏冮敭閫昏緫锛涜繖閲屼粠鐣�
+ auto& pageRef = page;
+ std::unordered_map<std::string, size_t> idxById;
+ idxById.reserve(pageRef.items.size());
+ for (size_t i = 0; i < pageRef.items.size(); ++i) idxById[pageRef.items[i].classId] = i;
+
+ std::unordered_set<std::string> consumed;
+ int zebra = 0;
+ auto zebraBk = [&](int z) -> COLORREF {
+ return (z % 2 == 0) ? RGB(255, 255, 255) : RGB(235, 235, 235);
+ };
+
+ for (size_t i = 0; i < pageRef.items.size(); ++i) {
+ const auto& r = pageRef.items[i];
+ if (consumed.count(r.classId)) continue;
+ if (!r.buddyId.empty()) {
+ auto it = idxById.find(r.buddyId);
+ if (it != idxById.end()) {
+ const auto& br = pageRef.items[it->second];
+ if (!consumed.count(br.classId)) {
+ COLORREF bk = zebraBk(zebra);
+ std::vector<CString> pcols(colCount), ccols(colCount);
+ pcols[1] = std::to_string(r.id).c_str();
+ pcols[2] = std::to_string(r.cassetteSeqNo).c_str();
+ pcols[3] = std::to_string(r.jobSeqNo).c_str();
+ pcols[4] = r.classId.c_str();
+ pcols[5] = SERVO::CServoUtilsTool::getMaterialsTypeText((SERVO::MaterialsType)r.materialType).c_str();
+ pcols[6] = SERVO::CServoUtilsTool::getGlassStateText((SERVO::GlsState)r.state).c_str();
+ pcols[7] = r.tStart.c_str();
+ pcols[8] = r.tEnd.c_str();
+ pcols[9] = r.buddyId.c_str();
+ pcols[10] = SERVO::CServoUtilsTool::getInspResultText((SERVO::InspResult)r.aoiResult).c_str();
+ pcols[11] = r.path.c_str();
+ pcols[12] = r.params.c_str();
+ auto* nParent = m_listCtrl.InsertRoot(pcols);
+ MaybeRestoreExpandByKey(nParent, expandedKeys);
+ m_listCtrl.SetNodeColor(nParent, RGB(0, 0, 0), bk);
+
+ ccols[1] = std::to_string(br.id).c_str();
+ ccols[2] = std::to_string(br.cassetteSeqNo).c_str();
+ ccols[3] = std::to_string(br.jobSeqNo).c_str();
+ ccols[4] = br.classId.c_str();
+ ccols[5] = SERVO::CServoUtilsTool::getMaterialsTypeText((SERVO::MaterialsType)br.materialType).c_str();
+ ccols[6] = SERVO::CServoUtilsTool::getGlassStateText((SERVO::GlsState)br.state).c_str();
+ ccols[7] = br.tStart.c_str();
+ ccols[8] = br.tEnd.c_str();
+ ccols[9] = br.buddyId.c_str();
+ ccols[10] = SERVO::CServoUtilsTool::getInspResultText((SERVO::InspResult)br.aoiResult).c_str();
+ ccols[11] = br.path.c_str();
+ ccols[12] = br.params.c_str();
+ auto* nChild = m_listCtrl.InsertChild(nParent, ccols);
+ m_listCtrl.SetNodeColor(nChild, RGB(0, 0, 0), bk);
+
+ consumed.insert(r.classId);
+ consumed.insert(br.classId);
+ ++zebra;
+ continue;
+ }
+ }
+
+ // 鎻掑崰浣嶅瓙
+ COLORREF bk = zebraBk(zebra);
+ std::vector<CString> pcols(colCount), ccols(colCount);
+ pcols[1] = std::to_string(r.id).c_str();
+ pcols[2] = std::to_string(r.cassetteSeqNo).c_str();
+ pcols[3] = std::to_string(r.jobSeqNo).c_str();
+ pcols[4] = r.classId.c_str();
+ pcols[5] = SERVO::CServoUtilsTool::getMaterialsTypeText((SERVO::MaterialsType)r.materialType).c_str();
+ pcols[6] = SERVO::CServoUtilsTool::getGlassStateText((SERVO::GlsState)r.state).c_str();
+ pcols[7] = r.tStart.c_str();
+ pcols[8] = r.tEnd.c_str();
+ pcols[9] = r.buddyId.c_str();
+ pcols[10] = SERVO::CServoUtilsTool::getInspResultText((SERVO::InspResult)r.aoiResult).c_str();
+ pcols[11] = r.path.c_str();
+ pcols[12] = r.params.c_str();
+ auto* nParent = m_listCtrl.InsertRoot(pcols);
+ MaybeRestoreExpandByKey(nParent, expandedKeys);
+ m_listCtrl.SetNodeColor(nParent, RGB(0, 0, 0), bk);
+
+ ccols[4] = r.buddyId.c_str();
+ auto* nChild = m_listCtrl.InsertChild(nParent, ccols);
+ m_listCtrl.SetNodeColor(nChild, RGB(0, 0, 0), bk);
+
+ consumed.insert(r.classId);
+ ++zebra;
+ }
+ }
+ for (size_t i = 0; i < pageRef.items.size(); ++i) {
+ const auto& r = pageRef.items[i];
+ if (consumed.count(r.classId)) continue;
+
+ COLORREF bk = zebraBk(zebra);
std::vector<CString> cols(colCount);
cols[1] = std::to_string(r.id).c_str();
cols[2] = std::to_string(r.cassetteSeqNo).c_str();
@@ -816,8 +1011,8 @@
++zebra;
}
- // 涓�娆℃�ч噸缁�
m_listCtrl.RebuildVisible();
+#endif
// 涓婁竴椤� / 涓嬩竴椤�
UpdatePageControls();
@@ -1162,7 +1357,7 @@
CExpandableListCtrl::Node* savedTop = nullptr;
// 3) 閫愪釜澶勭悊 WIP锛氬凡瀛樺湪 -> 灏卞湴鏇存柊锛涘繀瑕佹椂鈥滃彧瀵规牴琛ュ瓙椤光��
- // 涓嶅瓨鍦� -> 浼樺厛鎸傚埌 buddy 瀹瑰櫒锛涘惁鍒欒Е鍙戞暣椤甸噸寤猴紙鏂版牴淇濇寔椤堕儴锛�
+ // 涓嶅瓨鍦� -> 鎸傚埌 buddy 瀹瑰櫒锛涜嫢 buddy 涓嶅湪鍙琛紝瑙﹀彂鍏ㄩ噺閲嶅缓锛堜繚璇� WIP 椤堕儴锛�
for (auto* g : wipGlasses) {
if (!GlassMatchesFilters(*g, m_filters)) continue;
@@ -1205,7 +1400,7 @@
}
}
- // 鈥斺�� 鍙鈥滄牴鑺傜偣鈥濊ˉ瀛愰」锛屼笖浠呭綋 buddy 灏氭湭鍑虹幇鍦ㄥ彲瑙佽〃锛屼笖鏍逛笅涔熸病鏈夎 buddy 鈥斺��
+ // 鈥斺�� 鍙鈥滄牴鑺傜偣鈥濊ˉ瀛愰」 鈥斺��
SERVO::CGlass* b = g->getBuddy();
if (b) {
auto itRoot = wipRootById.find(cid);
@@ -1227,7 +1422,7 @@
bool buddyExistsAnywhere = (wipRowById.find(newBid) != wipRowById.end());
bool hasChildAlready = NodeHasChildWithClassId(container, newBuddyCid);
- // 鍏崇郴鏄惁鍙戠敓鍙樺寲锛燂紙oldChildCid 涓� newBuddyCid 涓嶅悓锛屾垨鏈夊瓙浣嗙幇鍦ㄦ病 buddy锛�
+ // 鍏崇郴鏄惁鍙戠敓鍙樺寲锛�
bool relationChanged =
(!oldChildCid.IsEmpty() && newBuddyCid.IsEmpty()) ||
(oldChildCid.IsEmpty() && !newBuddyCid.IsEmpty()) ||
@@ -1270,10 +1465,9 @@
}
}
}
- // 鑻ュ綋鍓嶆槸鈥滃瓙鑺傜偣鈥濓紝涓嶅湪杩欓噷璋冩暣鐖跺瓙鍏崇郴锛涜鈥滃叧绯诲彉鍖栤�濊蛋鍏ㄩ噺閲嶅缓
}
else {
- // 娌℃湁 buddy锛氬鏋滃鍣ㄤ笅鐜板湪鏈夊瓙锛屼篃绠楀叧绯诲彉鍖栵紝瑙﹀彂閲嶅缓
+ // 娌� buddy 浣嗗鍣ㄤ笅鏈夊瓙 -> 鍏崇郴鍙樺寲锛岃Е鍙戝叏閲忛噸寤�
auto itRoot = wipRootById.find(cid);
if (itRoot != wipRootById.end()) {
CExpandableListCtrl::Node* container = itRoot->second;
@@ -1284,8 +1478,6 @@
}
else {
// (B) 涓嶅瓨鍦細鏂板
- // 鍏堝皾璇曗�滄寕鍒� buddy 鐨勫鍣ㄦ牴鈥濅笅闈紱
- // 鑻� buddy 涓嶅湪褰撳墠鍙琛紝鍒欒Е鍙戝叏閲忛噸寤猴紙淇濊瘉 WIP 椤堕儴锛夈��
SERVO::CGlass* b = g->getBuddy();
CExpandableListCtrl::Node* container = nullptr;
@@ -1303,7 +1495,6 @@
}
if (container) {
- // buddy 瀹瑰櫒瀛樺湪锛氭妸 g 浣滀负鈥滃瓙琛屸�濇寕涓婂幓锛堥伩鍏嶉噸澶嶏級
CString cidCs = g->getID().c_str();
if (!NodeHasChildWithClassId(container, cidCs)) {
if (!needRebuildChildren) { CaptureUiState(m_listCtrl, savedSel, savedTop); }
diff --git a/SourceCode/Bond/Servo/Servo.rc b/SourceCode/Bond/Servo/Servo.rc
index 4ff1ae5..3a00a2f 100644
--- a/SourceCode/Bond/Servo/Servo.rc
+++ b/SourceCode/Bond/Servo/Servo.rc
Binary files differ
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj.user b/SourceCode/Bond/Servo/Servo.vcxproj.user
index 82c7903..0c03257 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj.user
+++ b/SourceCode/Bond/Servo/Servo.vcxproj.user
@@ -7,6 +7,6 @@
<RemoteDebuggerCommand>\\DESKTOP-IODBVIQ\Servo\Debug\Servo.exe</RemoteDebuggerCommand>
<RemoteDebuggerWorkingDirectory>\\DESKTOP-IODBVIQ\Servo\Debug\</RemoteDebuggerWorkingDirectory>
<RemoteDebuggerServerName>DESKTOP-IODBVIQ</RemoteDebuggerServerName>
- <DebuggerFlavor>WindowsRemoteDebugger</DebuggerFlavor>
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>
\ No newline at end of file
diff --git a/SourceCode/Bond/Servo/resource.h b/SourceCode/Bond/Servo/resource.h
index 5d39e6e..1d1a388 100644
--- a/SourceCode/Bond/Servo/resource.h
+++ b/SourceCode/Bond/Servo/resource.h
Binary files differ
--
Gitblit v1.9.3