Listing 4 Simulation of a medical clinic

#include "sim.hpp"
#include ...
#define nmbrOfPhysicians       4
#define openingHours           480.0
#define openPeriod             480.0
#define consultationLow        5.0
#define consultationHigh       20.0
#define arrivalsExpected       0.25

float treatmentPeriod(void)
{       return(fUniform(consultationLow,consultationHigh));
}

float periodBeforeNextArrival(void)
{       return(fNegexp(arrivalsExpected)); }

class clinic : public process
{public:chain lunchRoom,waitingRoom;
       float closingTime,totalWaitingTime;
       int totalNmbrOfPatients;
       clinic(int nrOfPhysicians,float Period);
       void main(void);
};

class physician : public process
{       clinic* theClinic;
public: physician(clinic* cl)   {theClinic=cl;}
       void main(void);
};

class patient : public process
{       clinic *theClinic;
public: float startWaitingAt,startTreatmentAt,
       finishedAt;
       patient(clinic* cl)    {theClinic=cl;}
       void main(void);
};

clinic::clinic(int nrOfPhysicians, float Period)
{       int i;
       totalWaitingTime=0.0;
       totalNmbrOfPatients=0;
       closingTime=currentTime() + Period;
       for (i=0;i<nrOfPhysicians;i++)
         activate(new physician(this),currentTime());
}

void clinic::main(void)
{       patient* ptnt;
       physician* phsn;
       hold(periodBeforeNextArrival());
       while (currentTime() < closingTime)
       {   ptnt=new patient(this);
          totalNmbrOfPatients++;
          waitingRoom.append(ptnt);
          activate(ptnt,currentTime());
          if (!lunchRoom.empty())
              {  phsn=(physician*)lunchRoom.
                    getfirst();
                 activate(phsn,currentTime());
              }
          hold(periodBeforeNextArrival());
       }
}

void physician::main(void)
{       patient *ptnt;
       while(1)
       {   if (theClinic->waitingRoom.empty())
           {   theClinic->lunchRoom.append(this);
               passivate();
           }
           else
           {    ptnt=(patient*)theClinic->waitingRoom.getfirst();
                activate(ptnt,currentTime());
                hold(treatmentPeriod());
                activate(ptnt,currentTime());
           }
       }
}

void patient::main(void)
{
       startWaitingAt=currentTime();
       passivate();
       startTreatmentAt=currentTime();
       passivate();
       finishedAt=currentTime();
       theClinic->totalWaitingTime+=
          (startTreatmentAt-startWaitingAt);
}

void main(void)
{       clinic *clnc;
       initRandom();
       initProcesses();
       hold(openingHours - currentTime());
       activate(clnc=new clinic(
          nmbrOfPhysicians,openPeriod),
          currentTime());
       hold(10000.0);
       cout << "Total number of patients ="
           << clnc->totalNmbrOfPatients << end1;
       cout << "Average waiting time     ="
           << clnc->totalWaitingTime/
                 clnc->totalNmbrOfPatients << end1;
}

// End of File