#include "stdafx.h" #include #ifdef _DEBUG #define new DEBUG_NEW #endif CTrain::CTrain( CNetwork* Net, TTrainID number, int ID, CStation* Station): TObject(TypeIsTrain,ID, theNetwork->NetEvents) { Distance = 0.0; Capacity = 500; Passengers = GetRandom(0,200); Number = number; Network = Net; Departing = Station; Arriving = Net->GetNextStation(Station); Location = 0; h_thread = NULL; } CTrain::~CTrain() { if(h_thread) CloseHandle(h_thread); } BOOL CTrain::AtStation() { return (BOOL)(Location == 0); } void CTrain::Create() { h_thread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)&CTrain::Execute,this,0,&m_tid); } DWORD __stdcall CTrain::Execute(CTrain* Train) { return Train->Run(); } DWORD CTrain::Embark(int PeopleON) { if(Passengers + PeopleON > Capacity) PeopleON = Capacity - Passengers; if(PeopleON > 0) { Passengers += PeopleON; return PeopleON * 20; } return 0; } DWORD CTrain::Disembark(int PeopleOFF) { if(Passengers - PeopleOFF > -1) Passengers -= PeopleOFF; else Passengers = 0; if(PeopleOFF > 0) return PeopleOFF * 20; return 0; } void CTrain::OnDeparting(CStation* S) { Arriving = Network->GetNextStation(S); } DWORD CTrain::OnArrival( CStation* S) { Departing = S; Location = 0; Delay = (Disembark(GetRandom()) + Embark(GetRandom())); DWORD ScheduleTime = Network->TimeAtStation(Departing); if(Delay > (int)ScheduleTime) return Delay; return ScheduleTime; } DWORD CTrain::Run() { if(Network->Stations.size() < 2) return 1; srand( (unsigned)time( NULL ) ); int wait = 0; Location = 0; bool bNextDeparture=true; while(!IsSet(TERMINATE_EVENT)) { int idleB = Network->GetSpeed(); Sleep(idleB); wait = 0; try { theLock.Lock(); if(Location == 0) { Arriving = Network->GetNextStation(Departing); } Location += 1; if(bNextDeparture) { bNextDeparture=false; OnDeparting(Departing); } if(GetLocation() > Network->RailPoints.size()) Location = Departing->Location * -1; CStation* S = Network->GetStation(GetLocation()); if(S && S != Departing) { wait = OnArrival(S); bNextDeparture=true;; } theLock.Unlock(); Network->SendMessage(WM_SUBWAY,Ident,0); // if run or stop is set continue WaitForMultipleObjects( 2, Events, false, INFINITE); } catch(...) { theLock.Unlock(); } } return 1; } void CTrain::Stop() { } void CTrain::Start() { } void CTrain::Exit() { } int CTrain::GetRandom(int RangeMin, int RangeMax) { int R = (int)(((double) rand() / (double) RangeMax) * RangeMax + RangeMin); while(R > RangeMax) { R /= RangeMax; } R += RangeMin; return R; }