| | |
| | | #include "Servo.h" |
| | | #include "CPageGraph2.h" |
| | | #include "afxdialogex.h" |
| | | #include "CHMPropertyDlg.h" |
| | | #include "CEquipmentPage1.h" |
| | | #include "CEquipmentPage2.h" |
| | | #include "CEquipmentPage3.h" |
| | | #include "CPageLinkSignal.h" |
| | | #include "CPagePortProperty.h" |
| | | #include "CPagePortStatus.h" |
| | | #include "CPageCassetteCtrlCmd.h" |
| | | #include "CJobDataB.h" |
| | | |
| | | |
| | | // CPageGraph2 对话框 |
| | |
| | | m_pEqsGraphWnd = nullptr; |
| | | m_crBkgnd = PAGE_GRPAH2_BACKGROUND_COLOR; |
| | | m_hbrBkgnd = nullptr; |
| | | m_pObserver = nullptr; |
| | | } |
| | | |
| | | CPageGraph2::~CPageGraph2() |
| | |
| | | // 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); |
| | | |
| | | |
| | |
| | | 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 { |
| | |
| | | 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); |
| | | |
| | | CPageLinkSignal* pPage1 = new CPageLinkSignal(); |
| | | pPage1->setEquipment(pEquipment); |
| | | pPage1->Create(IDD_PAGE_LINK_SIGNAL); |
| | | dlg.addPage(pPage1, "Link Signal"); |
| | | |
| | | 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, "Slots"); |
| | | |
| | | 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_LOADPORT4 && !pEquipment->hasGlass()) { |
| | | ((SERVO::CLoadPort*)pEquipment)->testGenerateGlassList(SERVO::MaterialsType::G1); |
| | | bTestGenerate = TRUE; |
| | | } |
| | | /* |
| | | else if (pEquipment->getID() == EQ_ID_LOADPORT1 && !pEquipment->hasGlass()) { |
| | | ((SERVO::CLoadPort*)pEquipment)->testGenerateGlassList(SERVO::MaterialsType::G2); |
| | | bTestGenerate = TRUE; |
| | | } |
| | | */ |
| | | if (!bTestGenerate) { |
| | | SERVO::CRobotTask* pTask = theApp.m_model.getMaster().getActiveRobotTask(); |
| | | if (pTask != nullptr) { |
| | | SERVO::CGlass* pGlass = (SERVO::CGlass*)pTask->getContext(); |
| | | SERVO::CJobDataS* pJobDataS = pGlass->getJobDataS(); |
| | | if (pJobDataS != nullptr) { |
| | | SERVO::CJobDataB jobDataB; |
| | | pEquipment->onFetchedOutJob(0, &pJobDataS->getJobDataB(jobDataB)); |
| | | 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::CJobDataS* pJobDataS = pGlass->getJobDataS(); |
| | | if (pJobDataS != nullptr) { |
| | | pEquipment->onReceivedJob(0, pJobDataS); |
| | | Sleep(600); |
| | | SERVO::CJobDataB jobDataB; |
| | | pEquipment->onStoredJob(0, &pJobDataS->getJobDataB(jobDataB)); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | 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; |
| | | if (pEquipment != nullptr) { |
| | | pEquipment->setLinkSignal(0, SIGNAL_UPSTREAM_INLINE, TRUE); |
| | | pEquipment->setLinkSignal(0, SIGNAL_UPSTREAM_TROUBLE, FALSE); |
| | | pEquipment->setLinkSignal(0, SIGNAL_INTERLOCK, TRUE); |
| | | pEquipment->setLinkSignal(0, SIGNAL_SEND_ABLE, TRUE); |
| | | pEquipment->setLinkSignal(1, SIGNAL_UPSTREAM_INLINE, TRUE); |
| | | pEquipment->setLinkSignal(1, SIGNAL_UPSTREAM_TROUBLE, FALSE); |
| | | pEquipment->setLinkSignal(1, SIGNAL_INTERLOCK, TRUE); |
| | | pEquipment->setLinkSignal(1, SIGNAL_SEND_ABLE, TRUE); |
| | | } |
| | | |
| | | if (pEquipment != nullptr && (pEquipment->getID() == EQ_ID_Bonder1 |
| | | || pEquipment->getID() == EQ_ID_Bonder2)) { |
| | | 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_TEST5) { |
| | | SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData; |
| | | if (pEquipment != nullptr) { |
| | | pEquipment->setLinkSignal(0, SIGNAL_UPSTREAM_INLINE, TRUE); |
| | | pEquipment->setLinkSignal(0, SIGNAL_UPSTREAM_TROUBLE, TRUE); |
| | | pEquipment->setLinkSignal(0, SIGNAL_INTERLOCK, TRUE); |
| | | pEquipment->setLinkSignal(0, SIGNAL_SEND_ABLE, FALSE); |
| | | pEquipment->setLinkSignal(1, SIGNAL_UPSTREAM_INLINE, TRUE); |
| | | pEquipment->setLinkSignal(1, SIGNAL_UPSTREAM_TROUBLE, TRUE); |
| | | pEquipment->setLinkSignal(1, SIGNAL_INTERLOCK, TRUE); |
| | | pEquipment->setLinkSignal(1, SIGNAL_SEND_ABLE, FALSE); |
| | | } |
| | | } |
| | | else if (nCmd == ID_EQSGRAPHITEM_TEST6) { |
| | | 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; |
| | | }; |
| | | |
| | |
| | | void CPageGraph2::OnDestroy() |
| | | { |
| | | CDialogEx::OnDestroy(); |
| | | SaveEqsGraphData(); |
| | | |
| | | if (m_hbrBkgnd != nullptr) { |
| | | ::DeleteObject(m_hbrBkgnd); |
| | | } |
| | | |
| | | if (m_pObserver != nullptr) { |
| | | m_pObserver->unsubscribe(); |
| | | m_pObserver = NULL; |
| | | } |
| | | } |
| | | |
| | |
| | | #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); |
| | |
| | | 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) |
| | |
| | | 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); |
| | | } |