mrDarker
2025-06-03 0393d1ff2ebc378b3c4cff9b45f72ebc8a4ea516
SourceCode/Bond/Servo/CPageGraph2.cpp
@@ -5,6 +5,14 @@
#include "Servo.h"
#include "CPageGraph2.h"
#include "afxdialogex.h"
#include "CHMPropertyDlg.h"
#include "CEquipmentPage1.h"
#include "CEquipmentPage2.h"
#include "CEquipmentPage3.h"
#include "CPagePortProperty.h"
#include "CPagePortStatus.h"
#include "CPageCassetteCtrlCmd.h"
#include "CJobDataB.h"
// CPageGraph2 对话框
@@ -17,6 +25,7 @@
   m_pEqsGraphWnd = nullptr;
   m_crBkgnd = PAGE_GRPAH2_BACKGROUND_COLOR;
   m_hbrBkgnd = nullptr;
   m_pObserver = nullptr;
}
CPageGraph2::~CPageGraph2()
@@ -40,9 +49,44 @@
// CPageGraph2 消息处理程序
void CPageGraph2::InitRxWindows()
{
   /* code */
   // 订阅数据
   IRxWindows* pRxWindows = RX_GetRxWindows();
   pRxWindows->enableLog(5);
   if (m_pObserver == NULL) {
      m_pObserver = pRxWindows->allocObserver([&](IAny* pAny) -> void {
         // onNext
         pAny->addRef();
         int code = pAny->getCode();
         if (RX_CODE_EQ_DATA_CHANGED == code) {
            // 通知设备状态
            SERVO::CEquipment* pEquipment = nullptr;
            if (pAny->getPtrValue("ptr", (void*&)pEquipment)) {
               if (pEquipment != nullptr) {
                  m_pEqsGraphWnd->ShowItemIndicator((DWORD_PTR)pEquipment, pEquipment->hasGlass());
               }
            }
         }
         pAny->release();
         }, [&]() -> void {
            // onComplete
         }, [&](IThrowable* pThrowable) -> void {
            // onErrorm
            pThrowable->printf();
         });
      theApp.m_model.getObservable()->observeOn(pRxWindows->mainThread())
         ->subscribe(m_pObserver);
   }
}
BOOL CPageGraph2::OnInitDialog()
{
   CDialogEx::OnInitDialog();
   InitRxWindows();
   SetTimer(1, 2000, nullptr);
@@ -54,11 +98,6 @@
      ASSERT(pPin1->pData);
      ASSERT(pPin2->pData);
      //int nRet = ((IPin*)pPin1->pData)->checkConnectPin((IPin*)pPin2->pData);
      //if (nRet >= 0) {
      //   return true;
      //}
      return false;
   };
   listener.onConnectPin = [](PIN* pPin1, PIN* pPin2) -> bool {
@@ -67,39 +106,250 @@
      ASSERT(pPin1->pData);
      ASSERT(pPin2->pData);
      //int nRet = ((IPin*)pPin1->pData)->connectPin((IPin*)pPin2->pData);
      //if (nRet >= 0) {
      //   return true;
      //}
      return false;
   };
   listener.onDisconnectPin = [](PIN* pPin) -> bool {
      ASSERT(pPin);
      ASSERT(pPin->pData);
      //int nRet = ((IPin*)pPin->pData)->disconnect();
      //if (nRet >= 0) {
      //   return true;
      //}
      return false;
   };
   listener.onDeleteEqItem = [&](EQITEM* pItem) -> bool {
      ASSERT(pItem);
      ASSERT(pItem->pData);
      return true;
      // return _filterManager.unload((CFilter*)pFilter->pData) >= 0;
      return false;
   };
   listener.onEqItemPosChanged = [&](EQITEM* pItem, int x, int y) -> void {
      ASSERT(pItem);
   };
   listener.onDblckEqItem = [&](EQITEM* pItem) -> bool {
      ASSERT(pItem);
      SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData;
      CHMPropertyDlg dlg(pEquipment->getName().c_str(), 658, 788);
      if (_strcmpi(pEquipment->getClassName(), "CLoadPort") == 0) {
         CPagePortProperty* pPageA = new CPagePortProperty();
         pPageA->setLoadPort((SERVO::CLoadPort*)pEquipment);
         pPageA->Create(IDD_PAGE_PORT_PROPERTY);
         dlg.addPage(pPageA, "属性");
         CPagePortStatus* pPageB = new CPagePortStatus();
         pPageB->setLoadPort((SERVO::CLoadPort*)pEquipment);
         pPageB->Create(IDD_PAGE_PORT_STATUS);
         dlg.addPage(pPageB, "Status");
      }
      CEquipmentPage2* pPage2 = new CEquipmentPage2();
      pPage2->setEquipment(pEquipment);
      pPage2->Create(IDD_PAGE_EQUIPMENT2);
      dlg.addPage(pPage2, "Glass");
      if (pEquipment->getID() == EQ_ID_EFEM) {
         CEquipmentPage3* pPage3 = new CEquipmentPage3();
         pPage3->setEquipment(pEquipment);
         pPage3->Create(IDD_PAGE_EQUIPMENT3);
         dlg.addPage(pPage3, "Dispatching Mode");
      }
      if (pEquipment->getID() == EQ_ID_LOADPORT1
         || pEquipment->getID() == EQ_ID_LOADPORT2) {
         CPageCassetteCtrlCmd* pPage = new CPageCassetteCtrlCmd();
         pPage->setEquipment(pEquipment);
         pPage->Create(IDD_PAGE_CASSETTE_CTRL_CMD);
         dlg.addPage(pPage, "Cassette control command");
      }
      dlg.DoModal();
      return true;
   };
   listener.onRclickEqItem = [&](EQITEM* pItem) -> bool {
      ASSERT(pItem);
      CMenu menu, menuCommand;
      CMenu* pPopupMenu;
      menu.LoadMenu(IDR_MENU_EQSGRAPH_ITEM);
      pPopupMenu = menu.GetSubMenu(0);
      // 显示模式
      pPopupMenu->EnableMenuItem(ID_EQSGRAPHITEM_SMALL, MF_DISABLED | MF_GRAYED);
      pPopupMenu->EnableMenuItem(ID_EQSGRAPHITEM_NORMAL, MF_DISABLED | MF_GRAYED);
      pPopupMenu->EnableMenuItem(ID_EQSGRAPHITEM_LARGE, MF_DISABLED | MF_GRAYED);
      if (pItem->nShowType == ITEM_SMALL) {
         pPopupMenu->CheckMenuRadioItem(ID_EQSGRAPHITEM_SMALL, ID_EQSGRAPHITEM_LARGE, ID_EQSGRAPHITEM_SMALL, MF_CHECKED);
      }
      else if (pItem->nShowType == ITEM_LARGE) {
         pPopupMenu->CheckMenuRadioItem(ID_EQSGRAPHITEM_SMALL, ID_EQSGRAPHITEM_LARGE, ID_EQSGRAPHITEM_LARGE, MF_CHECKED);
      }
      else {
         pPopupMenu->CheckMenuRadioItem(ID_EQSGRAPHITEM_SMALL, ID_EQSGRAPHITEM_LARGE, ID_EQSGRAPHITEM_NORMAL, MF_CHECKED);
      }
      POINT pt;
      GetCursorPos(&pt);
      int nCmd = pPopupMenu->TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_TOPALIGN, pt.x, pt.y, this, NULL);
      if (nCmd == ID_EQSGRAPHITEM_SMALL) {
         m_pEqsGraphWnd->SetItemType(pItem, ITEM_SMALL);
      }
      else if (nCmd == ID_EQSGRAPHITEM_NORMAL) {
         m_pEqsGraphWnd->SetItemType(pItem, ITEM_NORMAL);
      }
      else if (nCmd == ID_EQSGRAPHITEM_LARGE) {
         m_pEqsGraphWnd->SetItemType(pItem, ITEM_LARGE);
      }
      // 测试
      else if (nCmd == ID_EQSGRAPHITEM_TEST1) {
         BOOL bTestGenerate = FALSE;
         SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData;
         if (pEquipment->getID() == EQ_ID_LOADPORT1 && !pEquipment->hasGlass()) {
            ((SERVO::CLoadPort*)pEquipment)->testGenerateGlassList(SERVO::MaterialsType::G1,
               "P20250320G1X", 1);
            bTestGenerate = TRUE;
         }
         else if (pEquipment->getID() == EQ_ID_LOADPORT2 && !pEquipment->hasGlass()) {
            ((SERVO::CLoadPort*)pEquipment)->testGenerateGlassList(SERVO::MaterialsType::G2,
               "P20250320G2X", 1);
            bTestGenerate = TRUE;
         }
         if (!bTestGenerate) {
            SERVO::CRobotTask* pTask = theApp.m_model.getMaster().getActiveRobotTask();
            if (pTask != nullptr) {
               SERVO::CGlass* pGlass = (SERVO::CGlass*)pTask->getContext();
               SERVO::CJobDataB* pJobDataB = pGlass->getJobDataB();
               SERVO::CJobDataS* pJobDataS = pGlass->getJobDataS();
               if (pJobDataB != nullptr && pJobDataS != nullptr) {
                  pEquipment->onFetchedOutJob(0, pJobDataB);
                  pEquipment->onSentOutJob(0, pJobDataS);
               }
            }
         }
      }
      else if (nCmd == ID_EQSGRAPHITEM_TEST2) {
         SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData;
         SERVO::CArm* pArm = (SERVO::CArm*)pEquipment->getArm();
         if (pArm != nullptr) {
            SERVO::CGlass* pGlass = pArm->getAnyGlass();
            if (pGlass != nullptr) {
               SERVO::CJobDataB* pJobDataB = pGlass->getJobDataB();
               SERVO::CJobDataS* pJobDataS = pGlass->getJobDataS();
               if (pJobDataB != nullptr && pJobDataS != nullptr) {
                  pEquipment->onReceivedJob(0, pJobDataS);
                  Sleep(600);
                  pEquipment->onStoredJob(0, pJobDataB);
               }
            }
         }
      }
      else if (nCmd == ID_EQSGRAPHITEM_TEST3) {
         SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData;
         if (pEquipment != nullptr) {
            SERVO::CGlass* pGlass = pEquipment->getAnyGlass();
            if (pGlass != nullptr) {
               SERVO::CProcessData pd;
               pd.setGlassId(pGlass->getID().c_str());
               pEquipment->onProcessData(&pd);
            }
         }
      }
      else if (nCmd == ID_EQSGRAPHITEM_TEST4) {
         SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData;
         // 测试下发Cim Message
         /*
         if (pEquipment->getID() == EQ_ID_Bonder1
            || pEquipment->getID() == EQ_ID_Bonder2) {
            static int msgId = 0; msgId++;
            if (msgId % 2 == 0) {
               pEquipment->setCimMessage("Hello!", msgId, 1);
            }
            else {
               pEquipment->setCimMessage("ABC0123456789", msgId, 2);
            }
         }
         */
         // 测试清除Cim Message
         /*
         if (pEquipment->getID() == EQ_ID_Bonder1
            || pEquipment->getID() == EQ_ID_Bonder2) {
            static int msgId = 0; msgId++;
            if (msgId % 2 == 0) {
               pEquipment->clearCimMessage(msgId, 1);
            }
            else {
               pEquipment->clearCimMessage(msgId, 2);
            }
         }
         */
         // 测试设置时间
         /*
         if (pEquipment->getID() == EQ_ID_Bonder1
            || pEquipment->getID() == EQ_ID_Bonder2) {
            CTime time = CTime::GetCurrentTime();
            pEquipment->setDateTime((short)time.GetYear(),
               (short)time.GetMonth(),
               (short)time.GetDay(),
               (short)time.GetHour(),
               (short)time.GetMinute(),
               (short)time.GetSecond());
         }
         */
         // 测试设置cim mode
         /*
         if (pEquipment->getID() == EQ_ID_Bonder1
            || pEquipment->getID() == EQ_ID_Bonder2) {
            static int ii = 0; ii++;
            pEquipment->setCimMode(ii % 2 == 0);
         }
         */
         if (pEquipment->getID() == EQ_ID_Bonder1
            || pEquipment->getID() == EQ_ID_Bonder2) {
            static int ii = 0; ii++;
            pEquipment->setEqMode((ii % 5) + 1);
         }
         /*
         SERVO::CGlass* pGlass = pEquipment->getAnyGlass();
         if (pGlass != nullptr) {
            std::string strDescription;
            SERVO::CPath* pPath = pGlass->getPath();
            while (pPath != nullptr) {
               pPath->getDescription(strDescription);
               AfxMessageBox(strDescription.c_str());
               pPath = pPath->getNext();
            }
         }
         */
         // 请求主配方列表
         if (pEquipment != nullptr) {
            pEquipment->masterRecipeListRequest(0);
         }
      }
      return true;
   };
   listener.onSelectEqItem = [&](EQITEM* pItem) -> bool {
      ASSERT(pItem);
      SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData;
      theApp.m_model.notifyPtr(RX_CODE_SELECT_EQUIPMENT, pEquipment);
      return true;
   };
@@ -133,9 +383,15 @@
void CPageGraph2::OnDestroy()
{
   CDialogEx::OnDestroy();
   SaveEqsGraphData();
   if (m_hbrBkgnd != nullptr) {
      ::DeleteObject(m_hbrBkgnd);
   }
   if (m_pObserver != nullptr) {
      m_pObserver->unsubscribe();
      m_pObserver = NULL;
   }
}
@@ -154,8 +410,15 @@
#define OUTPIN      2
void CPageGraph2::AddEqToGraphWnd(SERVO::CEquipment* pEquipment)
{
   int x, y;
   GetItemDataFormIni(pEquipment->getName().c_str(), x, y);
   EQITEM* pItem = m_pEqsGraphWnd->AddItem(0, pEquipment->getName().c_str(), (DWORD_PTR)pEquipment);
   m_pEqsGraphWnd->SetItemType(pItem, ITEM_SMALL);
   if (x > 0 && y > 0) {
      m_pEqsGraphWnd->SetItemPos(pItem, x, y);
   }
   std::vector<SERVO::CPin*>& inPins = pEquipment->getInputPins();
   for (auto inPin : inPins) {
      m_pEqsGraphWnd->AddPin(pItem, INPIN, inPin->getName().c_str(), (DWORD_PTR)inPin);
@@ -165,6 +428,8 @@
   for (auto outPin : outPins) {
      m_pEqsGraphWnd->AddPin(pItem, OUTPIN, outPin->getName().c_str(), (DWORD_PTR)outPin);
   }
   m_pEqsGraphWnd->ShowItemIndicator((DWORD_PTR)pEquipment, pEquipment->hasGlass());
}
void CPageGraph2::OnTimer(UINT_PTR nIDEvent)
@@ -172,10 +437,50 @@
   if (1 == nIDEvent) {
      KillTimer(1);
      std::list<SERVO::CEquipment*>& eqs = theApp.m_model.m_master.getEquipmentList();
      for (auto item : eqs) {
         AddEqToGraphWnd(item);
      for (auto eq : eqs) {
         AddEqToGraphWnd(eq);
      }
      for (auto eq : eqs) {
         auto& pins = eq->getOutputPins();
         for (auto pin : pins) {
            SERVO::CPin* pPin2 = pin->getConnectedPin();
            if (pPin2 != nullptr) {
               m_pEqsGraphWnd->ConnectPin((DWORD_PTR)eq, (DWORD_PTR)pin, (DWORD_PTR)pPin2->getEquipment(), (DWORD_PTR)pPin2);
            }
         }
      }
   }
   CDialogEx::OnTimer(nIDEvent);
}
void CPageGraph2::SaveEqsGraphData()
{
   char szFilepath[MAX_PATH];
   CString strValue;
   sprintf_s(szFilepath, MAX_PATH, "%s\\EqsGraph.ini", (LPTSTR)(LPCTSTR)theApp.m_strAppDir);
   std::list<SERVO::CEquipment*>& eqs = theApp.m_model.m_master.getEquipmentList();
   for (auto item : eqs) {
      EQITEM* pEqItem = m_pEqsGraphWnd->GetItem((DWORD_PTR)item);
      if (nullptr == pEqItem) {
         continue;
      }
      strValue.Format(_T("%d"), pEqItem->rect.left);
      WritePrivateProfileString(item->getName().c_str(), _T("Left"),
         (LPTSTR)(LPCTSTR)strValue, szFilepath);
      strValue.Format(_T("%d"), pEqItem->rect.top);
      WritePrivateProfileString(item->getName().c_str(), _T("Top"),
         (LPTSTR)(LPCTSTR)strValue, szFilepath);
   }
}
void CPageGraph2::GetItemDataFormIni(const char* pszItemName, int& left, int& top)
{
   char szFilepath[MAX_PATH];
   CString strValue;
   sprintf_s(szFilepath, MAX_PATH, "%s\\EqsGraph.ini", (LPTSTR)(LPCTSTR)theApp.m_strAppDir);
   left = GetPrivateProfileInt(pszItemName, _T("Left"), 0, szFilepath);
   top = GetPrivateProfileInt(pszItemName, _T("Top"), 0, szFilepath);
}