/*-------------------------------------------------------------------------*
*--- ---*
*--- airport.cpp ---*
*--- ---*
*--- This program simulates the approach, landing, servicing, ---*
*--- and taking off of several flights. Each flight is in its own ---*
*--- thread, and is to be handled in a thread-safe fashion. ---*
*--- ---*
*--- ---- ---- ---- ---- ---- ---- ---- ---- ---*
*--- ---*
*--- Version 1.0 2018 August 1 Joseph Phillips ---*
*--- ---*
*-------------------------------------------------------------------------*/
//
// Compile with: g++ airport.cpp -o airport -lpthread
//
#include <cstdlib>
#include <cstdio>
#include <string>
#include <iostream>
#include <pthread.h>
#include <queue>
using namespace std;
// PURPOSE: To hold the names of the various airlines
const char* AIRLINE_NAME_ARRAY[]
= {"Air No Cares",
"Fly-By-Nite",
"Pterodactyl",
"SwineAir",
"Flying Toaster",
"Do You Dare Air",
"Air Montgolfier",
"Luft Zeppelin"
};
// PURPOSE: To tell how many elements are in array 'AIRLINE_NAME_ARRAY[]'.
const int NUM_AIRLINES = sizeof(AIRLINE_NAME_ARRAY)
/ sizeof(const char*);
// PURPOSE: To tell how many Flight instances need to be serviced.
const int NUM_FLIGHTS = 32;
// PURPOSE: To represent instances of a flight.
class Flight
{
// I. Member vars:
// PURPOSE: To tell the name of flight.
string name_;
// II. Disallowed auto-generated methods:
protected :
// III. Protected methods:
public :
// IV. Constructor(s), assignment op(s), factory(s) and destructor:
// PURPOSE: To randomly generate a flight. No parameters. No return value.
Flight ()
{
char text[64];
snprintf(text,64,"%s %d",
AIRLINE_NAME_ARRAY[rand() % NUM_AIRLINES],
(rand() % 9999)+1
);
name_ = text;
}
// PURPOSE: To make '*this' a copy of 'source'. No return value.
Flight (const Flight& source
) :
name_(source.getName())
{ }
// PURPOSE: To release the resources of '*this', make '*this' a copy of
// 'source', and return a reference to '*this'. No return value.
Flight& operator= (const Flight& source
)
{
// I. Application validity check:
if (this == &source)
return(*this);
// II. Release resources:
// III. Copy 'source':
name_ = source.getName();
// IV. Finished:
return(*this);
}
// PURPOSE: To release the resources of '*this'. No parameters. No return
// value.
~Flight ()
{
}
// V. Accessors:
// PURPOSE: To return the name of the Flight.
const string& getName ()
const
{
return(name_);
}
};
// PURPOSE: To output Flight instance 'flight' to 'os'. Returns reference to
// 'os'.
ostream& operator<< (ostream& os,
const Flight& flight
)
{
os << flight.getName();
return(os);
}
// PURPOSE: To represent the various places that a limited number of Flight
// instances could be.
typedef enum
{
HOLDING_PATTERN_FLIGHT_AREA,
LANDING_RUNWAY_FLIGHT_AREA,
TERMINAL_FLIGHT_AREA,
TAKE_OFF_RUNWAY_FLIGHT_AREA
}
flightArea_t;
// PURPOSE: To represent the various places that a limited number of Flight
// instances could be.
class FlightArea
{
// I. Member vars:
// PURPOSE: To tell what type of flight area this is.
flightArea_t type_;
// PURPOSE: To tell the capacity.
int capacity_;
// PURPOSE: To hold pointers to the Flight instances.
queue<Flight> flightQueue_;
// YOUR CODE HERE:
// II. Disallowed auto-generated methods:
// No default constructor:
FlightArea ();
// No copy constructor:
FlightArea (const FlightArea&
);
// No copy assignment op:
FlightArea& operator= (const FlightArea&
);
protected :
// III. Protected methods:
// PURPOSE: To return the name of '*this' FlightArea. No parameters.
string getName ()
const
{
const char* cPtr;
switch (type_)
{
case HOLDING_PATTERN_FLIGHT_AREA :
cPtr = "holding pattern";
break;
case LANDING_RUNWAY_FLIGHT_AREA :
cPtr = "landing runway";
break;
case TERMINAL_FLIGHT_AREA :
cPtr = "terminal";
break;
case TAKE_OFF_RUNWAY_FLIGHT_AREA :
cPtr = "take-off runway";
break;
}
return(string(cPtr));
}
// PURPOSE: To return the text when a Flight should stay out while it is
// waiting to enter '*this' FlightArea. No parameters.
string getHoldText ()
const
{
const char* cPtr;
switch (type_)
{
case HOLDING_PATTERN_FLIGHT_AREA :
cPtr = "stay in the 20,000 foot holding pattern";
break;
case LANDING_RUNWAY_FLIGHT_AREA :
cPtr = "stay in the 10,000 foot holding pattern";
break;
case TERMINAL_FLIGHT_AREA :
cPtr = "stay in one the landing runway";
break;
case TAKE_OFF_RUNWAY_FLIGHT_AREA :
cPtr = "stay at the terminal";
break;
}
return(string(cPtr));
}
// PURPOSE: To return the text when a Flight may enter '*this' FlightArea.
// No parameters.
string getEnterText ()
const
{
const char* cPtr;
switch (type_)
{
case HOLDING_PATTERN_FLIGHT_AREA :
cPtr = "enter the holding pattern";
break;
case LANDING_RUNWAY_FLIGHT_AREA :
cPtr = "land";
break;
case TERMINAL_FLIGHT_AREA :
cPtr = "taxi to the terminal";
break;
case TAKE_OFF_RUNWAY_FLIGHT_AREA :
cPtr = "take off";
break;
}
return(string(cPtr));
}
// PURPOSE: To return the text when a Flight should leave '*this'
// FlightArea. No parameters.
string getLeaveText ()
const
{
const char* cPtr;
switch (type_)
{
case HOLDING_PATTERN_FLIGHT_AREA :
cPtr = "make your final approach";
break;
case LANDING_RUNWAY_FLIGHT_AREA :
cPtr = "clear the runway for other flights";
break;
case TERMINAL_FLIGHT_AREA :
cPtr = "refuel safely";
break;
case TAKE_OFF_RUNWAY_FLIGHT_AREA :
cPtr = "have a safe flight";
break;
}
return(string(cPtr));
}
public :
// IV. Constructor(s), assignment op(s), factory(s) and destructor:
// PURPOSE: To initialize '*this' FlightArea to have type 'newType' and
// to be allowed to hold 'newCapacity' simultaneous Flight instances. No
// return value.
FlightArea (flightArea_t newType,
int newCapacity
) :
type_(newType),
capacity_(newCapacity),
flightQueue_()
{
// YOUR CODE HERE:
}
// PURPOSE: To release the resources of '*this'. No parameters. No return
// value.
~FlightArea ()
{
// YOUR CODE HERE:
}
// V. Accessors:
// PURPOSE: To return 'true' if '*this' FlightArea is full with Flight
// instances, or 'false' otherwise.
bool isFull ()
const
{
return(flightQueue_.size() == capacity_);
}
// VI. Mutators:
// VII. Methods that do main and misc. work of class:
// PURPOSE: To let Flight 'flight' begin to enter '*this' FlightArea. No
// return value.
void enter (const Flight& flight
)
{
// YOUR CODE IN HERE, SOMEWHERE:
while ( isFull() )
{
cout << "Air Traffic Control: "Flight "" << flight