From 1f5f8a22e9c584f709d4b34d2e4d24eaad2d5544 Mon Sep 17 00:00:00 2001
From: LAPTOP-SNT8I5JK\Boounion <Chenluhua@qq.com>
Date: 星期六, 24 五月 2025 15:11:56 +0800
Subject: [PATCH] 1.test

---
 SourceCode/Bond/Servo/CEquipment.cpp |  427 ++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 389 insertions(+), 38 deletions(-)

diff --git a/SourceCode/Bond/Servo/CEquipment.cpp b/SourceCode/Bond/Servo/CEquipment.cpp
index 0bf4132..e4d8c07 100644
--- a/SourceCode/Bond/Servo/CEquipment.cpp
+++ b/SourceCode/Bond/Servo/CEquipment.cpp
@@ -3,6 +3,8 @@
 #include "ToolUnits.h"
 #include <regex>
 #include "CArm.h"
+#include "CGlassPool.h"
+#include "Servo.h"
 
 
 #define CHECK_READ_STEP_SIGNAL(addr, data, size) {							\
@@ -83,6 +85,11 @@
 		ASSERT(pEquipment->isArm());
 		ASSERT(!this->isArm());
 		m_pArm = pEquipment;
+	}
+
+	CEquipment* CEquipment::getArm()
+	{
+		return m_pArm;
 	}
 
 	void CEquipment::setBaseAlarmId(int nBaseId)
@@ -306,13 +313,28 @@
 			Unlock();
 		}
 		else {
-			Lock();
+			// addGlassToList前不需要上锁,因其内部有锁
 			int count;
 			ar >> count;
 			for (int i = 0; i < count; i++) {
-				CGlass* pGlass = new CGlass();
+				CGlass* pGlass = theApp.m_model.m_glassPool.allocaGlass();
 				pGlass->serialize(ar);
 				addGlassToList(pGlass);
+			}
+			
+			// 梳理各玻璃之间的绑定关系
+			Lock();
+			std::list<CGlass*> list = m_glassList;
+			for (auto item : list) {
+				std::string& strBuddyId = item->getBuddyId();
+				if (!strBuddyId.empty()) {
+					for (auto item2 : m_glassList) {
+						if (strBuddyId.compare(item2->getID()) == 0) {
+							item->setBuddy(item2);
+							TRACE("绑定关系: %s <- %s\n", item->getID().c_str(), item2->getID().c_str());
+						}
+					}
+				}
 			}
 			Unlock();
 		}
@@ -471,30 +493,30 @@
 
 
 		// CEqCassetteTranserStateStep
-		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT1_CASSETTIE_EMPTY, pszData, size);
-		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT1_CASSETTIE_LOAD_READY, pszData, size);
-		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT1_CASSETTIE_LOADED, pszData, size);
-		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT1_CASSETTIE_INUSE, pszData, size);
-		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT1_CASSETTIE_UNLOAD_READY, pszData, size);
-		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT1_CASSETTIE_BLOCKED, pszData, size);
-		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT2_CASSETTIE_EMPTY, pszData, size);
-		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT2_CASSETTIE_LOAD_READY, pszData, size);
-		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT2_CASSETTIE_LOADED, pszData, size);
-		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT2_CASSETTIE_INUSE, pszData, size);
-		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT2_CASSETTIE_UNLOAD_READY, pszData, size);
-		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT2_CASSETTIE_BLOCKED, pszData, size);
-		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT3_CASSETTIE_EMPTY, pszData, size);
-		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT3_CASSETTIE_LOAD_READY, pszData, size);
-		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT3_CASSETTIE_LOADED, pszData, size);
-		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT3_CASSETTIE_INUSE, pszData, size);
-		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT3_CASSETTIE_UNLOAD_READY, pszData, size);
-		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT3_CASSETTIE_BLOCKED, pszData, size);
-		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT4_CASSETTIE_EMPTY, pszData, size);
-		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT4_CASSETTIE_LOAD_READY, pszData, size);
-		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT4_CASSETTIE_LOADED, pszData, size);
-		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT4_CASSETTIE_INUSE, pszData, size);
-		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT4_CASSETTIE_UNLOAD_READY, pszData, size);
-		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT4_CASSETTIE_BLOCKED, pszData, size);
+		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT1_EMPTY, pszData, size);
+		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT1_LOAD_READY, pszData, size);
+		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT1_LOADED, pszData, size);
+		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT1_INUSE, pszData, size);
+		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT1_UNLOAD_READY, pszData, size);
+		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT1_BLOCKED, pszData, size);
+		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT2_EMPTY, pszData, size);
+		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT2_LOAD_READY, pszData, size);
+		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT2_LOADED, pszData, size);
+		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT2_INUSE, pszData, size);
+		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT2_UNLOAD_READY, pszData, size);
+		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT2_BLOCKED, pszData, size);
+		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT3_EMPTY, pszData, size);
+		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT3_LOAD_READY, pszData, size);
+		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT3_LOADED, pszData, size);
+		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT3_INUSE, pszData, size);
+		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT3_UNLOAD_READY, pszData, size);
+		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT3_BLOCKED, pszData, size);
+		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT4_EMPTY, pszData, size);
+		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT4_LOAD_READY, pszData, size);
+		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT4_LOADED, pszData, size);
+		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT4_INUSE, pszData, size);
+		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT4_UNLOAD_READY, pszData, size);
+		CHECK_READ_STEP_SIGNAL(STEP_ID_PORT4_BLOCKED, pszData, size);
 	}
 
 	BOOL CEquipment::isBitOn(const char* pszData, size_t size, int index)
@@ -573,6 +595,7 @@
 				panelNo = (value & 0xffff);
 				LOGI("Cim Message Confirm(msgID = %d, panel no.=%d).", msgId, panelNo);
 			}
+			/*
 			else if (isVcrEventStep(pStep)) {
 				SERVO::CEqVcrEventStep* pEqVcrEventStep = (SERVO::CEqVcrEventStep*)pStep;
 				CVcrEventReport* pVcrEventReport = pEqVcrEventStep->getVcrEventReport();
@@ -585,6 +608,7 @@
 				pEqVcrEventStep->setReturnCode(1);		
 				return 1;
 			}
+			*/
 		}
 
 
@@ -781,6 +805,21 @@
 		}
 	}
 
+	CGlass* CEquipment::getGlassFromList(const char* pszId)
+	{
+		CGlass* pGlass = nullptr;
+		Lock();
+		for (auto item : m_glassList) {
+			if (item->getID().compare(pszId) == 0) {
+				pGlass = item;
+				break;
+			}
+		}
+		Unlock();
+
+		return pGlass;
+	}
+
 	BOOL CEquipment::removeClass(CGlass* pGlass)
 	{
 		Lock();
@@ -822,7 +861,7 @@
 		return pGlass;
 	}
 
-	int CEquipment::fetchedOut(const char* pszGlassId)
+	int CEquipment::fetchedOutJob(CJobDataB* pJobDataB)
 	{
 		if (m_pArm == nullptr) {
 			return -1;
@@ -837,7 +876,7 @@
 
 		CGlass* pContext = nullptr;
 		for (auto iter = m_glassList.begin(); iter != m_glassList.end(); iter++) {
-			if ((*iter)->getID().compare(pszGlassId) == 0) {
+			if ((*iter)->getID().compare(pJobDataB->getGlassId()) == 0) {
 				pContext = (*iter);
 				m_glassList.erase(iter);
 				break;
@@ -847,6 +886,19 @@
 			Unlock();
 			return -3;
 		}
+
+		// 如果此玻璃已经贴合,贴合的玻璃也要从列表中移除
+		CGlass* pBuddy = pContext->getBuddy();
+		if (pBuddy != nullptr) {
+			for (auto iter = m_glassList.begin(); iter != m_glassList.end(); iter++) {
+				if ((*iter)->getID().compare(pBuddy->getID()) == 0) {
+					(*iter)->release();
+					m_glassList.erase(iter);
+					break;
+				}
+			}
+		}
+
 
 		((CArm*)m_pArm)->tempStore(pContext);
 		pContext->release();
@@ -859,7 +911,7 @@
 		return 0;
 	}
 
-	int CEquipment::storedJob(const char* pszGlassId)
+	int CEquipment::storedJob(CJobDataB* pJobDataB)
 	{
 		if (m_pArm == nullptr) {
 			return -1;
@@ -878,6 +930,18 @@
 		m_glassList.push_back(pGlass);
 		pGlass->release();				// tempFetchOut需要调用一次release
 		Unlock();
+
+
+		// 如果此玻璃已经贴合,贴合的玻璃也要从加入到列表中
+		CGlass* pBuddy = pGlass->getBuddy();
+		if (pBuddy != nullptr) {
+			Lock();
+			pBuddy->addPath(m_nID);
+			pBuddy->addRef();					// 加入list,addRef
+			m_glassList.push_back(pBuddy);
+			Unlock();
+		}
+
 
 		if (m_listener.onDataChanged != nullptr) {
 			m_listener.onDataChanged(this, 0);
@@ -1001,6 +1065,61 @@
 		return pStep->setDateTime(year, month, day, hour, minute, second);
 	}
 
+	int CEquipment::setDispatchingMode(DISPATCHING_MODE mode, ONWRITED onWritedBlock/* = nullptr*/)
+	{
+		SERVO::CEqWriteStep* pStep = (SERVO::CEqWriteStep*)getStepWithName(STEP_EQ_DISPATCHINT_MODE_CHANGE);
+		if (pStep == nullptr) {
+			return -1;
+		}
+
+		LOGI("<CEquipment-%s>准备设置DispatchingMode<%d>", m_strName.c_str(), (int)mode);
+		if (onWritedBlock != nullptr) {
+			pStep->writeShort((short)mode, onWritedBlock);
+		}
+		else {
+			pStep->writeShort((short)mode, [&, mode](int code) -> int {
+				if (code == WOK) {
+					LOGI("<CEquipment-%s>设置DispatchingMode成功.", m_strName.c_str());
+				}
+				else {
+					LOGI("<CEquipment-%s>设置DispatchingMode失败,code:%d", m_strName.c_str(), code);
+				}
+
+				return 0;
+				});
+		}
+
+		return 0;
+	}
+
+	int CEquipment::indexerOperationModeChange(IDNEXER_OPERATION_MODE mode, ONWRITED onWritedBlock/* = nullptr*/)
+	{
+		SERVO::CEqWriteStep* pStep = (SERVO::CEqWriteStep*)getStepWithName(STEP_EFEM_IN_OP_MODE_CHANGE);
+		if (pStep == nullptr) {
+			return -1;
+		}
+
+		unsigned short operationMode = (unsigned short)(mode + getIndexerOperationModeBaseValue());
+		LOGI("<CEquipment-%s>准备设置indexerOperationMode<%d>", m_strName.c_str(), (int)mode);
+		if (onWritedBlock != nullptr) {
+			pStep->writeShort(operationMode, onWritedBlock);
+		}
+		else {
+			pStep->writeShort(operationMode, [&, mode](int code) -> int {
+				if (code == WOK) {
+					LOGI("<CEquipment-%s>设置indexerOperationMode成功.", m_strName.c_str());
+				}
+				else {
+					LOGI("<CEquipment-%s>设置indexerOperationMode失败,code:%d", m_strName.c_str(), code);
+				}
+
+				return 0;
+				});
+		}
+
+		return 0;
+	}
+
 	int CEquipment::masterRecipeListRequest(short unitNo)
 	{
 		SERVO::CEqWriteStep* pStep = (SERVO::CEqWriteStep*)getStepWithName(STEP_EQ_MASTER_RECIPE_LIST_REQ);
@@ -1061,6 +1180,83 @@
 		return m_recipesManager.decodeRecipeParameterReport(pszData, size);
 	}
 
+	int CEquipment::decodeProcessDataReport(CStep* pStep, const char* pszData, size_t size)
+	{
+		CProcessData processData;
+		int nRet = processData.unserialize(&pszData[0], (int)size);
+		if (nRet < 0) return nRet;
+
+		// 缓存Attribute,用于调试时显示信息
+		unsigned int weight = 201;
+		CAttributeVector attrubutes;
+		processData.getAttributeVector(attrubutes, weight);
+		pStep->addAttributeVector(attrubutes);
+
+
+		onProcessData(&processData);
+
+		return nRet;
+	}
+
+	int CEquipment::decodeReceivedJobReport(CStep* pStep, int port, const char* pszData, size_t size)
+	{
+		CJobDataS jobDataS;
+		int nRet = jobDataS.unserialize(&pszData[0], (int)size);
+		if (nRet < 0) return nRet;
+
+		// 缓存Attribute,用于调试时显示信息
+		unsigned int weight = 201;
+		CAttributeVector attrubutes;
+		jobDataS.getAttributeVector(attrubutes, weight);
+		pStep->addAttributeVector(attrubutes);
+
+
+		onReceivedJob(port, &jobDataS);
+
+		return nRet;
+	}
+
+	int CEquipment::onReceivedJob(int port, CJobDataS* pJobDataS)
+	{
+		LOGI("<CEquipment-%s>onReceivedJob.", m_strName.c_str());
+
+		addJobDataS(pJobDataS);
+		return 0;
+	}
+
+	int CEquipment::decodeSentOutJobReport(CStep* pStep, int port, const char* pszData, size_t size)
+	{
+		CJobDataS jobDataS;
+		int nRet = jobDataS.unserialize(&pszData[0], (int)size);
+		if (nRet < 0) return nRet;
+
+		// 缓存Attribute,用于调试时显示信息
+		unsigned int weight = 201;
+		CAttributeVector attrubutes;
+		jobDataS.getAttributeVector(attrubutes, weight);
+		pStep->addAttributeVector(attrubutes);
+
+
+		onReceivedJob(port, &jobDataS);
+
+		return nRet;
+	}
+
+	int CEquipment::onSentOutJob(int port, CJobDataS* pJobDataS)
+	{
+		LOGI("<CEquipment-%s>onSentOutJob.", m_strName.c_str());
+
+		int count = removeJobDataS(pJobDataS->getCassetteSequenceNo(), pJobDataS->getJobSequenceNo());
+		if (count == 1) {
+			LOGI("<CEquipment-%s>onSentOutJob,删除数据 %d 条", m_strName.c_str(), count);
+		}
+		else {
+			LOGE("<CEquipment-%s>onSentOutJob,删除数据 %d 条,注意排查风险", m_strName.c_str(), count);
+		}
+
+		return 0;
+	}
+
 	int CEquipment::decodeFetchedOutJobReport(CStep* pStep, int port, const char* pszData, size_t size)
 	{
 		int index = 0;
@@ -1098,16 +1294,32 @@
 			jobDataB.getGlassId().c_str(), "", weight++));
 
 
-		onFetchedOut(port, jobDataB.getGlassId().c_str());
+		onFetchedOutJob(port, &jobDataB);
 
 		return index;
 	}
 
-	int CEquipment::onFetchedOut(int port, const char* pszGlassId)
+	int CEquipment::onPreFetchedOutJob(int port, CJobDataB* pJobDataB)
 	{
-		LOGI("<CEquipment-%s>onFetchedOut:port:%d|GlassId:%s", 
-			m_strName.c_str(), port, pszGlassId);
-		return fetchedOut(pszGlassId);
+		LOGI("<CEquipment-%s>onPreFetchedOutJob:port:%d|GlassId:%s",
+			m_strName.c_str(), port, pJobDataB->getGlassId().c_str());
+		return TRUE;
+	}
+
+	int CEquipment::onFetchedOutJob(int port, CJobDataB* pJobDataB)
+	{
+		LOGI("<CEquipment-%s>onFetchedOutJob:port:%d|GlassId:%s", 
+			m_strName.c_str(), port, pJobDataB->getGlassId().c_str());
+
+		BOOL bCheck = onPreFetchedOutJob(port, pJobDataB);
+		if (bCheck) {
+			return fetchedOutJob(pJobDataB);
+		}
+
+		// 数据异常,处理或显示
+		LOGI("<CEquipment-%s>onFetchedOutJob Error.ort:%d|GlassId:%s",
+			m_strName.c_str(), port, pJobDataB->getGlassId().c_str());
+		return -1;
 	}
 
 	int CEquipment::decodeStoredJobReport(CStep* pStep, int port, const char* pszData, size_t size)
@@ -1147,15 +1359,154 @@
 			jobDataB.getGlassId().c_str(), "", weight++));
 
 
-		onStore(port, jobDataB.getGlassId().c_str());
+		onStoredJob(port, &jobDataB);
 
 		return index;
 	}
 
-	int CEquipment::onStore(int port, const char* pszGlassId)
+	int CEquipment::decodeVCREventReport(CStep* pStep, const char* pszData, size_t size)
+	{
+		CVcrEventReport vcrEventReport;
+		vcrEventReport.unserialize(pszData, size);
+		LOGI("<CEquipment-%s>decodeVCREventReport<Result:%d, GlassId:%s>\n", m_strName.c_str(),
+			vcrEventReport.getVcrResult(),
+			vcrEventReport.getGlassId().c_str());
+
+
+		// 缓存Attribute,用于调试时显示信息
+		unsigned int weight = 201;
+		CAttributeVector attrubutes;
+		vcrEventReport.getAttributeVector(attrubutes, weight);
+		pStep->addAttributeVector(attrubutes);
+
+		// 0426, 先固定返回1(OK)
+		((CReadStep*)pStep)->setReturnCode((short)VCR_Reply_Code::OK);
+
+		return 0;
+	}
+
+	int CEquipment::onPreStoredJob(int port, CJobDataB* pJobDataB)
+	{
+		LOGI("<CEquipment-%s>onPreStoredJob:port:%d|GlassId:%s",
+			m_strName.c_str(), port, pJobDataB->getGlassId().c_str());
+		return TRUE;
+	}
+
+	int CEquipment::onStoredJob(int port, CJobDataB* pJobDataB)
 	{
 		LOGI("<CEquipment-%s>onStore:port:%d|GlassId:%s",
-			m_strName.c_str(), port, pszGlassId);
-		return storedJob(pszGlassId);
+			m_strName.c_str(), port, pJobDataB->getGlassId().c_str());
+
+		BOOL bCheck = onPreStoredJob(port, pJobDataB);
+		if (bCheck) {
+			addJobDataB(pJobDataB);
+			return storedJob(pJobDataB);
+		}
+
+		// 数据异常,处理或显示
+		LOGI("<CEquipment-%s>onStoredJob Error.ort:%d|GlassId:%s",
+			m_strName.c_str(), port, pJobDataB->getGlassId().c_str());
+		return -1;
+	}
+
+	int CEquipment::onProcessData(CProcessData* pProcessData)
+	{
+		LOGI("<CEquipment-%s>onProcessData.", m_strName.c_str());
+		return 0;
+	}
+
+	int CEquipment::getIndexerOperationModeBaseValue()
+	{
+		return 0;
+	}
+
+	int CEquipment::addJobDataB(CJobDataB* pJobDataB)
+	{
+		// 添加之前先删除旧的,以免数据重复
+		Lock();
+		int count = removeJobDataB(pJobDataB->getCassetteSequenceNo(), pJobDataB->getJobSequenceNo());
+		if (count > 0) {
+			LOGE("<CEquipment-%s>addJobDataB,删除重复数据 %d 条,注意排查风险", m_strName.c_str(), count);
+		}
+
+		m_listJobDataB.push_back(std::move(*pJobDataB));
+		Unlock();
+
+		return (int)m_listJobDataB.size();
+	}
+
+	int CEquipment::removeJobDataB(int nCassetteSequenceNo, int nJobSequenceNo)
+	{
+		int count = 0;
+		for (auto it = m_listJobDataB.begin(); it != m_listJobDataB.end(); ) {
+			if ((*it).getCassetteSequenceNo() == nCassetteSequenceNo
+				&& (*it).getJobSequenceNo() == nJobSequenceNo) {
+				it = m_listJobDataB.erase(it);
+				count++;
+			}
+			else {
+				++it;
+			}
+		}
+
+		return count;
+	}
+
+	CJobDataB* CEquipment::getJobDataB(int nCassetteSequenceNo, int nJobSequenceNo)
+	{
+		for (auto& item : m_listJobDataB) {
+			if (item.getCassetteSequenceNo() == nCassetteSequenceNo
+				&& item.getJobSequenceNo() == nJobSequenceNo) {
+				return &item;
+			}
+		}
+
+		return nullptr;
+	}
+
+	int CEquipment::addJobDataS(CJobDataS* pJobDataS)
+	{
+		// 添加之前先删除旧的,以免数据重复
+		Lock();
+		int count = removeJobDataS(pJobDataS->getCassetteSequenceNo(), pJobDataS->getJobSequenceNo());
+		if (count > 0) {
+			LOGE("<CEquipment-%s>addJobDataS,删除重复数据 %d 条,注意排查风险", m_strName.c_str(), count);
+		}
+
+		m_listJobDataS.push_back(std::move(*pJobDataS));
+		Unlock();
+
+		return (int)m_listJobDataB.size();
+	}
+
+	int CEquipment::removeJobDataS(int nCassetteSequenceNo, int nJobSequenceNo)
+	{
+		int count = 0;
+		Lock();
+		for (auto it = m_listJobDataS.begin(); it != m_listJobDataS.end(); ) {
+			if ((*it).getCassetteSequenceNo() == nCassetteSequenceNo
+				&& (*it).getJobSequenceNo() == nJobSequenceNo) {
+				it = m_listJobDataS.erase(it);
+				count++;
+			}
+			else {
+				++it;
+			}
+		}
+		Unlock();
+
+		return count;
+	}
+
+	CJobDataS* CEquipment::getJobDataS(int nCassetteSequenceNo, int nJobSequenceNo)
+	{
+		for (auto& item : m_listJobDataS) {
+			if (item.getCassetteSequenceNo() == nCassetteSequenceNo
+				&& item.getJobSequenceNo() == nJobSequenceNo) {
+				return &item;
+			}
+		}
+
+		return nullptr;
 	}
 }
\ No newline at end of file

--
Gitblit v1.9.3