mrDarker
2025-07-23 5a66d26a2899a2450a50f00d09c728ae151715be
SourceCode/Bond/Servo/CLoadPort.cpp
@@ -16,6 +16,7 @@
      m_bEnable = FALSE;
      m_bAutoChangeEnable = FALSE;
      m_nNextCassetteSequenceNo = 0;
      m_isCompareMapsBeforeProceeding = FALSE;
   }
   CLoadPort::~CLoadPort()
@@ -134,7 +135,7 @@
         CEqReadStep* pStep = new CEqReadStep(dev[m_nIndex], sizeof(short),
            [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
               if (code == ROK && pszData != nullptr && size > 0) {
                  m_cassetteType = (CassetteType)CToolUnits::toInt16(pszData);
                  //m_cassetteType = (CassetteType)CToolUnits::toInt16(pszData);
               }
               return 0;
            });
@@ -347,6 +348,23 @@
   void CLoadPort::onTimer(UINT nTimerid)
   {
      CEquipment::onTimer(nTimerid);
      // 模拟测试
      /*
      if (m_nIndex == 0) {
         static int ii = 0;
         ii++;
         if (ii == 20) {
            char szBuffer[64];
            CStep* pStep = getStepWithName(STEP_EQ_PORT1_INUSE);
            CPortStatusReport portStatusReport;
            portStatusReport.setPortStatus(PORT_INUSE);
            portStatusReport.setJobExistenceSlot(0xf);
            int nRet = portStatusReport.serialize(szBuffer, 64);
            decodePortStatusReport(pStep, szBuffer, 64);
         }
      }
      */
   }
   void CLoadPort::serialize(CArchive& ar)
@@ -887,17 +905,27 @@
      // 当port状态为InUse, 比较map
      if (m_portStatusReport.getPortStatus() == PORT_INUSE) {
         short scanMap = m_portStatusReport.getJobExistenceSlot();
         short downMap = getCassetteMap();
         if (scanMap == downMap) {
            this->sendCassetteCtrlCmd(5, nullptr, 0, 0, 0, nullptr, nullptr);
         if (m_isCompareMapsBeforeProceeding) {
            short scanMap = getScanCassetteMap();
            short downloadMap = getDownloadCassetteMap();
            if (scanMap == downloadMap) {
               generateGlassList(scanMap);
               this->sendCassetteCtrlCmd(CCC_PROCESS_START, nullptr, 0, 0, 0, nullptr, nullptr);
            }
            else {
               this->sendCassetteCtrlCmd(CCC_PROCESS_CANCEL, nullptr, 0, 0, 0, nullptr, nullptr);
               // 抛出到应用层做提示
               if (m_listener.onMapMismatch != nullptr) {
                  m_listener.onMapMismatch(this, scanMap, downloadMap);
               }
            }
         }
         else {
            this->sendCassetteCtrlCmd(10, nullptr, 0, 0, 0, nullptr, nullptr);
            // 抛出到应用层做提示
            if (m_listener.onMapMismatch != nullptr) {
               m_listener.onMapMismatch(this, scanMap, downMap);
            // 抛出到应用层做选择要加工的片子
            generateGlassList(getScanCassetteMap());
            if (m_listener.onPortInUse != nullptr) {
               m_listener.onPortInUse(this, getScanCassetteMap());
            }
         }
      }
@@ -1011,6 +1039,7 @@
   int CLoadPort::setCassetteType(CassetteType type, ONWRITED onWritedBlock/* = nullptr*/)
   {
      m_cassetteType = type;
      static char* pszName[] = { STEP_PORT1_CASSETTE_TYPE_CHANGE, STEP_PORT2_CASSETTE_TYPE_CHANGE, STEP_PORT3_CASSETTE_TYPE_CHANGE, STEP_PORT4_CASSETTE_TYPE_CHANGE };
      SERVO::CEqWriteStep* pStep = (SERVO::CEqWriteStep*)getStepWithName(pszName[m_nIndex]);
      if (pStep == nullptr) {
@@ -1023,7 +1052,6 @@
         // test
         code = WOK;
         if (code == WOK) {
            m_cassetteType = type;
            LOGI("<CLoadPort-%d>设置Cassette Type成功.", m_nIndex);
         }
         else {
@@ -1126,15 +1154,15 @@
      m_bAutoChangeEnable = bEnable;
   }
   short CLoadPort::getCassetteMap()
   short CLoadPort::getScanCassetteMap()
   {
      short map = 0;
      for (int i = 0; i < SLOT_MAX; i++) {
         if (!m_slot[i].isEnable()) continue;
         if (m_slot[i].getContext() == nullptr) continue;
         map |= (1 << i);
      }
      return m_portStatusReport.getJobExistenceSlot();
   }
   short CLoadPort::getDownloadCassetteMap()
   {
      // 暂时未实现此功能
      short map = 0;
      return map;
   }
@@ -1176,6 +1204,47 @@
      return 0;
   }
   /*
    * 根据efem扫描到的map,生成玻璃列表
    */
   int CLoadPort::generateGlassList(short map)
   {
      // 先释放较早前的数据
      Lock();
      for (int i = 0; i < SLOT_MAX; i++) {
         m_slot[i].setContext(nullptr);
      }
      Unlock();
      // 根据map生成新的
      char szBuffer[64];
      for (int i = 0; i < SLOT_MAX; i++) {
         if (!m_slot[i].isEnable()) continue;
         if (!(map >> i) & 1) continue;
         CJobDataS js;
         js.setCassetteSequenceNo(getNextCassetteSequenceNo());
         js.setJobSequenceNo(m_slot[i].getNo());
         sprintf_s(szBuffer, 64, "%05d%05d", js.getCassetteSequenceNo(), js.getJobSequenceNo());
         js.setJobType(1);
         js.setMaterialsType((int)m_cassetteType);
         CGlass* pGlass = theApp.m_model.m_glassPool.allocaGlass();
         pGlass->setOriginPort(m_nIndex, i);
         pGlass->setScheduledForProcessing(i % 2 == 1);
         pGlass->addPath(m_nID, 0);
         pGlass->processEnd(m_nID, 0);
         pGlass->setID(szBuffer);
         pGlass->setType(m_cassetteType);
         pGlass->setJobDataS(&js);
         m_slot[i].setContext(pGlass);
      }
      return 0;
   }
   int CLoadPort::testGenerateGlassListFromConfig(const SERVO::PortConfig& config)
   {
      char szBuffer[64];
@@ -1215,4 +1284,9 @@
      return 0;
   }
   void CLoadPort::setCompareMapsBeforeProceeding(BOOL bCompare)
   {
      m_isCompareMapsBeforeProceeding = bCompare;
   }
}