From 8294c107676c18538c6e06fe8eab2d209604ac6a Mon Sep 17 00:00:00 2001
From: chenluhua1980 <Chenluhua@qq.com>
Date: 星期一, 19 一月 2026 18:34:06 +0800
Subject: [PATCH] 1.完善和优化界面显示,数据懒加载,等待光标等,修复启动时界面卡的问题。 2.SVData的Push的限制和检查,因发现Glass呆在机器中时,不管机台是否运行都在不停压入数据。

---
 SourceCode/Bond/Servo/CMaster.cpp |  388 ++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 272 insertions(+), 116 deletions(-)

diff --git a/SourceCode/Bond/Servo/CMaster.cpp b/SourceCode/Bond/Servo/CMaster.cpp
index ee0b951..80ce726 100644
--- a/SourceCode/Bond/Servo/CMaster.cpp
+++ b/SourceCode/Bond/Servo/CMaster.cpp
@@ -3,10 +3,14 @@
 #include "CMaster.h"
 #include <future>
 #include <vector>
+#include <algorithm>
 #include "RecipeManager.h"
 #include <fstream>
 #include "SerializeUtil.h"
 #include "CServoUtilsTool.h"
+#include "AlarmManager.h"
+#include "ToolUnits.h"
+#include "Model.h"
 
 
 namespace SERVO {
@@ -71,6 +75,8 @@
 		m_nContinuousWorkingPort = 0;
 		m_nContinuousWorkingSlot = 0;
 		m_pControlJob = nullptr;
+		m_bPauseAlarmRaised = false;
+		m_pModelCtx = nullptr;
 		m_nTestFlag = 0;
 		InitializeCriticalSection(&m_criticalSection);
 	}
@@ -120,6 +126,11 @@
 		m_listener = listener;
 	}
 
+	void CMaster::setModelCtx(CModel* pModel)
+	{
+		m_pModelCtx = pModel;
+	}
+
 	CRobotTask* CMaster::getActiveRobotTask()
 	{
 		return m_pActiveRobotTask;
@@ -127,128 +138,147 @@
 
 	int CMaster::init()
 	{
+		const ULONGLONG boot_master_begin = GetTickCount64();
 		LOGI("<Master>姝e湪鍒濆鍖�...");
+		LOGI("[BOOT][MASTER] init begin");
 
 
 		// 	cclink
-		if (m_cclink.Connect(CC_LINK_IE_CONTROL_CHANNEL(1)) != 0) {
+		const ULONGLONG boot_cclink_begin = GetTickCount64();
+		const int cc_ret = m_cclink.Connect(CC_LINK_IE_CONTROL_CHANNEL(1));
+		LOGI("[BOOT][MASTER] CC-Link connect ret=%d, cost=%llu ms",
+			cc_ret,
+			(unsigned long long)(GetTickCount64() - boot_cclink_begin));
+		if (cc_ret != 0) {
 			LOGE("杩炴帴CC-Link澶辫触.");
 		}
 		else {
-			LOGI("杩炴帴CC-Link鎴愬姛.");
-			BoardVersion version{};
-			int nRet = m_cclink.GetBoardVersion(version);
-			if (nRet == 0) {
-				LOGD("鐗堟湰淇℃伅锛�%s.", version.toString().c_str());
-			}
-			else {
-				LOGE("鑾峰彇CC-Link鐗堟湰淇℃伅澶辫触.");
+				LOGI("杩炴帴CC-Link鎴愬姛.");
+				BoardVersion version{};
+				int nRet = m_cclink.GetBoardVersion(version);
+				if (nRet == 0) {
+					LOGD("鐗堟湰淇℃伅锛�%s.", version.toString().c_str());
+				}
+				else {
+					LOGE("鑾峰彇CC-Link鐗堟湰淇℃伅澶辫触.");
+				}
+
+				BoardStatus status;
+				nRet = m_cclink.GetBoardStatus(status);
+				if (nRet == 0) {
+					LOGD("鐘舵�侊細%s.", status.toString().c_str());
+				}
+				else {
+					LOGE("鑾峰彇CC-Link鐘舵�佸け璐�.");
+				}
 			}
 
-			BoardStatus status;
-			nRet = m_cclink.GetBoardStatus(status);
-			if (nRet == 0) {
-				LOGD("鐘舵�侊細%s.", status.toString().c_str());
+
+			// 鍒濆鍖栨坊鍔犲悇瀛愯澶�
+			CLoadPort* pPort1, * pPort2, * pPort3, * pPort4;
+			CBonder* pBonder1, * pBonder2;
+			CEFEM* pEfem;
+			CArm* pArm;
+			CArmTray* pArmTray1, * pArmTray2;
+			CFliper* pFliper;
+			CVacuumBake* pVacuumBake;
+			CAligner* pAligner;
+			CBakeCooling* pBakeCooling;
+			CMeasurement* pMeasurement;
+
+			pPort1 = addLoadPort(0);
+			pPort2 = addLoadPort(1);
+			pPort3 = addLoadPort(2);
+			pPort4 = addLoadPort(3);
+			pEfem = addEFEM();
+			pArm = addArm();
+			pArmTray1 = addArmTray(0);
+			pArmTray2 = addArmTray(1);
+			pFliper = addFliper();
+			pVacuumBake = addVacuumBake();
+			pAligner = addAligner();
+			pBonder1 = addBonder(0);
+			pBonder2 = addBonder(1);
+			pBakeCooling = addBakeCooling();
+			pMeasurement = addMeasurement();
+
+			ASSERT(pEfem);
+			ASSERT(pFliper);
+			ASSERT(pVacuumBake);
+			ASSERT(pAligner);
+			ASSERT(pBonder1);
+			ASSERT(pBonder2);
+			ASSERT(pBakeCooling);
+			ASSERT(pMeasurement);
+
+			pEfem->setPort(0, pPort1);
+			pEfem->setPort(1, pPort2);
+			pEfem->setPort(2, pPort3);
+			pEfem->setPort(3, pPort4);
+			pEfem->setFliper(pFliper);
+			pEfem->setAligner(pAligner);
+			pEfem->setArmTray(0, pArmTray1);
+			pEfem->setArmTray(1, pArmTray2);
+			pPort1->setArm(pArm);
+			pPort2->setArm(pArm);
+			pPort3->setArm(pArm);
+			pPort4->setArm(pArm);
+			pArmTray1->setArm(pArm);
+			pArmTray2->setArm(pArm);
+			pFliper->setArm(pArm);
+			pVacuumBake->setArm(pArm);
+			pAligner->setArm(pArm);
+			pBonder1->setArm(pArm);
+			pBonder2->setArm(pArm);
+			pBakeCooling->setArm(pArm);
+			pMeasurement->setArm(pArm);
+
+			connectEquipments();
+
+
+
+			// 璇荤紦瀛樻暟鎹�
+			const ULONGLONG boot_cache_begin = GetTickCount64();
+			const ULONGLONG boot_read_begin = GetTickCount64();
+			readCache();
+			LOGI("[BOOT][MASTER] readCache finished, cost=%llu ms", (unsigned long long)(GetTickCount64() - boot_read_begin));
+
+			const ULONGLONG boot_state_begin = GetTickCount64();
+			loadState();
+			LOGI("[BOOT][MASTER] loadState finished, cost=%llu ms", (unsigned long long)(GetTickCount64() - boot_state_begin));
+			if (m_listener.onControlJobChanged) {
+				notifyControlJobChanged();
 			}
-			else {
-				LOGE("鑾峰彇CC-Link鐘舵�佸け璐�.");
-			}
+
+			LOGI("[BOOT][MASTER] cache/state loaded, cost=%llu ms (since init %llu ms)",
+				(unsigned long long)(GetTickCount64() - boot_cache_begin),
+				(unsigned long long)(GetTickCount64() - boot_master_begin));
+
+
+			// 瀹氭椂鍣�
+			g_pMaster = this;
+			SetTimer(NULL, 1, 250, (TIMERPROC)MasterTimerProc);
+
+
+			// 璋冨害绾跨▼
+			m_hDispatchThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::DispatchThreadFunction, this,
+				0, &m_nDispatchThreadAddr);
+
+
+			// 鐩戞帶bit绾跨▼
+			m_hReadBitsThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::ReadBitsThreadFunction, this,
+				0, &m_nReadBitsThreadAddr);
+
+
+			// 鏇茬嚎鏈嶅姟
+			CreateDAQBridgeServer();
+
+
+			LOGI("<Master>鍒濆鍖栧畬鎴�.");
+			LOGI("[BOOT][MASTER] init finished, total cost=%llu ms",
+				(unsigned long long)(GetTickCount64() - boot_master_begin));
+			return 0;
 		}
-
-
-		// 鍒濆鍖栨坊鍔犲悇瀛愯澶�
-		CLoadPort* pPort1, * pPort2, * pPort3, * pPort4;
-		CBonder* pBonder1, * pBonder2;
-		CEFEM* pEfem;
-		CArm* pArm;
-		CArmTray* pArmTray1, * pArmTray2;
-		CFliper* pFliper;
-		CVacuumBake* pVacuumBake;
-		CAligner* pAligner;
-		CBakeCooling* pBakeCooling;
-		CMeasurement* pMeasurement;
-
-		pPort1 = addLoadPort(0);
-		pPort2 = addLoadPort(1);
-		pPort3 = addLoadPort(2);
-		pPort4 = addLoadPort(3);
-		pEfem = addEFEM();
-		pArm = addArm();
-		pArmTray1 = addArmTray(0);
-		pArmTray2 = addArmTray(1);
-		pFliper = addFliper();
-		pVacuumBake = addVacuumBake();
-		pAligner = addAligner();
-		pBonder1 = addBonder(0);
-		pBonder2 = addBonder(1);
-		pBakeCooling = addBakeCooling();
-		pMeasurement = addMeasurement();
-
-		ASSERT(pEfem);
-		ASSERT(pFliper);
-		ASSERT(pVacuumBake);
-		ASSERT(pAligner);
-		ASSERT(pBonder1);
-		ASSERT(pBonder2);
-		ASSERT(pBakeCooling);
-		ASSERT(pMeasurement);
-
-		pEfem->setPort(0, pPort1);
-		pEfem->setPort(1, pPort2);
-		pEfem->setPort(2, pPort3);
-		pEfem->setPort(3, pPort4);
-		pEfem->setFliper(pFliper);
-		pEfem->setAligner(pAligner);
-		pEfem->setArmTray(0, pArmTray1);
-		pEfem->setArmTray(1, pArmTray2);
-		pPort1->setArm(pArm);
-		pPort2->setArm(pArm);
-		pPort3->setArm(pArm);
-		pPort4->setArm(pArm);
-		pArmTray1->setArm(pArm);
-		pArmTray2->setArm(pArm);
-		pFliper->setArm(pArm);
-		pVacuumBake->setArm(pArm);
-		pAligner->setArm(pArm);
-		pBonder1->setArm(pArm);
-		pBonder2->setArm(pArm);
-		pBakeCooling->setArm(pArm);
-		pMeasurement->setArm(pArm);
-
-		connectEquipments();
-
-
-
-		// 璇荤紦瀛樻暟鎹�
-		readCache();
-		loadState();
-		if (m_listener.onControlJobChanged) {
-			m_listener.onControlJobChanged(this);
-		}
-
-
-		// 瀹氭椂鍣�
-		g_pMaster = this;
-		SetTimer(NULL, 1, 250, (TIMERPROC)MasterTimerProc);
-
-
-		// 璋冨害绾跨▼
-		m_hDispatchThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::DispatchThreadFunction, this,
-			0, &m_nDispatchThreadAddr);
-
-
-		// 鐩戞帶bit绾跨▼
-		m_hReadBitsThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::ReadBitsThreadFunction, this,
-			0, &m_nReadBitsThreadAddr);
-
-
-		// 鏇茬嚎鏈嶅姟
-		CreateDAQBridgeServer();
-
-
-		LOGI("<Master>鍒濆鍖栧畬鎴�.");
-		return 0;
-	}
 
 	int CMaster::term()
 	{
@@ -878,6 +908,33 @@
 						m_pActiveRobotTask->place();
 					}
 					unlock(); // 绛夊綋鍓嶄换鍔″畬鎴愭垨涓鍚庣户缁�
+					continue;
+				}
+
+				// 5.5) 鏆傚仠鐘舵�佹鏌ワ細鑻� CJ 鎴栧湪鍒� PJ 澶勪簬 Paused锛屾殏缂撹皟搴︽柊鐨勬惉閫�
+				bool pausedByEvent = false;
+				if (m_pControlJob != nullptr && m_pControlJob->state() == CJState::Paused) {
+					pausedByEvent = true;
+				}
+				for (auto pj : m_inProcesJobs) {
+					if (pj != nullptr && pj->state() == PJState::Paused) {
+						pausedByEvent = true;
+						break;
+					}
+				}
+				if (!pausedByEvent && m_bPauseAlarmRaised) {
+					if (m_pModelCtx != nullptr) {
+						m_pModelCtx->clearSoftAlarm(ALID_SOFTWARE_PAUSE_EVENT, 0, 0);
+					}
+					else {
+						AlarmManager& alarmManager = AlarmManager::getInstance();
+						alarmManager.clearAlarmByAttributes(ALID_SOFTWARE_PAUSE_EVENT, 0, 0, CToolUnits::getCurrentTimeString());
+					}
+					m_bPauseAlarmRaised = false;
+				}
+				if (pausedByEvent) {
+					LOGI("<Master>璋冨害鏆傚仠锛欳ontrolJob/ProcessJob 澶勪簬 Paused 鐘舵�侊紙鍙兘鐢� PauseEvent 瑙﹀彂锛�");
+					unlock();
 					continue;
 				}
 
@@ -1637,6 +1694,14 @@
 			}
 		};
 		listener.onSVDataReport = [&](void* pEquipment, void* pData) {
+			const bool allowSvLog =
+				(m_state == MASTERSTATE::RUNNING ||
+					m_state == MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER ||
+					m_state == MASTERSTATE::RUNNING_BATCH ||
+					m_state == MASTERSTATE::STARTING);
+			if (!allowSvLog) {
+				return;
+			}
 			CSVData* pSVData = (CSVData*)pData;
 			auto rawData = pSVData->getSVRawData();
 			std::vector<CParam> params;
@@ -2858,7 +2923,7 @@
 
 		this->saveState();
 		if (m_listener.onControlJobChanged) {
-			m_listener.onControlJobChanged(this);
+			notifyControlJobChanged();
 		}
 
 		return (int)m_processJobs.size();
@@ -2918,7 +2983,7 @@
 		m_pControlJob->setPJs(temps);
 		this->saveState();
 		if (m_listener.onControlJobChanged) {
-			m_listener.onControlJobChanged(this);
+			notifyControlJobChanged();
 		}
 
 
@@ -2972,7 +3037,98 @@
 
 	bool CMaster::ceidDefined(uint32_t ceid) const
 	{
-		return true;
+		if (m_allowedCeids.empty()) return true; // backward compatible: treat as all allowed when not configured
+		return m_allowedCeids.find(ceid) != m_allowedCeids.end();
+	}
+
+	bool CMaster::raiseSoftAlarm(int alarmId,
+		const std::string& desc,
+		int level/* = -1*/,
+		int deviceId/* = 0*/,
+		int unitId/* = 0*/,
+		const char* deviceName/* = "Software"*/,
+		const char* unitName/* = "App"*/)
+	{
+		AlarmManager& alarmManager = AlarmManager::getInstance();
+		const AlarmInfo* info = alarmManager.getAlarmInfoByID(alarmId);
+
+		int severity = level;
+		if (severity < 0 && info != nullptr) {
+			severity = info->nAlarmLevel;
+		}
+		if (severity < 0) severity = 0; // fallback
+
+		std::string descText = desc;
+		if (descText.empty() && info != nullptr) {
+			descText = !info->strDescription.empty() ? info->strDescription : info->strAlarmText;
+		}
+		if (descText.empty()) {
+			descText = CToolUnits::formatString("Alarm %d", alarmId);
+		}
+
+		AlarmData alarmData;
+		alarmData.nId = alarmId;
+		alarmData.nSeverityLevel = severity;
+		alarmData.nDeviceId = deviceId;
+		alarmData.nUnitId = unitId;
+		alarmData.strDeviceName = deviceName;
+		alarmData.strUnitName = unitName;
+		alarmData.strStartTime = CToolUnits::timeToString2(CToolUnits::getTimestamp());
+		alarmData.strEndTime = "";
+		alarmData.strDescription = descText;
+
+		int nAlarmEventId = 0;
+		return alarmManager.addAlarm(alarmData, nAlarmEventId);
+	}
+
+	void CMaster::handleCollectionEvent(uint32_t ceid)
+	{
+		// 閬嶅巻褰撳墠 PJ锛屽懡涓� pauseEvents 鏃跺彲鍦ㄦ鎵╁睍鏆傚仠鍔ㄤ綔
+		bool pausedAny = false;
+		for (auto pj : m_processJobs) {
+			if (pj == nullptr) continue;
+			const auto& pauseList = pj->pauseEvents();
+			if (std::find(pauseList.begin(), pauseList.end(), ceid) != pauseList.end()) {
+				LOGW("<Master>PauseEvent hit: CEID=%u, PJ=%s, state=%d", ceid, pj->id().c_str(), (int)pj->state());
+				if (pj->pause()) {
+					LOGI("<Master>PJ paused by CEID=%u", ceid);
+					pausedAny = true;
+				}
+				if (m_pControlJob != nullptr && m_pControlJob->state() == CJState::Executing) {
+					if (m_pControlJob->pause()) {
+						LOGI("<Master>ControlJob paused by CEID=%u", ceid);
+						pausedAny = true;
+					}
+				}
+			}
+		}
+		if (pausedAny && m_listener.onControlJobChanged) {
+			// 閫氱煡搴旂敤灞傚埛鏂� UI/鎸夐挳鐘舵��
+			notifyControlJobChanged();
+		}
+		if (pausedAny && !m_bPauseAlarmRaised) {
+			std::string desc = CToolUnits::formatString("<PauseEvent CEID=%u>", ceid);
+			bool raised = false;
+			if (m_pModelCtx != nullptr) {
+				raised = m_pModelCtx->raiseSoftAlarm(ALID_SOFTWARE_PAUSE_EVENT, desc);
+			}
+			else {
+				raised = raiseSoftAlarm(ALID_SOFTWARE_PAUSE_EVENT, desc);
+			}
+			if (raised) {
+				LOGI("<Master>PauseEvent soft alarm raised, CEID=%u", ceid);
+				m_bPauseAlarmRaised = true;
+			}
+		}
+	}
+
+	void CMaster::setAllowedCeids(const std::vector<unsigned int>& ceids)
+	{
+		m_allowedCeids.clear();
+		m_allowedCeids.reserve(ceids.size());
+		for (auto id : ceids) {
+			m_allowedCeids.insert(id);
+		}
 	}
 
 	bool CMaster::saveState() const
@@ -3263,7 +3419,7 @@
 
 		saveState();
 		if (m_listener.onControlJobChanged) {
-			m_listener.onControlJobChanged(this);
+			notifyControlJobChanged();
 		}
 
 		return true;
@@ -3300,7 +3456,7 @@
 
 		saveState();
 		if (m_listener.onControlJobChanged) {
-			m_listener.onControlJobChanged(this);
+			notifyControlJobChanged();
 		}
 
 		return true;

--
Gitblit v1.9.3