ich nicht sicher mehrere Überlastungen für dervied Klassen zu handhaben war, wie der Titel dieser Frage zu Wort, aber hier ist mein Problem:Wie, ohne dass mehrere Änderungen an anderen Dateien
ich auf einem Spiel in C arbeitete ++ verwenden die Architektur der Entitätskomponentensystem. In dieser Architektur wird jedes Spiel Objekt als Klasse dargestellt:
class Object
Eine Klasse nicht viel mehr als ein Behälter für Komponenten ist, die Teile des Spiels Objekt Logik behandeln.
class Component
Jede Komponente verfügt über eine Aktualisierungsfunktion und Ereignishandler für bestimmte Ereignisse. Jedes Ereignis wird von einer gemeinsamen Basisklasse abgeleitet, und jedes untergeordnete Objekt verfügt über eigene Datenfelder zur Beschreibung des Ereignisses. In meinem tatsächlichen Code hat die Basis-Event-Klasse einige Attribute, die alle Events teilen.
class Event
{
};
class OnDeathEvent : public Event
{
public:
int getKillerID() const
{
return 92341;
}
};
class OnLevelEnterEvent : public Event
{
public:
int getLevelEnteredID() const
{
return 100;
}
};
Im gesamten Code senden wir Ereignisse an Objekte. Hier ist die Hauptfunktion schrieb ich mein Beispiel-Code zu testen:
int main()
{
Object obj;
obj.sendEvent(OnLevelEnterEvent());
obj.sendEvent(OnDeathEvent());
std::cin.ignore();
return 0;
}
Wenn ein Objekt ein Ereignis empfängt, Verantwortung Delegierten für diesen Event seine Komponenten.
for (auto& component : components)
{
component->handleEvent(e);
}
Ich möchte Funktion Überladung für jeden Ereignistyp verwenden. Ereignisbehandlungsfunktionen werden dann sehr klar in ihrem Zweck.
Dazu müssen jedoch die Object-Klasse UND die Component-Basisklasse alle Überladungen für jeden Ereignistyp deklarieren. Offensichtlich wollen wir das vermeiden, weil wir mehrere Klassen ändern müssen, um unserem Spiel einen neuen Ereignistyp hinzuzufügen. Hier ist der Rest des Beispielcode:
class Component
{
public:
virtual void handleEvent(const Event& e) {}
virtual void handleEvent(const OnDeathEvent& e) {};
virtual void handleEvent(const OnLevelEnterEvent& e) {};
};
class TestComponent : public Component
{
public:
virtual void handleEvent(const OnDeathEvent& e)
{
std::cout << "You died. Your killer was: " << e.getKillerID() << std::endl;
}
};
class AnotherComponent : public Component
{
public:
virtual void handleEvent(const OnLevelEnterEvent& e)
{
std::cout << "Level Entered with ID: " << e.getLevelEnteredID() << std::endl;
}
};
Die Objektklasse:
class Object
{
public:
Object()
{
components.push_back(new TestComponent());
components.push_back(new AnotherComponent());
}
void sendEvent(const Event& e)
{
for (auto& component : components)
{
component->handleEvent(e);
}
}
void sendEvent(const OnDeathEvent& e)
{
for (auto& component : components)
{
component->handleEvent(e);
}
}
void sendEvent(const OnLevelEnterEvent& e)
{
for (auto& component : components)
{
component->handleEvent(e);
}
}
private:
std::vector<Component*> components;
};
Wir wollen einen neuen Event-Typen hinzufügen können, indem sie von der Event-Klasse erben, ohne Änderungen an andere zu erfordern Dateien oder Erstellen neuer Dateien (außer der neuen Event-Klasse). Was wäre eine elegante Art, unseren Code zu strukturieren?
Alle Vorschläge sind willkommen.
Wenn ich etwas nicht vermisse, würde das nicht funktionieren. Irgendwann würde ich ablegen müssen, da nicht alle Event-Typen die gleiche Event-Schnittstelle teilen. Und Casting ist nicht viel besser als der Code, den ich bereits habe – kgwong