Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Schorsch

Supermoderator

  • »Schorsch« ist der Autor dieses Themas

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

1

14.04.2011, 23:46

Eventsystem - Eventspezifische Daten

Hey,
ich bin grad dabei ein Eventsystem umzusetzen. Ich habe einen Eventmanager. Dies ist das Kernstück des Systems. Objekte können einen Eventlistener beim Manager anmelden. Diese werden mit den für sie interessanten Events registriert. Wenn jetzt ein Objekt ein Event feuert, benachrichtigt der Eventmanager alle Eventlistener, welche interessiert sind, und diese können dann die ihre Unterobjekte aufrufen, damit sie darauf reagieren können. Alles also nichts besonderes. Meine Überlegung ist nun, wie Eventspezifische Daten behandelt werden. Events können ja verschiedene Zusatzinformationen beinhalten. Zum Beispiel könnte ein Weapon_fire Event noch die ID des Spielers beinhalten, welcher gefeuert hat, oder vielleicht auch mit welcher Waffe gefeuert wurde. Andererseits könnte bei einem Move_forward Event vielleicht eine Intensität mitgesendet werden, für den Fall dass ein Spiel möglicherweise mit einem Analogstick bedient wird. Naja welche Daten dort verpackt werden ist ja eigentlich egal, aber es gibt verschiedene davon. Eine Überlegung wäre jetzt einfach eine EventArgs Klasse zu schreiben, von welcher Alle Argumente abgeleitet werden. Diese besitzen dann jedoch ihre jeweiligen Methoden für ihre Daten. Das Problem hierbei ist, dass jedes mal ein Cast erfolgen muss, um an die Daten zu kommen, da diese Klassen nicht genau dasselbe Interface implementieren können. Finde ich persönlich nicht besonders elegant. Ich könnte die Daten auch in einen String schreiben und dann parsen, was aber mindestens genauso unschön ist. Jetzt wollte ich mal nachfragen, ob ihr vielleicht noch gute Ideen habt, wie ich das Problem lösen könnte. Wichtig ist, dass die Argumente wirklich grundverschiedene Daten enthalten können, wie zum Beispiel Punkt und Richtungsvektor oder ID oder oder oder. Von daher ist keine einheitliche Schnittstelle zu finden. Wem es weiterhilft, ich setze das System mit C# um.
Gruß
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

15.04.2011, 00:47

C# hat doch bereits ein eingebautes Eventsystem!?

3

15.04.2011, 00:53

Also ich habe auch schon ein Eventsystem geschrieben ;)

Was ich jetzt nicht genau verstanden habe, setzt du ne Klasse ein von der man ableiten muss um Events zu erhalten?

Warum arbeitest du nicht mit Templates(ka wie das in C# heißt^^) und registrierst immer nur direkt Funktionen als Callback-Funktionen.
So kannst du dann für jedes Event ne eigene Klasse schreiben, kannst alles reinpacken was du willst und brauchst nichts casten^^

Schorsch

Supermoderator

  • »Schorsch« ist der Autor dieses Themas

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

4

15.04.2011, 01:10

Vom Prinzip läuft es so. Ich "feuer" ein Event. Dabei wird es im EventManager in eine Queue geschrieben und einmal pro Update werden alle Events aus der Queue ausgeführt. Wer sich für das Event registriert hat, bekommt eine Nachricht per Methodenaufruf. Dies passiert über die Eventlistener. Der EventManager benachrichtigt einfach alle Eventlistener die sich für das Event registriert haben, oder wohl besser für diesen Eventtyp. Die Eventlistener können das Event dann weiter verarbeiten und an die jeweiligen Objekte weiterleiten. Zum Beispiel im Falle eines Events für Bewegung dann die Objekte bewegen. Ob ich irgendwie generisch an die Sache heran gehen kann habe ich mir auch schon überlegt, bin jedoch noch zu keinem guten Ergebnis gekommen. Deine Methode über die Callbackfunktionen hört sich nicht so schlecht an. Müsste ich mir mal genauer drüber Gedanken machen. Wobei dann in dem Fall jeder Eventlistener Methoden für alle Events benötigen würde, die ihn interessieren. Fände es unschön jedes mal die Schnittstellen zu verändern, wenn sich was an den Events ändert, bzw neue dazu kommen. Fände es etwas eleganter dies in den einzelnen Methoden selbst zu implementieren.
Jeder Eventlistener registriert sich natürlich normal für mehr als eine Art von Events. Als Beispiel müsste eine Viewklasse ja auf so gut wie alles reagieren, um eine passende Ausgabe zu liefern, sei es durch Sound oder Partikelsysteme oder was weiß ich.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

5

15.04.2011, 01:32

Nochmal für den Fall dass es untergegangen ist: C# hat doch bereits ein komplettes System mit Events und Delegates eingebaut, warum verwendest du das nicht einfach!? Warum brauchst du einen globalen Punkt an dem sämtliche Events gequeued werden!?

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

15.04.2011, 08:19

dot, es geht eigentlich darum, dass auch Delegates Parameter zur Übergabe brauchen. Und da hat auch bei C# in den vorgefertigten Events jedes Delegate einen anderen Typ als Parameter. MouseEventArgs, TimerElapsedEventArgs, DrawItemEventArgs... und alle erben von EventArgs.
Genau das überlegt Schorsch gerade. Nur sehe ich überhaupt nicht, wo er da casten müsste.
Ein Objekt sollte ja keine Methode registrieren, bei dem es ALLE Events bekommt und somit keinen einheitlichen Datentyp als Parameter festlegen kann, sondern es sollte sich für spezifische Events anmelden von denen jedes Delegate einen spezialisierten Typ als Parameter fordert. Damit fällt jegliches Casten komplett weg. Genau so hat es Microsoft ja auch gelöst. Z.B. ein Forms-Element bekommt nie alle möglichen Events in nur einer Methode und muss dann selbst casten, sondern es hat dutzende Methoden für verschiedene Event-Typen, die alle verschiedene Typen von EventArgs übergeben bekommen.

Die Queue, die er da hat, die ist mir allerdings auch schleierhaft, denn die braucht er nicht, dank Delegates und Events.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

7

15.04.2011, 10:08

Die "vorgefertigten" Events die du meinst sind wohl die von den Windows Forms. Die stammen eben aus Zeiten bevor es generics gab. Da wir aber in C# nun schon seit geraumer Zeit generics haben kann man das heute auch ganz einfach so lösen: http://msdn.microsoft.com/en-us/library/sx2bwtw7.aspx

Wobei mir grad auffällt dass das wohl nicht sein Problem war. Wenn ich das Problem richtig versteh entsteht es doch erst dadurch dass dieser komischen Event Manager sämtliche Events behandeln muss!? Lass das einfach und verwend Events so wie man es eben normalerweise macht. Dann kannst du auch für jeden Eventtyp einen eigenen Typ machen und fertig!?

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »dot« (15.04.2011, 10:14)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

8

15.04.2011, 10:29

Keine Ahnung, worauf du dich bei den Generics beziehst, das geht glaub ich am Thema vorbei.

Es geht ihm (wo weit ich das verstanden habe) nur um die Parameter, die übergeben werden müssen bei einem Event, damit der Event-Handler was damit anfangen kann - da will er nicht casten müssen. Und um das zu lösen schlägst du genau das vor, was auch ich schon gesagt habe. Jedes Ereignis (um es mal nicht mit dem Keyword "Event" zu verwechseln) hat einen eigenen Typ mit eigenem Parameter-Typ und ein eigenes Event (hier jetzt das echte C# Keyword!). Damit entfällt jedwede Art von Cast, da eben nicht nur eine Methode aufgerufen wird, sondern viele verschiedene.

Aber ich glaube, dass sein eigentliches Problem ganz woanders liegt und ihm das noch gar nicht klar ist. Denn wozu genau dient denn der Event-Manager überhaupt oder das gesamte Event-System? Denn ich nehme mal an, das wird verwendet um z.B. zwei Objekten mitzuteilen, dass sie kollidiert sind oder eins Lebenspunkte verliert oder ähnliches. Aber da würde ich kein Event-System brauchen, denn wozu da eine Callback aufrufen, wenn man die notwendige Methode auch direkt aufrufen kann? Events machen ja nur dann Sinn, wenn man die konkreten Objekte (die Beobachter) eigentlich gar nicht kennt (oder nicht kennen will), die da "informiert" werden wollen, sobald sich in einem anderen Objekt (das Beobachtete) etwas ändert. Das ist in seinem Code aber vermutlich gar nicht der Fall, sondern eher, dass ein Objekt geändert werden soll (kollidiert, HP verloren, was auch immer) und das Objekt selbst darüber in Kenntnis gesetzt werden muss. Klar, man kann es mit Events irgendwie lösen, aber den genauen Vorteil sehe ich da irgendwie nicht gegenüber einem direkten Methoden-Aufruf.
Aber dafür sind die Informationen vielleicht auch etwas zu spärlich, um das genau beurteilen zu können.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von »BlueCobold« (15.04.2011, 10:39)


9

15.04.2011, 10:38

Naja aber für so Sachen wie Key-Events bietet sich das schon an.
Und man kann noch viele weitere interessantere Dinge machen, mein Eventsystem zum Beispiel ist auch Multithreading fähig und kümmert sich dadrum das die Events an die anderen Threads gesendet werden und so mit hat man z.B. nur eine zentrale Stelle wo etwas gelockt werden muss ;)

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

10

15.04.2011, 10:41

Ja, klar, für solche Sachen ist es durchaus zu gebrauchen. Aber "weapon_fired" klingt für mich jetzt irgendwie überhaupt nicht danach, als ob da alle anderen Objekte informiert werden WOLLEN, wenn ein anderes Objekt eine Waffe abfeuert. Speziell dann nicht, wenn das über einen Manager läuft. Denn eigentlich würden sich ja dann eher alle Beobachter direkt beim Beobachteten anmelden und sagen: "Hier, sag mir mal Bescheid, wenn du was abfeuerst".
Es klingt für mich aber eher nach: Objekt X soll abfeuern und daher ruft der Manager das Callback (weapon_fired) von Objekt X auf. Und das wäre ja nicht im Sinne des Patterns und eine total Uminterpretation von Events.
Genau das gleiche für "Move_forward". Das ist ja kein Event, sondern ein Befehl. Also nur ein normaler und direkter Methoden-Aufruf. Ein Event wäre: "X moved forward and informed Y about it".

Aber zu dem Key-Ding nochmal: Ich finde irgendwie nicht, dass ein Objekt den Key-Controller kennen sollte, um sich bei diesem an einem Event zu registrieren. Da würde ich doch lieber der "Welt" mitteilen, dass ein Key gedrückt wurde und diese leitet es an die Objekte in der Welt weiter. Sonst ist da irgendwie eine logische Verbindung drin, die nicht drin sein dürfte (Objekte sollten den Key-Controller eben nicht kennen).
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »BlueCobold« (15.04.2011, 10:47)


Werbeanzeige