Subversion Repositories programming

Rev

Rev 331 | Rev 334 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
321 ira 1
 
2
#include "controller.h"
3
 
4
Controller::Controller (int num_floors, int num_elevators) : num_floors (num_floors), num_elevators (num_elevators)
5
{
6
    assert (num_floors > 2);
7
    assert (num_elevators > 0);
8
 
332 ira 9
    elevators.reserve (num_elevators);
331 ira 10
 
11
    for (int i=0; i<num_elevators; i++)
332 ira 12
    {
13
        elevators.push_back (Elevator (num_floors));
331 ira 14
        elevators[i].set_controller (this);
332 ira 15
    }
321 ira 16
}
17
 
18
Controller::~Controller ()
19
{
20
}
21
 
329 ira 22
void Controller::request_elevator (int on_floor, int direction)
321 ira 23
{
328 ira 24
    assert (on_floor <= num_floors);
25
    assert (on_floor > 0);
331 ira 26
    assert (direction == MOVE_UP || direction == MOVE_DOWN);
328 ira 27
 
28
    float distance = INT_MAX;
29
    int elevator_number;
30
 
31
    // check that there is not already an elevator requested
32
    // to this floor. If there is already one, ignore this
33
    // request.
34
    if (floor_already_requested (on_floor))
35
        return;
36
 
37
    // find elevator that is closest, AND NOT moving away
38
    // "push" it's button
332 ira 39
    elevator_number = find_closest_elevator (on_floor, direction);
328 ira 40
    elevators[elevator_number].push_button (on_floor);
332 ira 41
 
42
    printf ("elevator[%d] gets queued for floor: %d\n", elevator_number, on_floor);
321 ira 43
}
44
 
328 ira 45
/**
46
 * Check if there is an elevator already in the queue to stop
47
 * at the floor given as a parameter.
48
 */
49
bool Controller::floor_already_requested (int on_floor)
50
{
51
    int i;
52
 
53
    for (i=0; i<num_elevators; i++)
54
        if (elevators[i].button_is_pushed (on_floor))
55
            return true;
56
 
57
    return false;
58
}
59
 
60
/**
61
 * Return the number of the closest elevator to the
62
 * floor given as a parameter.
63
 *
64
 * We only want to choose elevators that are close and
65
 * heading in the right direction, or the closest elevator
66
 * if it is sitting idle.
67
 */
332 ira 68
int Controller::find_closest_elevator (int to_floor, int in_direction)
328 ira 69
{
70
    int i;
71
    float distance = INT_MAX;
72
    float temp_distance;
73
    int answer;
74
 
75
    float cur_floor;
76
    int direction;
77
 
78
    for (i=0; i<num_elevators; i++)
79
    {
80
        cur_floor = elevators[i].get_current_floor ();
81
        direction = elevators[i].get_direction ();
82
        temp_distance = fabsf (cur_floor - to_floor);
83
 
332 ira 84
        // Automatically discard elevators that are moving in the wrong
85
        // direction, but DO consider ones that are idle.
86
        if (direction != IDLE || direction != in_direction)
87
            continue;
88
 
328 ira 89
        // Check that this elevator is closer
90
        if (temp_distance < distance)
91
        {
92
            // If we are below the floor we want to go to and we
93
            // are moving up, then this is an ok choice
94
            if (cur_floor < to_floor && direction == MOVE_UP)
95
            {
96
                answer = i;
97
                distance = temp_distance;
98
            }
99
            // If we are above the floor we want to go to and we
100
            // are moving down, then this is an ok choice
101
            else if (cur_floor > to_floor && direction == MOVE_DOWN)
102
            {
103
                answer = i;
104
                distance = temp_distance;
105
            }
106
            // If we are closest, but idle, then this is an ok choice
107
            else
108
            {
109
                answer = i;
110
                distance = temp_distance;
111
            }
112
        }
113
    }
114
 
115
    return answer;
116
}
117
 
329 ira 118
void Controller::disable_elevator (int elevator_number)
119
{
120
}
121
 
122
void Controller::enable_elevator (int elevator_number)
123
{
124
    // make sure elevator is enabled first
125
}
126
 
331 ira 127
void Controller::start_all_elevators ()
128
{
129
    int i;
130
 
131
    for (i=0; i<num_elevators; i++)
132
        elevators[i].thread_start ();
133
}
134
 
135
void Controller::stop_all_elevators ()
136
{
137
    int i;
138
 
139
    for (i=0; i<num_elevators; i++)
140
        elevators[i].thread_stop ();
141
}
142
 
143
void Controller::pause_all_elevators ()
144
{
145
    int i;
146
 
147
    for (i=0; i<num_elevators; i++)
148
        elevators[i].thread_pause ();
149
}
150
 
151
void Controller::unpause_all_elevators ()
152
{
153
    int i;
154
 
155
    for (i=0; i<num_elevators; i++)
156
        elevators[i].thread_unpause ();
157
}
158