#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);
|
}
|
}
|
|
void CRecipesManager::syncTimeout()
|
{
|
lock();
|
m_nSyncStatus = SS_TIMEOUT;
|
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(totalMasterRecipeCount, 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_LIST_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, ÕÒ²»µ½Ôò·µ»ØNG
|
lock();
|
CRecipeList* pRecipeList = getRecipeListFromTemp(unitNo);
|
if (pRecipeList == nullptr) {
|
unlock();
|
return MRLRC_NG;
|
}
|
unlock();
|
|
/*
|
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->addParamsPacket(totalParameterCount, toatlGroupCount, currentGroupCount,
|
unitNo, localRecipeId,
|
pszParameterData, 250 * 2);
|
if (MRLRC_CURRENT_RECIPE_COMPLETE == nRet) {
|
lock();
|
m_nSyncStatus = SS_PARAMS_COMPLETE;
|
unlock();
|
return MRLRC_OK;
|
}
|
|
return nRet;
|
}
|
|
|
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) {
|
unlock();
|
syncTimeout();
|
TRACE("CRecipesManager::TimeoutCheckWorkingProc ³¬Ê±Í˳ö\n");
|
lock();
|
}
|
}
|
|
unlock();
|
}
|
|
// _endthreadex(0);
|
TRACE("CRecipesManager::TimeoutCheckWorkingProc Ïß³ÌÍ˳ö\n");
|
return 0;
|
}
|
|
}
|