| | |
| | | |
| | | CEquipment::CEquipment() : m_nID(0), m_strName(""), m_strDescription(""), m_station(0, 255) |
| | | { |
| | | m_listener = { nullptr, nullptr, nullptr, nullptr, nullptr }; |
| | | m_listener = { }; |
| | | m_alive = { FALSE, 0, FALSE }; |
| | | m_bCimState = FALSE; |
| | | m_bUpstreamInline = FALSE; |
| | |
| | | m_bLocalAlarm = FALSE; |
| | | m_bAutoRecipeChange = FALSE; |
| | | m_bVCREnable[0] = FALSE; |
| | | memset(m_bLinkSignal, 0, sizeof(m_bLinkSignal)); |
| | | m_pCclink = nullptr; |
| | | m_nBaseAlarmId = 0; |
| | | m_pArm = nullptr; |
| | |
| | | |
| | | void CEquipment::setListener(EquipmentListener listener) |
| | | { |
| | | m_listener.onAlive = listener.onAlive; |
| | | m_listener.onCimStateChanged = listener.onCimStateChanged; |
| | | m_listener.onAlarm = listener.onAlarm; |
| | | m_listener.onDataChanged = listener.onDataChanged; |
| | | m_listener.onVcrEventReport = listener.onVcrEventReport; |
| | | m_listener = listener; |
| | | } |
| | | |
| | | void CEquipment::setCcLink(CCCLinkIEControl* pCcLink) |
| | |
| | | Lock(); |
| | | for (int i = 0; i < SLOT_MAX; i++) { |
| | | m_slot[i].serialize(ar); |
| | | if (m_slot[i].getContext() != nullptr) { |
| | | ((CGlass*)m_slot[i].getContext())->serialize(ar); |
| | | } |
| | | } |
| | | Unlock(); |
| | | } |
| | | else { |
| | | for (int i = 0; i < SLOT_MAX; i++) { |
| | | m_slot[i].serialize(ar); |
| | | if (m_slot[i].getContext() != nullptr) { |
| | | if (m_slot[i].getTempContext() != nullptr) { |
| | | CGlass* pGlass = theApp.m_model.m_glassPool.allocaGlass(); |
| | | pGlass->serialize(ar); |
| | | m_slot[i].setContext(pGlass); |
| | |
| | | } |
| | | |
| | | // 梳理各玻璃之间的绑定关系 |
| | | /* |
| | | Lock(); |
| | | std::list<CGlass*> list = m_glassList; |
| | | for (auto item : list) { |
| | | std::string& strBuddyId = item->getBuddyId(); |
| | | if (!strBuddyId.empty()) { |
| | | for (auto item2 : m_glassList) { |
| | | if (strBuddyId.compare(item2->getID()) == 0) { |
| | | item->setBuddy(item2); |
| | | TRACE("绑定关系: %s <- %s\n", item->getID().c_str(), item2->getID().c_str()); |
| | | for (int i = 0; i < SLOT_MAX; i++) { |
| | | CGlass* pGlass = (CGlass*)m_slot[i].getContext(); |
| | | if (pGlass != nullptr) { |
| | | std::string& strBuddyId = pGlass->getBuddyId(); |
| | | if (!strBuddyId.empty()) { |
| | | for (int j = 0; j < SLOT_MAX; j++) { |
| | | CGlass* pBudy = (CGlass*)m_slot[j].getContext(); |
| | | if (pBudy != nullptr && strBuddyId.compare(pBudy->getID()) == 0) { |
| | | pGlass->setBuddy(pBudy); |
| | | TRACE("绑定关系: %s <- %s\n", pGlass->getID().c_str(), pBudy->getID().c_str()); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | Unlock(); |
| | | */ |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | */ |
| | | |
| | | // 以下解释和处理数据 |
| | | // 连接信号解释和保存 |
| | | BOOL bFlag; |
| | | int index = 0x540; |
| | | int index = 0; |
| | | for (int i = 0; i < 8; i++) { |
| | | m_bLinkSignal[i][SIGNAL_UPSTREAM_INLINE] = isBitOn(pszData, size, index + 0); |
| | | m_bLinkSignal[i][SIGNAL_UPSTREAM_TROUBLE] = isBitOn(pszData, size, index + 1); |
| | | m_bLinkSignal[i][SIGNAL_INTERLOCK] = isBitOn(pszData, size, index + 2); |
| | | m_bLinkSignal[i][SIGNAL_SEND_ABLE] = isBitOn(pszData, size, index + 3); |
| | | index += 0x40; |
| | | } |
| | | |
| | | |
| | | // 其它信号及响应 |
| | | index = 0x540; |
| | | |
| | | |
| | | // alive |
| | |
| | | return m_bVCREnable[index]; |
| | | } |
| | | |
| | | BOOL CEquipment::isLinkSignalOn(unsigned int path, unsigned int signal) |
| | | { |
| | | if (path >= PATH_MAX) return FALSE; |
| | | if (signal >= SIGNAL_MAX) return FALSE; |
| | | return m_bLinkSignal[path][signal]; |
| | | } |
| | | |
| | | void CEquipment::setLinkSignal(unsigned int path, unsigned int signal, BOOL bOn) |
| | | { |
| | | if (path >= PATH_MAX) return; |
| | | if (signal >= SIGNAL_MAX) return; |
| | | m_bLinkSignal[path][signal] = bOn; |
| | | } |
| | | |
| | | void CEquipment::setLinkSignalBlock(unsigned int path, BOOL* pSignal) |
| | | { |
| | | if (path >= PATH_MAX) return; |
| | | for (int i = 0; i < SIGNAL_MAX; i++) { |
| | | m_bLinkSignal[path][i] = pSignal[i]; |
| | | } |
| | | } |
| | | |
| | | int CEquipment::onStepEvent(CStep* pStep, int code) |
| | | { |
| | | if (code == STEP_EVENT_READDATA) { |
| | |
| | | CGlass* pGlass = (CGlass*)m_slot[i].getContext(); |
| | | if (pGlass != nullptr && compareJobDataB(pJobDataB, pGlass->getJobDataB())) { |
| | | pContext = pGlass; |
| | | if (pGlass != nullptr) pGlass->addRef(); |
| | | m_slot[i].setContext(nullptr); |
| | | break; |
| | | } |
| | |
| | | for (int i = 0; i < SLOT_MAX; i++) { |
| | | CGlass* pGlass = (CGlass*)m_slot[i].getContext(); |
| | | if (pGlass != nullptr && compareJobDataB(pBuddy->getJobDataB(), pGlass->getJobDataB())) { |
| | | pContext->release(); |
| | | m_slot[i].setContext(nullptr); |
| | | break; |
| | | } |
| | |
| | | Unlock(); |
| | | |
| | | if (m_listener.onDataChanged != nullptr) { |
| | | m_listener.onDataChanged(this, 0); |
| | | m_listener.onDataChanged(this, EDCC_FETCHOUT_JOB); |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | int CEquipment::storedJob(CJobDataB* pJobDataB) |
| | | int CEquipment::storedJob(CJobDataB* pJobDataB, short putSlot) |
| | | { |
| | | /* |
| | | if (m_pArm == nullptr) { |
| | | return -1; |
| | | } |
| | |
| | | |
| | | ASSERT(pGlass); |
| | | Lock(); |
| | | pGlass->addPath(m_nID); |
| | | pGlass->addRef(); // 加入list,addRef |
| | | m_glassList.push_back(pGlass); |
| | | pGlass->addPath(m_nID, getSlotUnit(putSlot)); |
| | | m_slot[putSlot - 1].setContext(pGlass); |
| | | pGlass->release(); // tempFetchOut需要调用一次release |
| | | Unlock(); |
| | | |
| | |
| | | CGlass* pBuddy = pGlass->getBuddy(); |
| | | if (pBuddy != nullptr) { |
| | | Lock(); |
| | | pBuddy->addPath(m_nID); |
| | | pBuddy->addRef(); // 加入list,addRef |
| | | m_glassList.push_back(pBuddy); |
| | | pBuddy->addPath(m_nID, 0); |
| | | if (putSlot % 2 == 0) { |
| | | m_slot[putSlot - 2].setContext(pBuddy); |
| | | } |
| | | else { |
| | | m_slot[putSlot].setContext(pBuddy); |
| | | } |
| | | Unlock(); |
| | | } |
| | | |
| | | |
| | | if (m_listener.onDataChanged != nullptr) { |
| | | m_listener.onDataChanged(this, 0); |
| | | m_listener.onDataChanged(this, EDCC_STORED_JOB); |
| | | } |
| | | */ |
| | | |
| | | return 0; |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | return FALSE; |
| | | } |
| | | |
| | | CGlass* CEquipment::getGlass(const char* pszGlassId) |
| | | { |
| | | for (int i = 0; i < SLOT_MAX; i++) { |
| | | if (!m_slot[i].isEnable()) continue; |
| | | CGlass* pGlass = (CGlass*)m_slot[i].getContext(); |
| | | if (pGlass == nullptr) continue; |
| | | if (pGlass->getID().compare(pszGlassId) == 0) { |
| | | return pGlass; |
| | | } |
| | | } |
| | | |
| | | return nullptr; |
| | | } |
| | | |
| | | bool CEquipment::isAlarmStep(SERVO::CStep* pStep) |
| | |
| | | return nullptr; |
| | | } |
| | | |
| | | CSlot* CEquipment::getAvailableSlotForGlass2(MaterialsType type, const std::vector<int>& candidates) |
| | | { |
| | | for (auto item : candidates) { |
| | | for (int i = 0; i < SLOT_MAX; i++) { |
| | | if (item == i + 1) { |
| | | if (!m_slot[i].isEnable()) continue; |
| | | if (m_slot[i].isLock()) continue; |
| | | if (!m_slot[i].isEmpty()) continue; |
| | | |
| | | MaterialsType slotType = m_slot[i].getType(); |
| | | if (type == MaterialsType::G1 && slotType == MaterialsType::G2) continue; |
| | | if (type == MaterialsType::G2 && slotType == MaterialsType::G1) continue; |
| | | |
| | | return &m_slot[i]; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return nullptr; |
| | | } |
| | | |
| | | CSlot* CEquipment::getNonEmptySlot(MaterialsType putSlotType) |
| | | { |
| | | for (int i = 0; i < SLOT_MAX; i++) { |
| | |
| | | if (glassType == MaterialsType::G2 && putSlotType == MaterialsType::G1) continue; |
| | | |
| | | return &m_slot[i]; |
| | | } |
| | | |
| | | return nullptr; |
| | | } |
| | | |
| | | CSlot* CEquipment::getProcessedSlot(MaterialsType putSlotType) |
| | | { |
| | | for (int i = 0; i < SLOT_MAX; i++) { |
| | | if (!m_slot[i].isEnable()) continue; |
| | | if (m_slot[i].isLock()) continue; |
| | | CGlass* pGlass = (CGlass*)m_slot[i].getContext(); |
| | | if (pGlass == nullptr) continue; |
| | | int lsPath = m_slot[i].getLinkSignalPath(); |
| | | if(!m_bLinkSignal[lsPath][SIGNAL_UPSTREAM_INLINE] |
| | | || m_bLinkSignal[lsPath][SIGNAL_UPSTREAM_TROUBLE] |
| | | || !m_bLinkSignal[lsPath][SIGNAL_INTERLOCK] |
| | | || !m_bLinkSignal[lsPath][SIGNAL_SEND_ABLE] ) continue; |
| | | |
| | | MaterialsType glassType = pGlass->getType(); |
| | | if (glassType == MaterialsType::G1 && putSlotType == MaterialsType::G2) continue; |
| | | if (glassType == MaterialsType::G2 && putSlotType == MaterialsType::G1) continue; |
| | | |
| | | return &m_slot[i]; |
| | | } |
| | | |
| | | return nullptr; |
| | | } |
| | | |
| | | CSlot* CEquipment::getProcessedSlot2(MaterialsType putSlotType, const std::vector<int>& candidates) |
| | | { |
| | | for (auto item : candidates) { |
| | | for (int i = 0; i < SLOT_MAX; i++) { |
| | | if (item == i + 1) { |
| | | if (!m_slot[i].isEnable()) continue; |
| | | if (m_slot[i].isLock()) continue; |
| | | CGlass* pGlass = (CGlass*)m_slot[i].getContext(); |
| | | if (pGlass == nullptr) continue; |
| | | int lsPath = m_slot[i].getLinkSignalPath(); |
| | | if (!m_bLinkSignal[lsPath][SIGNAL_UPSTREAM_INLINE] |
| | | || m_bLinkSignal[lsPath][SIGNAL_UPSTREAM_TROUBLE] |
| | | || !m_bLinkSignal[lsPath][SIGNAL_INTERLOCK] |
| | | || !m_bLinkSignal[lsPath][SIGNAL_SEND_ABLE]) continue; |
| | | |
| | | MaterialsType glassType = pGlass->getType(); |
| | | if (glassType == MaterialsType::G1 && putSlotType == MaterialsType::G2) continue; |
| | | if (glassType == MaterialsType::G2 && putSlotType == MaterialsType::G1) continue; |
| | | |
| | | return &m_slot[i]; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return nullptr; |
| | |
| | | } |
| | | |
| | | return nullptr; |
| | | } |
| | | |
| | | BOOL CEquipment::canPlaceGlassInSlot(const short slotIndex) |
| | | { |
| | | if (slotIndex >= SLOT_MAX) return FALSE; |
| | | if (!m_slot[slotIndex].isEnable()) return FALSE; |
| | | if (m_slot[slotIndex].getContext() != nullptr) return FALSE; |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | short CEquipment::decodeRecipeListReport(const char* pszData, size_t size) |
| | |
| | | return index; |
| | | } |
| | | |
| | | int CEquipment::onPreFetchedOutJob(int port, CJobDataB* pJobDataB) |
| | | BOOL CEquipment::onPreFetchedOutJob(int port, CJobDataB* pJobDataB) |
| | | { |
| | | LOGI("<CEquipment-%s>onPreFetchedOutJob:port:%d|GlassId:%s", |
| | | m_strName.c_str(), port, pJobDataB->getGlassId().c_str()); |
| | | if (m_listener.onPreFethedOutJob != nullptr) { |
| | | return m_listener.onPreFethedOutJob(this, pJobDataB); |
| | | } |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | |
| | | return 0; |
| | | } |
| | | |
| | | int CEquipment::onPreStoredJob(int port, CJobDataB* pJobDataB) |
| | | int CEquipment::onPreStoredJob(int port, CJobDataB* pJobDataB, short& putSlot) |
| | | { |
| | | LOGI("<CEquipment-%s>onPreStoredJob:port:%d|GlassId:%s", |
| | | m_strName.c_str(), port, pJobDataB->getGlassId().c_str()); |
| | |
| | | return FALSE; |
| | | } |
| | | |
| | | // 当前不能有任何玻璃,且当前准备进的片是G2 |
| | | // 如果没有可用位置,报错 |
| | | Lock(); |
| | | CSlot* pSlot = getAvailableSlotForGlass((MaterialsType)pJobDataS->getMaterialsType()); |
| | | if (pSlot == nullptr) { |
| | |
| | | } |
| | | Unlock(); |
| | | |
| | | |
| | | if (m_listener.onPreStoredJob != nullptr) { |
| | | if (!m_listener.onPreStoredJob(this, pJobDataB, putSlot)) { |
| | | return FALSE; |
| | | } |
| | | |
| | | if(!canPlaceGlassInSlot(putSlot - 1)) { |
| | | return FALSE; |
| | | } |
| | | } |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | |
| | | LOGI("<CEquipment-%s>onStore:port:%d|GlassId:%s", |
| | | m_strName.c_str(), port, pJobDataB->getGlassId().c_str()); |
| | | |
| | | BOOL bCheck = onPreStoredJob(port, pJobDataB); |
| | | short putSlot = 0; |
| | | BOOL bCheck = onPreStoredJob(port, pJobDataB, putSlot); |
| | | if (bCheck) { |
| | | addJobDataB(pJobDataB); |
| | | return storedJob(pJobDataB); |
| | | return storedJob(pJobDataB, putSlot); |
| | | } |
| | | |
| | | // 数据异常,处理或显示 |
| | |
| | | int CEquipment::onProcessData(CProcessData* pProcessData) |
| | | { |
| | | LOGI("<CEquipment-%s>onProcessData.", m_strName.c_str()); |
| | | |
| | | return 0; |
| | | } |
| | | |