mrDarker
2025-05-06 cacea2da59a3acd73f3161d819a10e0060762616
SourceCode/Bond/Servo/CRecipesManager.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,187 @@
#include "stdafx.h"
#include "CRecipesManager.h"
#include "ToolUnits.h"
#include "Common.h"
namespace SERVO {
   unsigned __stdcall TimeoutCheckWorkThreadFunction(LPVOID lpParam)
   {
      CRecipesManager* pRecipesManager = (CRecipesManager*)lpParam;
      return pRecipesManager->TimeoutCheckWorkingProc();
   }
   CRecipesManager::CRecipesManager()
   {
      m_nSyncStatus = SS_NONE;
      m_nTotalMasterRecipeCount = 0;
      m_nWordThreadAddr = 0;
      m_hWorkStop = nullptr;
      m_hWorkThreadHandle = nullptr;
      m_nTimeoutCount = 0;
      ::InitializeCriticalSection(&m_cs);
   }
   CRecipesManager::~CRecipesManager()
   {
      // ç­‰å¾…超时检测线程退出
      if (m_hWorkStop != nullptr) {
         SetEvent(m_hWorkStop);
         if (m_hWorkThreadHandle != NULL) {
            WaitForSingleObject(m_hWorkThreadHandle, INFINITE);
            CloseHandle(m_hWorkThreadHandle);
            m_hWorkThreadHandle = NULL;
         }
         CloseHandle(m_hWorkStop);
         m_hWorkStop = NULL;
      }
      // æ¸…理数据
      lock();
      for (auto item : m_mapRecipes) {
         delete item.second;
      }
      for (auto item : m_mapRecipesTemp) {
         delete item.second;
      }
      unlock();
      ::DeleteCriticalSection(&m_cs);
   }
   int CRecipesManager::syncing()
   {
      lock();
      if (m_nSyncStatus == SS_SYNCING) {
         unlock();
         return -1;
      }
      m_nSyncStatus = SS_SYNCING;
      m_nTimeoutCount = 0;
      unlock();
      if (m_hWorkStop == nullptr) {
         m_hWorkStop = ::CreateEvent(NULL, TRUE, FALSE, NULL);
         m_hWorkThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::TimeoutCheckWorkThreadFunction, this,
            0, &m_nWordThreadAddr);
      }
      return 0;
   }
   void CRecipesManager::syncFailed()
   {
      lock();
      m_nSyncStatus = SS_FAILED;
      m_nTimeoutCount = 0;
      unlock();
   }
   short CRecipesManager::decodeRecipeListReport(const char* pszData, size_t size)
   {
      int index = 0;
      int unitNo, reportType, totalMasterRecipeCount;
      int toatlGroupCount, currentGroupCount;
      const char* pszIdsData;
      unitNo = CToolUnits::toInt16(&pszData[index]);
      index += 2;
      pszIdsData = &pszData[index];
      index += (250 * 2);
      reportType = CToolUnits::toInt16(&pszData[index]);
      index += 2;
      totalMasterRecipeCount = CToolUnits::toInt16(&pszData[index]);
      index += 2;
      toatlGroupCount = CToolUnits::toInt16(&pszData[index]);
      index += 2;
      lock();
      if (m_nTotalMasterRecipeCount == 0) m_nTotalMasterRecipeCount = toatlGroupCount;
      if (m_nTotalMasterRecipeCount != toatlGroupCount) {
         return MRLRC_MASTER_RECIPE_LIST_COUNT_NG;
      }
      m_nTimeoutCount = 0;
      unlock();
      currentGroupCount = CToolUnits::toInt16(&pszData[index]);
      index += 2;
      // æ‰¾åˆ°å¯¹åº”CRecipeList, æ‰¾ä¸åˆ°åˆ™æ–°å»º
      lock();
      CRecipeList* pRecipeList = getRecipeListFromTemp(unitNo);
      if (pRecipeList == nullptr) {
         pRecipeList = new CRecipeList(unitNo);
         m_mapRecipesTemp[unitNo] = pRecipeList;
      }
      unlock();
      ASSERT(pRecipeList);
      // è¿™é‡Œæš‚时只处理reportType=4,即Request from EAS
      if (reportType == 4) {
         int nRet = pRecipeList->addRecipePacket(toatlGroupCount, currentGroupCount, pszIdsData, 250 * 2);
         if (MRLRC_CURRENT_RECIPE_COMPLETE == nRet) {
            lock();
            if (m_nTotalMasterRecipeCount == m_mapRecipesTemp.size()) {
               for (auto item : m_mapRecipes) {
                  delete item.second;
               }
               m_mapRecipes = m_mapRecipesTemp;
               m_mapRecipesTemp.clear();
               m_nSyncStatus = SS_COMPLETE;
               unlock();
               return MRLRC_OK;
            }
            unlock();
         }
         else if (MRLRC_CONTINUE == nRet) {
            return MRLRC_CONTINUE;
         }
      }
      return MRLRC_OK;
   }
   CRecipeList* CRecipesManager::getRecipeListFromTemp(int unitNo)
   {
      auto iter = m_mapRecipesTemp.find(unitNo);
      if (iter == m_mapRecipesTemp.end()) return nullptr;
      return iter->second;
   }
   unsigned CRecipesManager::TimeoutCheckWorkingProc()
   {
      while (1) {
         int nRet = WaitForSingleObject(m_hWorkStop, 1000);
         if (nRet == WAIT_OBJECT_0) {
            ResetEvent(m_hWorkStop);
            break;
         }
         lock();
         if (m_nSyncStatus == SS_SYNCING) {
            m_nTimeoutCount++;
            if (m_nTimeoutCount > 10) {
               m_nSyncStatus = SS_TIMEOUT;
               unlock();
               TRACE("CRecipesManager::TimeoutCheckWorkingProc è¶…时退出\n");
            }
         }
         unlock();
      }
      // _endthreadex(0);
      TRACE("CRecipesManager::TimeoutCheckWorkingProc çº¿ç¨‹é€€å‡º\n");
      return 0;
   }
}