#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_nTotalParameterCount = 0; m_nWordThreadAddr = 0; m_hWorkStop = nullptr; m_hWorkThreadHandle = nullptr; m_nTimeoutCount = 0; m_onSyncingStateChanged = nullptr; ::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_onSyncingStateChanged != nullptr) { m_onSyncingStateChanged(m_nSyncStatus); } 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(); if (m_onSyncingStateChanged != nullptr) { m_onSyncingStateChanged(m_nSyncStatus); } } 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); /* 1: Create 2: Modify 3: Delete 4: Request from EAS */ if (reportType == RT_CREATE) { } else if (reportType == RT_MODIFY) { } else if (reportType == RT_DELETE) { } else if (reportType == RT_REQUEST_FROM_EAS) { int nRet = pRecipeList->addRecipePacket(toatlGroupCount, currentGroupCount, pszIdsData, 250 * 2); if (MRLRC_CURRENT_RECIPE_COMPLETE == nRet) { lock(); for (auto item : m_mapRecipes) { delete item.second; } m_mapRecipes = m_mapRecipesTemp; m_mapRecipesTemp.clear(); m_nSyncStatus = SS_COMPLETE; unlock(); if (m_onSyncingStateChanged != nullptr) { m_onSyncingStateChanged(m_nSyncStatus); } return MRLRC_OK; } else if (MRLRC_CONTINUE == nRet) { return MRLRC_CONTINUE; } } return MRLRC_OK; } short CRecipesManager::decodeRecipeParameterReport(const char* pszData, size_t size) { int index = 0; int masterRecipeId, localRecipeId, unitNo, reportType; int totalParameterCount; int toatlGroupCount, currentGroupCount; const char* pszParameterData; masterRecipeId = CToolUnits::toInt16(&pszData[index]); index += 2; localRecipeId = CToolUnits::toInt16(&pszData[index]); index += 2; unitNo = CToolUnits::toInt16(&pszData[index]); index += 2; reportType = CToolUnits::toInt16(&pszData[index]); index += 2; totalParameterCount = CToolUnits::toInt16(&pszData[index]); index += 2; toatlGroupCount = CToolUnits::toInt16(&pszData[index]); index += 2; currentGroupCount = CToolUnits::toInt16(&pszData[index]); index += 2; pszParameterData = &pszData[index]; lock(); if (m_nTotalParameterCount == 0) m_nTotalParameterCount = toatlGroupCount; if (m_nTotalParameterCount != toatlGroupCount) { return MRLRC_MASTER_RECIPE_LIST_COUNT_NG; } m_nTimeoutCount = 0; unlock(); // ÕÒµ½¶ÔÓ¦CRecipeList, ÕÒ²»µ½Ôòн¨ /* lock(); CRecipeList* pRecipeList = getRecipeListFromTemp(unitNo); if (pRecipeList == nullptr) { pRecipeList = new CRecipeList(unitNo); m_mapRecipesTemp[unitNo] = pRecipeList; } unlock(); ASSERT(pRecipeList); */ /* 1: Create 2: Modify 3: Delete 4: Request from EAS */ /* if (reportType == RT_CREATE) { } else if (reportType == RT_MODIFY) { } else if (reportType == RT_DELETE) { } else if (reportType == RT_REQUEST_FROM_EAS) { 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; } CRecipeList* CRecipesManager::getRecipeList(int unitNo) { auto iter = m_mapRecipes.find(unitNo); if (iter == m_mapRecipes.end()) return nullptr; return iter->second; } void CRecipesManager::setOnSyncingStateChanged(ONSYNCINGSTATECHANGED block) { m_onSyncingStateChanged = block; } 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; } }