⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 elevatorthread.cpp

📁 电梯调度模拟,有mfc界面展现5部电梯的相互调度
💻 CPP
📖 第 1 页 / 共 2 页
字号:

		m_TCB.m_iNextDestFloor = iReqFloor;

		KillTimer(1);
		SetTimer(1,RUNONE_FLOOR_TIME*1000,NULL);//启动电梯
		break;

	case Ele_UP_PAUSE:
		m_TCB.m_iNextDestFloor = m_mycUpInnerWaitQueue->getNextAvail();
		if(m_TCB.m_iNextDestFloor==-1 || iReqFloor<m_TCB.m_iNextDestFloor) m_TCB.m_iNextDestFloor = iReqFloor;
		m_mycUpInnerWaitQueue->addElement(iReqFloor);
		m_TCB.m_eCurState =Ele_UP_RUN;
		m_ElevatorBox.SetWindowText(stateDespArr[m_TCB.m_eCurState]);//改变电梯状态显示

		KillTimer(1);		
		SetTimer(1,RUNONE_FLOOR_TIME*1000,NULL);//启动电梯
		break;

	case Ele_DOWN_PAUSE:
		m_TCB.m_iNextDestFloor = m_mycDownInnerWaitQueue->getNextAvail();
		if(m_TCB.m_iNextDestFloor==-1 || iReqFloor>m_TCB.m_iNextDestFloor) m_TCB.m_iNextDestFloor = iReqFloor;
		m_mycDownInnerWaitQueue->addElement(iReqFloor);
		m_TCB.m_eCurState =Ele_DOWN_RUN;
		m_ElevatorBox.SetWindowText(stateDespArr[m_TCB.m_eCurState]);//改变电梯状态显示

		KillTimer(1);		
		SetTimer(1,RUNONE_FLOOR_TIME*1000,NULL);//启动电梯		
		break;

	case Ele_UP_RUN:
		if(iReqFloor<m_TCB.m_iNextDestFloor) m_TCB.m_iNextDestFloor = iReqFloor;
		m_mycUpInnerWaitQueue->addElement(iReqFloor);
		break;

	case Ele_DOWN_RUN:
		if(iReqFloor>m_TCB.m_iNextDestFloor) m_TCB.m_iNextDestFloor = iReqFloor;
		m_mycDownInnerWaitQueue->addElement(iReqFloor);
		break;

	}

}


void CMyElevatorThread::openDoor() {

	//如果电梯之前接受的是逆向请求,现在到达了目的楼层,则转向并解禁
	if(m_TCB.m_eBackupDirection!=BAD_DIRE)
	{
		if(m_TCB.m_eBackupDirection==UP)
		{
			m_TCB.m_eCurState = Ele_UP_PAUSE;
			m_mycDownInnerWaitQueue->removeElement(m_TCB.m_iCurFloor);
		}
		else
		{
			m_TCB.m_eCurState = Ele_DOWN_PAUSE;
			m_mycUpInnerWaitQueue->removeElement(m_TCB.m_iCurFloor);
		}

		m_TCB.m_bCanSchedule = TRUE;
		m_TCB.m_eBackupDirection = BAD_DIRE;

	}else{

		//从等待队列中移除当前楼层请求
		if(m_TCB.m_eCurState == Ele_UP_RUN){
			m_mycUpInnerWaitQueue->removeElement(m_TCB.m_iCurFloor);
			m_TCB.m_eCurState = Ele_UP_PAUSE;
		}
		else if(m_TCB.m_eCurState == Ele_DOWN_RUN){
			m_mycDownInnerWaitQueue->removeElement(m_TCB.m_iCurFloor);
			m_TCB.m_eCurState = Ele_DOWN_PAUSE;
		}
	}


	CString tempStr,tempStr1;
	tempStr.Format(_T("%d"),m_TCB.m_iCurFloor);
	tempStr = _T("到达")+tempStr+_T("楼");
	m_ElevatorBox.SetWindowText(tempStr);
	tempStr1.Format(_T("%d"),m_TCB.m_iCurPassengerNum);
	tempStr="";

	m_ElevatorBox.SetWindowText(_T("开门中。。。"));	

	GetDlgItem(IDC_BUTTON_OPENDOOR)->EnableWindow(FALSE);
	GetDlgItem(IDC_BUTTON_CLOSEDOOR)->EnableWindow(TRUE);
	GetDlgItem(IDC_BUTTON_ENTER)->EnableWindow(TRUE);
	GetDlgItem(IDC_BUTTON_LEAVE)->EnableWindow(TRUE);


	enableRelateBtn(m_TCB.m_eCurState,m_TCB.m_iCurFloor);
	// m_ElevatorBox.SetBkColor(RGB(0,0,0));
	SetTimer(2,DOOR_KEEPOPEN_TIME*1000,NULL);//开启开门超时计时时钟

}

void CMyElevatorThread::closeDoor() {

	//KillTimer(2);
	//m_eCurState = m_eOldState;	//恢复电梯运行方向
	m_ElevatorBox.SetWindowText(_T("关门中。。。"));

	//到头后自动换向
	if(m_TCB.m_eCurState==Ele_UP_PAUSE && m_TCB.m_iCurFloor==MAX_FLOOR_NUM) m_TCB.m_eCurState =Ele_DOWN_PAUSE;
	if(m_TCB.m_eCurState==Ele_DOWN_PAUSE && m_TCB.m_iCurFloor==1) m_TCB.m_eCurState =Ele_UP_PAUSE;

	GetDlgItem(IDC_BUTTON_CLOSEDOOR)->EnableWindow(FALSE);
	GetDlgItem(IDC_BUTTON_ENTER)->EnableWindow(FALSE);
	GetDlgItem(IDC_BUTTON_LEAVE)->EnableWindow(FALSE);


	if (m_TCB.m_iCurPassengerNum==0)
	{
		for (int i=19;i>=0;i--)
		{
			GetDlgItem(IDC_MYBUTTONS+i)->EnableWindow(TRUE);
		}
	}
	if ((m_TCB.m_iCurPassengerNum!=0)&&((m_TCB.m_eCurState==UP)||(m_TCB.m_eCurState==Ele_UP_PAUSE)))
	{
		for (int i=m_TCB.m_iCurFloor-2;i>=0;i--)
		{
			GetDlgItem(IDC_MYBUTTONS+i)->EnableWindow(FALSE);
		}


	}
	if ((m_TCB.m_iCurPassengerNum!=0)&&((m_TCB.m_eCurState==DOWN)||(m_TCB.m_eCurState==Ele_DOWN_PAUSE)))
	{
		for (int i=m_TCB.m_iCurFloor;i<=19;i++)
		{
			GetDlgItem(IDC_MYBUTTONS+i)->EnableWindow(FALSE);
		}


	}

	//前往下一楼层
	gotoNextDest();

}


void CMyElevatorThread::gotoNextDest() 
{

	if(m_TCB.m_eCurState==Ele_UP_PAUSE) 
	{	
		if((m_TCB.m_iNextDestFloor = m_mycUpInnerWaitQueue->getNextAvail())==-1)//上行队列空,调整方向
		{

			if(m_TCB.m_iCurPassengerNum>0) //如果无请求但有乘客则进入暂停状态
			{
				m_ElevatorBox.SetWindowText(_T("上行暂停"));		
			}
			else
			{
				m_TCB.m_eCurState =Ele_IDLE;
				m_ElevatorBox.SetWindowText(_T("空闲"));
			}

		}
		else{m_TCB.m_eCurState =Ele_UP_RUN;}

	}
	else if(m_TCB.m_eCurState==Ele_DOWN_PAUSE) 
	{
		if((m_TCB.m_iNextDestFloor = m_mycDownInnerWaitQueue->getNextAvail())==-1)//下行队列空,调整方向
		{

			if(m_TCB.m_iCurPassengerNum>0) //如果无请求但有乘客则进入暂停状态
			{
				m_ElevatorBox.SetWindowText(_T("下行暂停"));	
			}else{
				m_TCB.m_eCurState =Ele_IDLE;
				m_ElevatorBox.SetWindowText(_T("空闲"));
			}

		}else{m_TCB.m_eCurState =Ele_DOWN_RUN;}
	}

	m_ElevatorBox.SetWindowText(stateDespArr[m_TCB.m_eCurState]);//改变电梯状态显示

	//如果找到了下一个请求 
	if(m_TCB.m_iNextDestFloor >0)	SetTimer(1,RUNONE_FLOOR_TIME*1000,NULL);//启动电梯


}

//处理电梯内部任务请求

void CMyElevatorThread::OnInnerBtnClk(UINT curBtn) 
{

	if(m_TCB.m_iCurPassengerNum==0)
	{
		AfxMessageBox(_T("内部无人,不可能进行操作!"));
		return;
	}

	if(isMalFunction())
	{
		AfxMessageBox(_T("本电梯故障。"));
		return;
	}

	int iReqFloor = curBtn-900+1;

	if((m_TCB.m_eCurState==Ele_UP_RUN && iReqFloor<=m_TCB.m_iCurFloor) || \
		(m_TCB.m_eCurState==Ele_UP_PAUSE && iReqFloor<m_TCB.m_iCurFloor))
	{
		AfxMessageBox(_T("您的请求跟电梯当前运行方向不一致。"));
		return;
	}else if((m_TCB.m_eCurState==Ele_DOWN_RUN && iReqFloor>=m_TCB.m_iCurFloor) || \
		(m_TCB.m_eCurState==Ele_DOWN_PAUSE && iReqFloor>m_TCB.m_iCurFloor))
	{
		AfxMessageBox(_T("您的请求跟电梯当前运行方向不一致。"));
		return;
	}

	//如果刚好电梯所停楼层有请求,则直接开门
	if((m_TCB.m_eCurState==Ele_UP_PAUSE || m_TCB.m_eCurState==Ele_DOWN_PAUSE) && (iReqFloor==m_TCB.m_iCurFloor))
	{
		if(m_TCB.m_eCurState==Ele_UP_PAUSE) m_TCB.m_eCurState = Ele_UP_RUN;
		else m_TCB.m_eCurState = Ele_DOWN_RUN;

		MessageBeep(MB_ICONASTERISK);
		openDoor();
		return;
	}

	switch(m_TCB.m_eCurState)
	{
	case Ele_UP_PAUSE:
		m_TCB.m_iNextDestFloor = m_mycUpInnerWaitQueue->getNextAvail();
		if(m_TCB.m_iNextDestFloor==-1 || iReqFloor<m_TCB.m_iNextDestFloor) m_TCB.m_iNextDestFloor = iReqFloor;
		m_mycUpInnerWaitQueue->addElement(iReqFloor);
		m_TCB.m_eCurState =Ele_UP_RUN;
		m_ElevatorBox.SetWindowText(_T("上行中。。。"));

		KillTimer(1);		
		SetTimer(1,RUNONE_FLOOR_TIME*1000,NULL);//启动电梯
		break;

	case Ele_DOWN_PAUSE:
		m_TCB.m_iNextDestFloor = m_mycDownInnerWaitQueue->getNextAvail();
		if(m_TCB.m_iNextDestFloor==-1 || iReqFloor>m_TCB.m_iNextDestFloor) m_TCB.m_iNextDestFloor = iReqFloor;
		m_mycDownInnerWaitQueue->addElement(iReqFloor);
		m_TCB.m_eCurState =Ele_DOWN_RUN;
		m_ElevatorBox.SetWindowText(_T("下行中。。。"));

		KillTimer(1);		
		SetTimer(1,RUNONE_FLOOR_TIME*1000,NULL);//启动电梯		
		break;

	case Ele_UP_RUN:
		if(iReqFloor<m_TCB.m_iNextDestFloor) m_TCB.m_iNextDestFloor = iReqFloor;
		m_mycUpInnerWaitQueue->addElement(iReqFloor);
		break;

	case Ele_DOWN_RUN:
		if(iReqFloor>m_TCB.m_iNextDestFloor) m_TCB.m_iNextDestFloor = iReqFloor;
		m_mycDownInnerWaitQueue->addElement(iReqFloor);
		break;

	}

	m_ElevatorBox.SetWindowText(stateDespArr[m_TCB.m_eCurState]);//改变电梯状态显示
	GetDlgItem(IDC_MYBUTTONS+iReqFloor-1)->EnableWindow(FALSE);

}


void CMyElevatorThread::OnDestroy() 
{
	CDialog::OnDestroy();

	// TODO: Add your message handler code here

	for(int i=0;i<MAX_FLOOR_NUM;i++)
	{
		delete m_pButton[i];
		delete m_pLabel[i];
	}




	KillTimer(1);KillTimer(2);

}

void CMyElevatorThread::OnBtnCreateFault() 
{
	// TODO: Add your control notification handler code here

	if(m_TCB.m_eCurState==Ele_UP_RUN || m_TCB.m_eCurState==Ele_DOWN_RUN)
	{
		AfxMessageBox(_T("电梯正在运行中,不允许出现故障!"));
		return;
	}
	if(m_TCB.m_iCurPassengerNum > 0)
	{
		AfxMessageBox(_T("电梯当前有乘客,不允许出现故障!"));
		return;
	}

	m_eOldState = m_TCB.m_eCurState;
	m_TCB.m_eCurState =MAL_FUNCTION;
	GetDlgItem(IDC_BUTTON_TROUBLE)->EnableWindow(FALSE);
	GetDlgItem(IDC_BUTTON_CORRECT)->EnableWindow(TRUE);
	m_ElevatorBox.SetWindowText(stateDespArr[m_TCB.m_eCurState]);//改变电梯状态显示
}

void CMyElevatorThread::OnBtnCorrectFault() 
{
	// TODO: Add your control notification handler code here
	m_TCB.m_eCurState =m_eOldState;
	GetDlgItem(IDC_BUTTON_TROUBLE)->EnableWindow(TRUE);
	GetDlgItem(IDC_BUTTON_CORRECT)->EnableWindow(FALSE);
	m_ElevatorBox.SetWindowText(stateDespArr[m_TCB.m_eCurState]);//改变电梯状态显示

}

void CMyElevatorThread::OnBtnPsgEnter() 
{
	// TODO: Add your control notification handler code here
	if(isOverWeight())
	{
		AfxMessageBox(_T("本电梯已达到最大负重,不能再进人。"));
		return;
	}

	m_TCB.m_iCurPassengerNum++;

	CString TempStr =_T(" ");
	TempStr.Format(_T("%d"),m_TCB.m_iCurPassengerNum);
	m_conPsgNum.SetWindowText(_T("内有人数:")+TempStr);

}

void CMyElevatorThread::OnBtnPsgLeave() 
{
	// TODO: Add your control notification handler code here
	if(m_TCB.m_iCurPassengerNum==0)
	{
		AfxMessageBox(_T("本电梯内当前无乘客。"));
		return;
	}

	m_TCB.m_iCurPassengerNum--;

	CString TempStr =_T(" ");
	TempStr.Format(_T("%d"),m_TCB.m_iCurPassengerNum);
	m_conPsgNum.SetWindowText(_T("内有人数:")+TempStr);

}


void CMyElevatorThread::enableRelateBtn(enum state eCurState, int iFloorNo)
{
	//Enable当前楼层按钮
	GetDlgItem(IDC_MYBUTTONS+iFloorNo-1)->EnableWindow(TRUE);

	//通知父窗体Enable该楼层按钮
	int tarFloorBtnID = (eCurState==Ele_UP_PAUSE) ? (2*(iFloorNo-1)) : (2*(iFloorNo-1)+1);

	m_pParent->SendMessage(WM_ARRIVE_ONEFLOOR,(WPARAM)tarFloorBtnID);

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -