SourceCode/Bond/Servo/CStep.cpp
@@ -3,44 +3,17 @@
namespace SERVO {
#define TIMEOUT         15
   unsigned __stdcall StepWorkThreadFunction(LPVOID lpParam)
   {
      CStep* pStep = (CStep*)lpParam;
      return pStep->WorkingProc();
   }
   CStep::CStep()
   {
      m_listener = {nullptr};
      m_nWordThreadAddr = 0;
      m_hWorkStop = nullptr;
      m_hWorkThreadHandle = nullptr;
      m_hSignalOn = ::CreateEvent(NULL, TRUE, FALSE, NULL);
      m_hSignalOff = ::CreateEvent(NULL, TRUE, FALSE, NULL);
      m_nCurStep = 0;
      m_nID = 0;
      m_pCclink = nullptr;
      m_nWriteSignalDev = 0;
      InitializeCriticalSection(&m_criticalSection);
   }
   CStep::~CStep()
   {
      ASSERT(m_hSignalOn);
      CloseHandle(m_hSignalOn);
      m_hSignalOn = nullptr;
      ASSERT(m_hSignalOff);
      CloseHandle(m_hSignalOff);
      m_hSignalOff = nullptr;
      DeleteCriticalSection(&m_criticalSection);
   }
   void CStep::setListener(StepListener listener)
   {
      m_listener.onEvent = listener.onEvent;
   }
   void CStep::setCcLink(CCCLinkIEControl* pCcLink)
@@ -58,6 +31,16 @@
      return m_pEquipment;
   }
   void CStep::setID(int id)
   {
      m_nID = id;
   }
   int CStep::getID()
   {
      return m_nID;
   }
   void CStep::setName(const char* pszName)
   {
      m_strName = pszName;
@@ -68,142 +51,82 @@
      return m_strName;
   }
   void CStep::setWriteSignalDev(int dev)
   void CStep::getAttributeVector(CAttributeVector& attrubutes)
   {
      m_nWriteSignalDev = dev;
      unsigned int weight = 1;
      attrubutes.clear();
      attrubutes.addAttribute(new CAttribute("Network",
         std::to_string(m_station.nNetNo).c_str(), "", weight++));
      attrubutes.addAttribute(new CAttribute("Station",
         std::to_string(m_station.nStNo).c_str(), "", weight++));
      auto as = m_attributeVector.getAttributes();
      for (auto item : as) {
         attrubutes.addAttribute(new CAttribute(item->getName().c_str(),
            item->getValue().c_str(), item->getDescription().c_str(), item->getWeight()));
      }
   }
   CAttributeVector& CStep::attributeVector()
   {
      return m_attributeVector;
   }
   void CStep::init()
   {
      if (m_hWorkStop != nullptr) return;
      m_hWorkStop = ::CreateEvent(NULL, TRUE, FALSE, NULL);
      m_hWorkThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::StepWorkThreadFunction, this,
         0, &m_nWordThreadAddr);
   }
   void CStep::term()
   {
      ASSERT(m_hWorkStop);
      SetEvent(m_hWorkStop);
      if (m_hWorkThreadHandle != NULL) {
         WaitForSingleObject(m_hWorkThreadHandle, INFINITE);
         CloseHandle(m_hWorkThreadHandle);
         m_hWorkThreadHandle = NULL;
      }
      CloseHandle(m_hWorkStop);
      m_hWorkStop = NULL;
   }
   unsigned CStep::WorkingProc()
   void CStep::setProp(const char* pszKey, void* pValue)
   {
      HANDLE hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
      BOOL bReadOk = FALSE;
      m_mapProp[pszKey] = pValue;
   }
      int nBeginAddr = 0x0;
      while (1) {
RESET:
         resetStep();
   void* CStep::getProp(const char* pszKey)
   {
      auto iter = m_mapProp.find(pszKey);
      if (iter == m_mapProp.end()) return nullptr;
      return iter->second;
   }
         // 待退出信号或时间到
         HANDLE hEvents[] = { m_hWorkStop, m_hSignalOn };
         int nRet = WaitForMultipleObjects(2, hEvents, FALSE, INFINITE);
         if (nRet == WAIT_OBJECT_0) {
            ResetEvent(m_hWorkStop);
            break;
   void CStep::addAttribute(CAttribute* pAttribute)
   {
      // 添加attribute时,要前删除存在的同名的attribute
      m_attributeVector.addAttribute(pAttribute, TRUE);
   }
   void CStep::addAttributeVector(CAttributeVector& attributeVector)
   {
      // 添加attribute时,要前删除存在的同名的attribute
      std::vector<CAttribute*>& srcs = attributeVector.getAttributes();
      auto it = srcs.begin();
      while (it != srcs.end()) {
         BOOL bAdd = m_attributeVector.addAttribute((*it), TRUE);
         if (bAdd) {
            it = srcs.erase(it);
         }
         else if (nRet == WAIT_OBJECT_0 + 1) {
            ResetEvent(m_hSignalOn);
            // 1.读取数据
            nextStep();
            ASSERT(m_pCclink);
            if (0 == onReadData()) {
               if (m_listener.onEvent != nullptr) {
                  m_listener.onEvent(this, STEP_EVENT_READDATA, nullptr);
               }
            }
            // 2.给对方写ON
            nextStep();
            m_pCclink->SetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
            // 3.等待对方OFF
            nextStep();
            int nStep3Ret = ::WaitForSingleObject(m_hSignalOff, TIMEOUT * 1000);
            if (nStep3Ret == WAIT_TIMEOUT) {
               m_pCclink->ResetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
               onTimeout();
               goto RESET;
            }
            ResetEvent(m_hSignalOff);
            // 4.给对方写OFF
            nextStep();
            m_pCclink->ResetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
            // 6.完成
            nextStep();
            if (0 == onComplete()) {
               if (m_listener.onEvent != nullptr) {
                  m_listener.onEvent(this, STEP_EVENT_COMPLETE, nullptr);
               }
            }
         else {
            ++it;
         }
      }
   }
      if (hEvent != nullptr) {
         CloseHandle(hEvent);
   void CStep::convertString(const char* pszBuffer, int size, std::string& strOut)
   {
      strOut.clear();
      int nLength = 0;
      for (int i = 0; i < size; i++) {
         if (pszBuffer[i] == '\0') break;
         nLength++;
      }
      // _endthreadex(0);
      TRACE("CStep::WorkingProc 线程退出\n");
      return 0;
   }
   void CStep::onSignal(BOOL bSignal)
   {
      Lock();
      if (m_nCurStep == 0 && bSignal) {
         SetEvent(m_hSignalOn);
      if (nLength > 0) {
         strOut = std::string(pszBuffer, nLength);
      }
      else if (m_nCurStep == 3 && !bSignal) {
         SetEvent(m_hSignalOff);
      }
      Unlock();
   }
   int CStep::onReadData()
   {
      return 0;
   }
   int CStep::onComplete()
   {
      return 0;
   }
   int CStep::onTimeout()
   {
      return 0;
   }
   void CStep::resetStep()
   {
      Lock();
      m_nCurStep = 0;
      Unlock();
   }
   void CStep::nextStep()
   {
      Lock();
      m_nCurStep++;
      Unlock();
   }
}