diff --git a/cmat/Ex42/Observer.h b/cmat/Ex42/Observer.h index b55a19e..ff161f5 100644 --- a/cmat/Ex42/Observer.h +++ b/cmat/Ex42/Observer.h @@ -1,10 +1,12 @@ - -#ifndef OBSERVER_H -#define OBSERVER_H - -class Observer { - public: - virtual void update() = 0; -}; - -#endif + +#ifndef OBSERVER_H +#define OBSERVER_H + +class Hint; + +class Observer { + public: + virtual void update(const Hint&) = 0; +}; + +#endif diff --git a/cmat/Ex42/Pelican.cpp b/cmat/Ex42/Pelican.cpp index 8cde63a..2463ead 100644 --- a/cmat/Ex42/Pelican.cpp +++ b/cmat/Ex42/Pelican.cpp @@ -1,55 +1,57 @@ - - -#include "Pelican.h" -#include "PelicanTimer.h" - -Pelican::Pelican() : pressed(false), RED_TIME(4), YELLOW_TIME(2), GREEN_TIME(3), FLASH_TIME(5), state(GREEN_IDLE) { - myTimer = new PelicanTimer(*this, &Pelican::timerExpired); -} - -void Pelican::press(void) { - if (state == GREEN_IDLE) { - state = YELLOW_STATE; - myTimer->timeoutRequest(YELLOW_TIME); - pressed = true; - notify(); - } else if (state != RED_STATE) { - pressed = true; - notify(); - } -} - -void Pelican::timerExpired(void) { - switch (state) { - case RED_STATE: - state = YELLOW_FLASHING; - myTimer->timeoutRequest(FLASH_TIME); - break; - - case YELLOW_FLASHING: - state = GREEN_TIMING; - myTimer->timeoutRequest(GREEN_TIME); - break; - - case GREEN_TIMING: - if (pressed) { - state = YELLOW_STATE; - myTimer->timeoutRequest(YELLOW_TIME); - } else { - state = GREEN_IDLE; - } - break; - - case GREEN_IDLE: - // should never happen - break; - - case YELLOW_STATE: - state = RED_STATE; - pressed = false; - myTimer->timeoutRequest(RED_TIME); - break; - } - - notify(); -} + + +#include "Pelican.h" +#include "PelicanTimer.h" +#include "Subject.h" + +Pelican::Pelican() : pressed(false), RED_TIME(4), YELLOW_TIME(2), GREEN_TIME(3), FLASH_TIME(5), state(GREEN_IDLE) { + myTimer = new PelicanTimer(*this, &Pelican::timerExpired); +} + +void Pelican::press(void) { + if (state == GREEN_IDLE) { + state = YELLOW_STATE; + myTimer->timeoutRequest(YELLOW_TIME); + pressed = true; + } else if (state != RED_STATE) { + pressed = true; + } + notify(LightHint(state)); + notify(WaitHint(pressed)); +} + +void Pelican::timerExpired(void) { + switch (state) { + case RED_STATE: + state = YELLOW_FLASHING; + myTimer->timeoutRequest(FLASH_TIME); + break; + + case YELLOW_FLASHING: + state = GREEN_TIMING; + myTimer->timeoutRequest(GREEN_TIME); + break; + + case GREEN_TIMING: + if (pressed) { + state = YELLOW_STATE; + myTimer->timeoutRequest(YELLOW_TIME); + } else { + state = GREEN_IDLE; + } + break; + + case GREEN_IDLE: + // should never happen + break; + + case YELLOW_STATE: + state = RED_STATE; + pressed = false; + myTimer->timeoutRequest(RED_TIME); + break; + } + + notify(LightHint(state)); + notify(WaitHint(pressed)); +} diff --git a/cmat/Ex42/Pelican.h b/cmat/Ex42/Pelican.h index 6527cd5..5a26229 100644 --- a/cmat/Ex42/Pelican.h +++ b/cmat/Ex42/Pelican.h @@ -1,51 +1,63 @@ -// ====================================================== -// -// Represents a Pelican crossing -// -// ====================================================== - -#ifndef PELICAN_H -#define PELICAN_H - -#include "Subject.h" - -class PelicanTimer; - -class Pelican : public Subject { - public: - Pelican(); - - // call when the WAIT button has been pressed - void press(void); - - // states that a Pelican can be in - enum PelicanState { RED_STATE, YELLOW_FLASHING, GREEN_TIMING, GREEN_IDLE, YELLOW_STATE }; - - bool isPressed() const { return pressed; } - PelicanState getState() const { return state; } - - private: - // state that this Pelican is in - PelicanState state; - - // called by PelicanTimer when the lights need to change - void timerExpired(void); - - const unsigned int RED_TIME; - const unsigned int YELLOW_TIME; - const unsigned int GREEN_TIME; - const unsigned int FLASH_TIME; - - // indicates whether the WAIT light should be on - bool pressed; - - // Timer that indicates when the lights should change - PelicanTimer *myTimer; - - private: - // prevent general use of copy ctor and operator= - Pelican(const Pelican &); - Pelican &operator=(const Pelican &); -}; - -#endif +// ====================================================== +// +// Represents a Pelican crossing +// +// ====================================================== + +#ifndef PELICAN_H +#define PELICAN_H + +#include "Subject.h" + +class PelicanTimer; + +class Pelican : public Subject { + public: + Pelican(); + + // call when the WAIT button has been pressed + void press(void); + + // states that a Pelican can be in + enum PelicanState { RED_STATE, YELLOW_FLASHING, GREEN_TIMING, GREEN_IDLE, YELLOW_STATE }; + + bool isPressed() const { return pressed; } + PelicanState getState() const { return state; } + + private: + // state that this Pelican is in + PelicanState state; + + // called by PelicanTimer when the lights need to change + void timerExpired(void); + + const unsigned int RED_TIME; + const unsigned int YELLOW_TIME; + const unsigned int GREEN_TIME; + const unsigned int FLASH_TIME; + + // indicates whether the WAIT light should be on + bool pressed; + + // Timer that indicates when the lights should change + PelicanTimer *myTimer; + + private: + // prevent general use of copy ctor and operator= + Pelican(const Pelican &); + Pelican &operator=(const Pelican &); +}; + +class LightHint : public Hint { + public: + LightHint(Pelican::PelicanState s) : state(s) { } + Pelican::PelicanState state; +}; + +class WaitHint : public Hint { + public: + WaitHint (bool p) : pressed(p) {} + bool pressed; +}; + +#endif diff --git a/cmat/Ex42/Pole.cpp b/cmat/Ex42/Pole.cpp index fdf9826..8d0240a 100644 --- a/cmat/Ex42/Pole.cpp +++ b/cmat/Ex42/Pole.cpp @@ -1,68 +1,80 @@ -#include "Pole.h" -#include "Screen.h" - -Pole::Pole(int x, int y, Pelican &p) : waitLight(new Light("WAIT", x + 6, y + 12, Screen::WHITE)), myPelican(p) { - myPelican.attach(*this); - - using namespace Screen; // we will discuss namespaces in the course - - lights[RED_LIGHT] = new Light("*", x + 11, y + 3, RED); - lights[RED_MAN] = new Light("*<-=", x + 6, y + 4, RED); - lights[YELLOW_LIGHT] = new Light("*", x + 11, y + 5, YELLOW); - lights[GREEN_LIGHT] = new Light("*", x + 11, y + 7, GREEN); - lights[GREEN_MAN] = new Light("*|-<", x + 6, y + 7, GREEN); - - write(" _____ ", x, ++y, GRAY); - write(" /___ /| ", x, ++y, GRAY); - write(" | | | ", x, ++y, GRAY); - write(" | |/| ", x, ++y, GRAY); - write(" |____| | ", x, ++y, GRAY); - write(" | |/| ", x, ++y, GRAY); - write(" | | | ", x, ++y, GRAY); - write(" |____|/ ", x, ++y, GRAY); - write(" _||__ ", x, ++y, GRAY); - write(" /___ /| ", x, ++y, GRAY); - write(" | | | ", x, ++y, GRAY); - write(" | | | ", x, ++y, GRAY); - write(" |____|/ ", x, ++y, GRAY); - write(" || ", x, ++y, GRAY); - write(" || ", x, ++y, GRAY); - write(" || ", x, ++y, GRAY); - write(" || ", x, ++y, GRAY); - write(" || ", x, ++y, GRAY); - write(" || ", x, ++y, GRAY); - write("========||===========", x, ++y, GRAY); - write(" / || / ", x, ++y, GRAY); - write("_ /_________ /_ ", x, ++y, GRAY); - write("/ / ", x, ++y, GRAY); - - update(); -} - -Pole::~Pole() { - for (int i = 0; i < sizeof lights / sizeof(lights[0]); ++i) - delete lights[i]; - delete waitLight; -} - -void Pole::setTrafficLights(Pelican::PelicanState state) { - static const Light::LightState LightStates[Pelican::YELLOW_STATE + 1][RED_MAN + 1] = { - // red yellow green green man red man - {Light::ON, Light::OFF, Light::OFF, Light::ON, Light::OFF}, // red - {Light::OFF, Light::FLASH, Light::OFF, Light::FLASH, Light::OFF}, // y flash - {Light::OFF, Light::OFF, Light::ON, Light::OFF, Light::ON}, // g time - {Light::OFF, Light::OFF, Light::ON, Light::OFF, Light::ON}, // g idle - {Light::OFF, Light::ON, Light::OFF, Light::OFF, Light::ON} // yellow - }; - - for (int i = RED_LIGHT; i <= RED_MAN; i++) { - lights[i]->set(LightStates[state][i]); - } -} - -void Pole::setWaitLight(bool pressed) { waitLight->set(pressed ? Light::ON : Light::OFF); } - -void Pole::update() { - setTrafficLights(myPelican.getState()); - setWaitLight(myPelican.isPressed()); -} +#include "Pole.h" +#include "Pelican.h" +#include "Screen.h" + +#include + +Pole::Pole(int x, int y, Pelican &p) : waitLight(new Light("WAIT", x + 6, y + 12, Screen::WHITE)), myPelican(p) { + myPelican.attach(*this); + + using namespace Screen; // we will discuss namespaces in the course + + lights[RED_LIGHT] = new Light("*", x + 11, y + 3, RED); + lights[RED_MAN] = new Light("*<-=", x + 6, y + 4, RED); + lights[YELLOW_LIGHT] = new Light("*", x + 11, y + 5, YELLOW); + lights[GREEN_LIGHT] = new Light("*", x + 11, y + 7, GREEN); + lights[GREEN_MAN] = new Light("*|-<", x + 6, y + 7, GREEN); + + write(" _____ ", x, ++y, GRAY); + write(" /___ /| ", x, ++y, GRAY); + write(" | | | ", x, ++y, GRAY); + write(" | |/| ", x, ++y, GRAY); + write(" |____| | ", x, ++y, GRAY); + write(" | |/| ", x, ++y, GRAY); + write(" | | | ", x, ++y, GRAY); + write(" |____|/ ", x, ++y, GRAY); + write(" _||__ ", x, ++y, GRAY); + write(" /___ /| ", x, ++y, GRAY); + write(" | | | ", x, ++y, GRAY); + write(" | | | ", x, ++y, GRAY); + write(" |____|/ ", x, ++y, GRAY); + write(" || ", x, ++y, GRAY); + write(" || ", x, ++y, GRAY); + write(" || ", x, ++y, GRAY); + write(" || ", x, ++y, GRAY); + write(" || ", x, ++y, GRAY); + write(" || ", x, ++y, GRAY); + write("========||===========", x, ++y, GRAY); + write(" / || / ", x, ++y, GRAY); + write("_ /_________ /_ ", x, ++y, GRAY); + write("/ / ", x, ++y, GRAY); + + setTrafficLights(myPelican.getState()); + setWaitLight(myPelican.isPressed()); +} + +Pole::~Pole() { + for (int i = 0; i < sizeof lights / sizeof(lights[0]); ++i) + delete lights[i]; + delete waitLight; +} + +void Pole::setTrafficLights(Pelican::PelicanState state) { + static const Light::LightState LightStates[Pelican::YELLOW_STATE + 1][RED_MAN + 1] = { + // red yellow green green man red man + {Light::ON, Light::OFF, Light::OFF, Light::ON, Light::OFF}, // red + {Light::OFF, Light::FLASH, Light::OFF, Light::FLASH, Light::OFF}, // y flash + {Light::OFF, Light::OFF, Light::ON, Light::OFF, Light::ON}, // g time + {Light::OFF, Light::OFF, Light::ON, Light::OFF, Light::ON}, // g idle + {Light::OFF, Light::ON, Light::OFF, Light::OFF, Light::ON} // yellow + }; + + for (int i = RED_LIGHT; i <= RED_MAN; i++) { + lights[i]->set(LightStates[state][i]); + } +} + +void Pole::setWaitLight(bool pressed) { waitLight->set(pressed ? Light::ON : Light::OFF); } + +void Pole::update(const Hint& hint) { + const WaitHint* waitHintPtr; + waitHintPtr = dynamic_cast(&hint); + const LightHint* lightHintPtr; + lightHintPtr = dynamic_cast(&hint); + if (waitHintPtr != nullptr) { + setWaitLight(waitHintPtr->pressed); + } + if (lightHintPtr != nullptr) { + setTrafficLights(lightHintPtr->state); + } +} diff --git a/cmat/Ex42/Pole.h b/cmat/Ex42/Pole.h index 674fbfe..2386f61 100644 --- a/cmat/Ex42/Pole.h +++ b/cmat/Ex42/Pole.h @@ -1,28 +1,28 @@ - -#ifndef POLE_H -#define POLE_H - -#include "Light.h" -#include "Observer.h" -#include "Pelican.h" - -class Pole : public Observer { - public: - Pole(int x, int y, Pelican &p); - ~Pole(); - - void setTrafficLights(Pelican::PelicanState state); - void setWaitLight(bool pressed); - - void update(); - - private: - Pelican &myPelican; - - enum LightName { RED_LIGHT, YELLOW_LIGHT, GREEN_LIGHT, GREEN_MAN, RED_MAN }; - - Light *lights[RED_MAN + 1]; - Light *waitLight; -}; - -#endif + +#ifndef POLE_H +#define POLE_H + +#include "Light.h" +#include "Observer.h" +#include "Pelican.h" + +class Pole : public Observer { + public: + Pole(int x, int y, Pelican &p); + ~Pole(); + + void setTrafficLights(Pelican::PelicanState state); + void setWaitLight(bool pressed); + + void update(const Hint& hint); + + private: + Pelican &myPelican; + + enum LightName { RED_LIGHT, YELLOW_LIGHT, GREEN_LIGHT, GREEN_MAN, RED_MAN }; + + Light *lights[RED_MAN + 1]; + Light *waitLight; +}; + +#endif diff --git a/cmat/Ex42/Subject.cpp b/cmat/Ex42/Subject.cpp index c31e2b6..a7f6681 100644 --- a/cmat/Ex42/Subject.cpp +++ b/cmat/Ex42/Subject.cpp @@ -1,12 +1,12 @@ - - -#include "Subject.h" -#include "Observer.h" - -void Subject::attach(Observer &obs) { myObservers.insert(&obs); } - -void Subject::notify() const { - for (ObsList::const_iterator iter = myObservers.begin(); iter != myObservers.end(); ++iter) { - (*iter)->update(); - } -} + + +#include "Subject.h" +#include "Observer.h" + +void Subject::attach(Observer &obs) { myObservers.insert(&obs); } + +void Subject::notify(const Hint& hint) const { + for (ObsList::const_iterator iter = myObservers.begin(); iter != myObservers.end(); ++iter) { + (*iter)->update(hint); + } +} diff --git a/cmat/Ex42/Subject.h b/cmat/Ex42/Subject.h index 245ff61..c98da96 100644 --- a/cmat/Ex42/Subject.h +++ b/cmat/Ex42/Subject.h @@ -1,20 +1,25 @@ - - -#ifndef SUBJECT_H -#define SUBJECT_H - -class Observer; - -#include - -class Subject { - public: - typedef std::set ObsList; - void attach(Observer &obs); - void notify() const; - - private: - ObsList myObservers; -}; - -#endif + + +#ifndef SUBJECT_H +#define SUBJECT_H + +class Observer; + +#include + +class Hint { + public: + virtual ~Hint() = default; +}; + +class Subject { + public: + typedef std::set ObsList; + void attach(Observer &obs); + void notify(const Hint&) const; + + private: + ObsList myObservers; +}; + +#endif