+ switch (s)
+ {
+ case STATE_IDLE:
+ sname = "STATE_IDLE";
+ break;
+ case STATE_UP:
+ sname = "STATE_UP";
+ break;
+ case STATE_DOWN:
+ sname = "STATE_DOWN";
+ break;
+ case STATE_WAIT:
+ sname = "STATE_WAIT";
+ break;
+ case STATE_OPEN_DOOR:
+ sname = "STATE_OPEN_DOOR";
+ break;
+ case STATE_CLOSE_DOOR:
+ sname = "STATE_CLOSE_DOOR";
+ break;
+ default:
+ sname = "BAD STATE";
+ break;
+ }
+
+ return sname;
+}
+
+static std::string get_event_name (Event e)
+{
+ std::string ename;
+
+ switch (e)
+ {
+ case EVT_IDLE:
+ ename = "EVT_IDLE";
+ break;
+ case EVT_UP:
+ ename = "EVT_UP";
+ break;
+ case EVT_DOWN:
+ ename = "EVT_DOWN";
+ break;
+ case EVT_WAIT:
+ ename = "EVT_WAIT";
+ break;
+ case EVT_OPEN_DOOR:
+ ename = "EVT_OPEN_DOOR";
+ break;
+ case EVT_CLOSE_DOOR:
+ ename = "EVT_CLOSE_DOOR";
+ break;
+ default:
+ ename = "BAD EVENT";
+ break;
+ }
+
+ return ename;
+}
+
+static void bad_transition (State s, Event e)
+{
+ std::cout << "Bad State Transition: " << get_state_name (s)
+ << " -> " << get_event_name (e) << std::endl;
+}
+
+Event Elevator::find_next_event () const
+{
+ /* Calculate the number of Stops above and below our
+ * current position */
+ StopList::const_iterator it;
+ Stop current = Stop(position_, direction_);
+ int stops_above = 0;
+ int stops_below = 0;
+
+ for (it = stops_.begin(); it != stops_.end(); it++)
+ {
+ if (current < *it)
+ ++stops_above;
+
+ if (current > *it)
+ ++stops_below;
+ }
+
+ /* Now figure out which state transition to make */
+ switch (state_)
+ {
+ case STATE_IDLE:
+
+ if (currently_at_stop ())
+ return EVT_OPEN_DOOR;
+
+ if (stops_above > 0)
+ return EVT_UP;
+
+ if (stops_below > 0)
+ return EVT_DOWN;
+
+ return EVT_IDLE;
+
+ break;
+ case STATE_UP:
+
+ if (currently_at_stop ())
+ return EVT_OPEN_DOOR;
+
+ return EVT_UP;
+
+ break;
+ case STATE_DOWN:
+
+ if (currently_at_stop ())
+ return EVT_OPEN_DOOR;
+
+ return EVT_DOWN;
+
+ break;
+ case STATE_WAIT:
+
+ if (wait_ > 0)
+ return EVT_WAIT;
+
+ return EVT_CLOSE_DOOR;
+
+ break;
+ case STATE_OPEN_DOOR:
+
+ return EVT_WAIT;
+
+ break;
+ case STATE_CLOSE_DOOR:
+
+ if (currently_at_stop ())
+ return EVT_OPEN_DOOR;
+
+ if (direction_ == UP && stops_above > 0)
+ return EVT_UP;
+
+ if (direction_ == DOWN && stops_below > 0)
+ return EVT_DOWN;
+
+ /* We need to switch directions */
+ if (direction_ == UP && stops_above == 0 && stops_below > 0)
+ return EVT_DOWN;
+
+ if (direction_ == DOWN && stops_below == 0 && stops_above > 0)
+ return EVT_UP;
+
+ return EVT_IDLE;
+
+ break;
+ default:
+ std::cout << "find_next_event(): Bad State" << std::endl;
+ break;
+ }
+}
+
+void Elevator::move ()
+{
+ /* Generate Events */
+ Event e = find_next_event ();
+
+ std::cout << "State Transition: " << get_state_name (state_) << " with "
+ << get_event_name (e) << std::endl;
+
+ switch (state_)
+ {
+ case STATE_IDLE:
+ switch (e)
+ {
+ case EVT_UP:
+ state_ = STATE_UP;
+ transition_move_up ();
+ break;
+ case EVT_DOWN:
+ state_ = STATE_DOWN;
+ transition_move_down ();
+ break;
+ case EVT_IDLE:
+ state_ = STATE_IDLE;
+ transition_move_idle ();
+ break;
+ case EVT_OPEN_DOOR:
+ state_ = STATE_OPEN_DOOR;
+ transition_open_door ();
+ break;
+ default:
+ bad_transition (state_, e);
+ break;
+ } // end switch (e)
+ break;
+
+ case STATE_UP:
+ switch (e)
+ {
+ case EVT_UP:
+ state_ = STATE_UP;
+ transition_move_up ();
+ break;
+ case EVT_OPEN_DOOR:
+ state_ = STATE_OPEN_DOOR;
+ transition_open_door ();
+ break;
+ default:
+ bad_transition (state_, e);
+ break;
+ } // end switch (e)
+ break;
+
+ case STATE_DOWN:
+ switch (e)
+ {
+ case EVT_DOWN:
+ state_ = STATE_DOWN;
+ transition_move_down ();
+ break;
+ case EVT_OPEN_DOOR:
+ state_ = STATE_OPEN_DOOR;
+ transition_open_door ();
+ break;
+ default:
+ bad_transition (state_, e);
+ break;
+ } // end switch (e)
+ break;
+
+ case STATE_WAIT:
+ switch (e)
+ {
+ case EVT_WAIT:
+ state_ = STATE_WAIT;
+ transition_continue_wait ();
+ break;
+ case EVT_CLOSE_DOOR:
+ state_ = STATE_CLOSE_DOOR;
+ transition_close_door ();
+ break;
+ default:
+ bad_transition (state_, e);
+ break;
+ } // end switch (e)
+ break;
+
+ case STATE_OPEN_DOOR:
+ switch (e)
+ {
+ case EVT_WAIT:
+ state_ = STATE_WAIT;
+ transition_begin_wait ();
+ break;
+ default:
+ bad_transition (state_, e);
+ break;
+ } // end switch (e)
+ break;
+
+ case STATE_CLOSE_DOOR:
+ switch (e)
+ {
+ case EVT_OPEN_DOOR:
+ state_ = STATE_OPEN_DOOR;
+ transition_open_door ();
+ break;
+ case EVT_UP:
+ state_ = STATE_UP;
+ transition_move_up ();
+ break;
+ case EVT_DOWN:
+ state_ = STATE_DOWN;
+ transition_move_down ();
+ break;
+ case EVT_IDLE:
+ state_ = STATE_IDLE;
+ transition_move_idle ();
+ break;
+ default:
+ bad_transition (state_, e);
+ break;
+ } // end switch (e)
+ break;
+
+ default:
+ std::cout << "Bad State: " << get_state_name (state_) << std::endl;
+ break;
+ }
+}
+
+bool Elevator::is_idle () const
+{
+ return direction_ == IDLE;
+}