feat(cmat): pass hints to Ex42 observers
Extend the Ex42 observer pattern with Hint objects so each observer receives the reason for the update instead of querying the subject: - Subject::notify() and Observer::update() now take a const Hint& argument. - Add LightHint and WaitHint carrying the traffic light state and WAIT button state, defined in Pelican.h. - Pole dispatches on hint type using dynamic_cast. - The Pole constructor sets its initial lights directly from the Pelican's current state, since no notification is sent at startup. Stopgap until the initial update is handled properly. Co-authored-by: Qwen 3.8 27B <qwen3.8_27b-q3_k_xl@lmstudio.local>
This commit is contained in:
+80
-68
@@ -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 <typeinfo>
|
||||
|
||||
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<const WaitHint*>(&hint);
|
||||
const LightHint* lightHintPtr;
|
||||
lightHintPtr = dynamic_cast<const LightHint*>(&hint);
|
||||
if (waitHintPtr != nullptr) {
|
||||
setWaitLight(waitHintPtr->pressed);
|
||||
}
|
||||
if (lightHintPtr != nullptr) {
|
||||
setTrafficLights(lightHintPtr->state);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user