Handling Multiple Event Types
Can I have an observer observe multiple different types of events from the same subject?
Yes, a single observer can handle multiple event types from the same subject. There are several ways to implement this, each with its own advantages. Let's explore the main approaches.
Multiple Delegate Properties
The simplest approach is to have separate delegates for each event type:
class Player {
public:
using HealthDelegate = std::function<
void(int NewHealth)>;
using LevelDelegate = std::function<
void(int NewLevel)>;
void SetOnDamageDelegate(HealthDelegate D) {
OnDamage = D;
}
void SetOnLevelUpDelegate(LevelDelegate D) {
OnLevelUp = D;
}
void TakeDamage(int Damage) {
Health -= Damage;
if (OnDamage) OnDamage(Health);
}
void GainExperience(int Exp) {
Experience += Exp;
if (Experience >= 100) {
Level++;
if (OnLevelUp) OnLevelUp(Level);
Experience -= 100;
}
}
private:
HealthDelegate OnDamage;
LevelDelegate OnLevelUp;
int Health{100};
int Level{1};
int Experience{0};
};
Event Objects
Another approach is to use a single delegate type but pass event objects that contain information about the event type:
enum class PlayerEventType { Damage, LevelUp };
struct PlayerEvent {
PlayerEventType Type;
int Value;
};
class Player {
public:
using EventDelegate = std::function<
void(const PlayerEvent&)>;
void SetEventDelegate(EventDelegate D) {
OnEvent = D;
}
void TakeDamage(int Damage) {
Health -= Damage;
if (OnEvent) {
OnEvent({PlayerEventType::Damage, Health});
}
}
void GainExperience(int Exp) {
Experience += Exp;
if (Experience >= 100) {
Level++;
if (OnEvent) {
OnEvent({
PlayerEventType::LevelUp, Level
});
}
Experience -= 100;
}
}
private:
EventDelegate OnEvent;
int Health{100};
int Level{1};
int Experience{0};
};
The observer can then handle different event types:
void HandlePlayerEvent(const PlayerEvent& E) {
switch (E.Type) {
case PlayerEventType::Damage:
std::cout << "Health changed to: "
<< E.Value << '\n';
break;
case PlayerEventType::LevelUp:
std::cout << "Level up to: "
<< E.Value << '\n';
break;
}
}
Choose the approach that best fits your needs:
- Multiple delegates are simpler but less flexible
- Event objects are more complex but provide a unified interface
- Event objects make it easier to add new event types later
Delegates and the Observer Pattern
An overview of the options we have for building flexible notification systems between game components