Rev 331 | Rev 334 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
#include "controller.h"Controller::Controller (int num_floors, int num_elevators) : num_floors (num_floors), num_elevators (num_elevators){assert (num_floors > 2);assert (num_elevators > 0);elevators.reserve (num_elevators);for (int i=0; i<num_elevators; i++){elevators.push_back (Elevator (num_floors));elevators[i].set_controller (this);}}Controller::~Controller (){}void Controller::request_elevator (int on_floor, int direction){assert (on_floor <= num_floors);assert (on_floor > 0);assert (direction == MOVE_UP || direction == MOVE_DOWN);float distance = INT_MAX;int elevator_number;// check that there is not already an elevator requested// to this floor. If there is already one, ignore this// request.if (floor_already_requested (on_floor))return;// find elevator that is closest, AND NOT moving away// "push" it's buttonelevator_number = find_closest_elevator (on_floor, direction);elevators[elevator_number].push_button (on_floor);printf ("elevator[%d] gets queued for floor: %d\n", elevator_number, on_floor);}/*** Check if there is an elevator already in the queue to stop* at the floor given as a parameter.*/bool Controller::floor_already_requested (int on_floor){int i;for (i=0; i<num_elevators; i++)if (elevators[i].button_is_pushed (on_floor))return true;return false;}/*** Return the number of the closest elevator to the* floor given as a parameter.** We only want to choose elevators that are close and* heading in the right direction, or the closest elevator* if it is sitting idle.*/int Controller::find_closest_elevator (int to_floor, int in_direction){int i;float distance = INT_MAX;float temp_distance;int answer;float cur_floor;int direction;for (i=0; i<num_elevators; i++){cur_floor = elevators[i].get_current_floor ();direction = elevators[i].get_direction ();temp_distance = fabsf (cur_floor - to_floor);// Automatically discard elevators that are moving in the wrong// direction, but DO consider ones that are idle.if (direction != IDLE || direction != in_direction)continue;// Check that this elevator is closerif (temp_distance < distance){// If we are below the floor we want to go to and we// are moving up, then this is an ok choiceif (cur_floor < to_floor && direction == MOVE_UP){answer = i;distance = temp_distance;}// If we are above the floor we want to go to and we// are moving down, then this is an ok choiceelse if (cur_floor > to_floor && direction == MOVE_DOWN){answer = i;distance = temp_distance;}// If we are closest, but idle, then this is an ok choiceelse{answer = i;distance = temp_distance;}}}return answer;}void Controller::disable_elevator (int elevator_number){}void Controller::enable_elevator (int elevator_number){// make sure elevator is enabled first}void Controller::start_all_elevators (){int i;for (i=0; i<num_elevators; i++)elevators[i].thread_start ();}void Controller::stop_all_elevators (){int i;for (i=0; i<num_elevators; i++)elevators[i].thread_stop ();}void Controller::pause_all_elevators (){int i;for (i=0; i<num_elevators; i++)elevators[i].thread_pause ();}void Controller::unpause_all_elevators (){int i;for (i=0; i<num_elevators; i++)elevators[i].thread_unpause ();}