Compare commits

..
2 Commits
Author SHA1 Message Date
porterskyandQwen 3.8 27B 11b96e4410 docs(materials): update S3 905 material
Co-authored-by: Qwen 3.8 27B <qwen3.8_27b-q3_k_xl@lmstudio.local>
2026-10-06 16:26:54 +02:00
porterskyandQwen 3.8 27B 6e0e45110a feat(cmat): implement Ex41 observer pattern
Refactor the Pelican crossing exercise to use the Observer
pattern: Pelican acts as Subject and each Pole observes it,
replacing direct calls through the owned Pole pointer.

Co-authored-by: Qwen 3.8 27B <qwen3.8_27b-q3_k_xl@lmstudio.local>
2026-10-06 16:26:53 +02:00
9 changed files with 39 additions and 28 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
class Observer {
public:
// TODO: declare the pure virtual function update()
virtual void update() = 0;
};
#endif
+6 -11
View File
@@ -3,29 +3,25 @@
#include "PelicanTimer.h"
#include "Pole.h"
Pelican::Pelican(int x, int y)
: pressed(false), RED_TIME(4), YELLOW_TIME(2), GREEN_TIME(3), FLASH_TIME(5), myPole(new Pole(x, y)),
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);
myPole->setTrafficLights(getState());
myPole->setWaitLight(isPressed());
notify();
}
Pelican::~Pelican() { delete myPole; }
Pelican::~Pelican() { }
void Pelican::press(void) {
if (state == GREEN_IDLE) {
state = YELLOW_STATE;
myTimer->timeoutRequest(YELLOW_TIME);
pressed = true;
myPole->setTrafficLights(getState());
myPole->setWaitLight(isPressed());
} else if (state != RED_STATE) {
pressed = true;
myPole->setTrafficLights(getState());
myPole->setWaitLight(isPressed());
}
notify();
}
void Pelican::timerExpired(void) {
@@ -60,6 +56,5 @@ void Pelican::timerExpired(void) {
break;
}
myPole->setTrafficLights(getState());
myPole->setWaitLight(isPressed());
notify();
}
+4 -4
View File
@@ -7,12 +7,14 @@
#ifndef PELICAN_H
#define PELICAN_H
#include "Subject.h"
class PelicanTimer;
class Pole;
class Pelican {
class Pelican : public Subject {
public:
Pelican(int x, int y);
Pelican();
~Pelican();
// call when the WAIT button has been pressed
@@ -39,8 +41,6 @@ class Pelican {
// indicates whether the WAIT light should be on
bool pressed;
Pole *myPole;
// Timer that indicates when the lights should change
PelicanTimer *myTimer;
+7 -1
View File
@@ -1,8 +1,9 @@
#include "Pole.h"
#include "Screen.h"
Pole::Pole(int x, int y) : waitLight(new Light("WAIT", x + 6, y + 12, Screen::WHITE)) {
Pole::Pole(int x, int y, Pelican& pelican) : waitLight(new Light("WAIT", x + 6, y + 12, Screen::WHITE)), pelican(pelican) {
using namespace Screen; // we will discuss namespaces in the course
pelican.attach(this);
lights[RED_LIGHT] = new Light("*", x + 11, y + 3, RED);
lights[RED_MAN] = new Light("*<-=", x + 6, y + 4, RED);
@@ -57,3 +58,8 @@ void Pole::setTrafficLights(Pelican::PelicanState state) {
}
void Pole::setWaitLight(bool pressed) { waitLight->set(pressed ? Light::ON : Light::OFF); }
void Pole::update() {
setTrafficLights(pelican.getState());
setWaitLight(pelican.isPressed());
}
+6 -3
View File
@@ -3,22 +3,25 @@
#define POLE_H
#include "Light.h"
#include "Observer.h"
#include "Pelican.h"
class Pole {
class Pole : public Observer {
public:
Pole(int x, int y);
Pole(int x, int y, Pelican&);
~Pole();
void setTrafficLights(Pelican::PelicanState state);
void setWaitLight(bool pressed);
void update();
private:
enum LightName { RED_LIGHT, YELLOW_LIGHT, GREEN_LIGHT, GREEN_MAN, RED_MAN };
Light *lights[RED_MAN + 1];
Light *waitLight;
Pelican& pelican;
};
#endif
+8 -4
View File
@@ -1,8 +1,12 @@
#include "Subject.h"
#include "Observer.h"
// TODO: Implement the Subject::attach() member function that adds an Observer to the set
void Subject::attach(Observer* observer) {
m_observers.insert(observer);
}
// TODO: Implement the Subject::notify() member function that calls all the update functions
void Subject::notify() {
for (auto* observer : m_observers) {
observer->update();
}
}
+3 -3
View File
@@ -8,11 +8,11 @@ class Observer;
class Subject {
public:
// TODO: Declare the attach() function that adds an Observer to the set
void attach(Observer* observer);
protected:
// TODO: Declare the notify() function that calls all the update functions
void notify();
private:
// TODO: Define a set of Observer pointers
std::set<Observer*> m_observers;
};
#endif
+4 -1
View File
@@ -1,13 +1,16 @@
#include "Keyboard.h"
#include "Pelican.h"
#include "Pole.h"
#include "TimerSet.h"
#include <cctype> // provides toupper()
int main() {
Keyboard kbd;
Pelican thePelican(30, 0);
Pelican thePelican;
Pole pole1(20, 0, thePelican);
Pole pole2(40, 0, thePelican);
char c = 0;
Binary file not shown.