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.
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};
};
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:
Answers to questions are automatically generated and may not have been reviewed.
An overview of the options we have for building flexible notification systems between game components