Ereignisprogrammierung

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
Benutzeravatar
Bebu
Beiträge: 562
Registriert: Mi Okt 21, 2009 6:19 pm
Wohnort: In der Nähe von Salzburg - Bin aber kein Österreicher!

Ereignisprogrammierung

Beitrag von Bebu » Di Jul 06, 2010 2:07 am

Huhu zusammen, ich bin schon eine Weile auf der Suche danach, wie man Ereignisse programmieren kann. Google hat mir bisher nichts brauchbares/verständliches ausgespuckt.

Genauer gesagt, möchte ich in meine Filesearcherklasse von Dedupe verschiedene Ereignisse einbauen, z. B. ein Ereignis für Suche beendet, Fehler, Suche gestartet usw. Leider habe ich keine Ahnung wie ich das Hinkriegen soll. Könnte mir jemand die Grundzüge anhand eines Beispiels erklären? Nur das keine Missverständnisse aufkommen, ich weiß was ein Ereignis ist, aber ich weiß nicht, wie ich meine Klasse dazu bringen kann, eines auszulösen.

PS: @Xin: Die Abwesenheit ist hiermit noch nicht aufgehoben ;)
Wer immer nach dem Unerreichbaren jagt, der wird irgendwann auf die Schnauze fallen!

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Ereignisprogrammierung

Beitrag von cloidnerux » Di Jul 06, 2010 8:06 am

Im Grunde genommen hast du eine Liste an Funktionspointern, die bei einem Bestimmten Ereignis aufgerufen werden.
Das heißt, du könntest dir eine Hilfsklasse "event" programmieren, die eine Liste für Funktionspointer enthält, eine Methode zum Hinzufügen und Entfernen von Funktionspointern und eine Methode zum Starten mit entsprechenden Parametern. Diese klasse kannst du dann für jeden Zweck spezialisieren.

Code: Alles auswählen

class event
{
    List<void*(int, int)> eventMethods;  //<-- Pointer so richtig?
    ...
    public bool AddToEvent(void (*func)(int, int))
    ....
    public bool RemoveFromEvent(void (*func)(int, int))
    public void Start(int int);
};
...
event myEvent;
myEvent.AddToEvent(my_func);
...
//Hier könntest du z.B fertig mit der Suche sein
myEvent.Start(a, b);
Das ist alles nicht getestet und dient nur der Anschauung.
Redundanz macht wiederholen unnötig.
quod erat expectandum

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Ereignisprogrammierung

Beitrag von Xin » Di Jul 06, 2010 8:47 am

cloidnerux hat geschrieben:Im Grunde genommen hast du eine Liste an Funktionspointern, die bei einem Bestimmten Ereignis aufgerufen werden.
Das heißt, du könntest dir eine Hilfsklasse "event" programmieren, die eine Liste für Funktionspointer enthält, eine Methode zum Hinzufügen und Entfernen von Funktionspointern und eine Methode zum Starten mit entsprechenden Parametern. Diese klasse kannst du dann für jeden Zweck spezialisieren.
Das wäre ein Event-Handler, der ein einziges Ereignis an beliebig viele Listener übermittelt.


Statt einer einzelnen Funktion, lässt sich alternativ aber auch ein Listener Objekt konstruieren. Das wäre eine abstrakte Klasse, die von den Empfängern der Nachricht implementiert wird. Der Sender erhält so die Kontrolle und ruft nur noch die Funktionen des Empfänger-Objektes auf. Das Empfängerobjekt hat damit also auch keine Kontrolle darüber, was rundum passiert.

Möglichkeit 3 habe ich kürzlich ins Repository eingecheckt: Man fragt den Sender, ob es schon was Neues gibt. Der Sender liefert einen Hinweis darauf, was anliegt und überlässt dem Empfänger die Nachricht zu bearbeiten oder es sein zu lassen.

In Kombination mit cloidnerux Liste ergibt sich so die Möglichkeit viele Empfänger mit vielen Ereignissen zu versorgen. Da wir aber vermutlich hinter jeder Oberfläche nur ein Programm laufen haben, können wir uns vermutlich auch auf einen Empfänger beschränken.
Bebu hat geschrieben:PS: @Xin: Die Abwesenheit ist hiermit noch nicht aufgehoben
Heißt das, ich hätte die Frage noch nicht beantworten dürfen? ;-)
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
Bebu
Beiträge: 562
Registriert: Mi Okt 21, 2009 6:19 pm
Wohnort: In der Nähe von Salzburg - Bin aber kein Österreicher!

Re: Ereignisprogrammierung

Beitrag von Bebu » Mi Jul 07, 2010 12:46 am

Xin hat geschrieben:
Statt einer einzelnen Funktion, lässt sich alternativ aber auch ein Listener Objekt konstruieren. Das wäre eine abstrakte Klasse, die von den Empfängern der Nachricht implementiert wird. Der Sender erhält so die Kontrolle und ruft nur noch die Funktionen des Empfänger-Objektes auf. Das Empfängerobjekt hat damit also auch keine Kontrolle darüber, was rundum passiert.

Möglichkeit 3 habe ich kürzlich ins Repository eingecheckt: Man fragt den Sender, ob es schon was Neues gibt. Der Sender liefert einen Hinweis darauf, was anliegt und überlässt dem Empfänger die Nachricht zu bearbeiten oder es sein zu lassen.

In Kombination mit cloidnerux Liste ergibt sich so die Möglichkeit viele Empfänger mit vielen Ereignissen zu versorgen. Da wir aber vermutlich hinter jeder Oberfläche nur ein Programm laufen haben, können wir uns vermutlich auch auf einen Empfänger beschränken.
Und jetzt so, das es ein Nichtinformatiker auch versteht...
Na schön, Spass beiseite, ich hab zwar nicht alles davon verstanden, aber ich vermute mal es heißt, dass das was cloidnerux vorgeschlagen hat, für unsere Zwecke ausreicht. Oder? :(
Xin hat geschrieben:Heißt das, ich hätte die Frage noch nicht beantworten dürfen? ;-)
Heißt eigentlich, ich hätte die Frage gar nicht stellen dürfen :P
Wer immer nach dem Unerreichbaren jagt, der wird irgendwann auf die Schnauze fallen!

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Ereignisprogrammierung

Beitrag von Xin » Mi Jul 07, 2010 10:06 am

Bebu hat geschrieben:Und jetzt so, das es ein Nichtinformatiker auch versteht...
Du gibst das Programm als Objekt an die GUI und wenn die GUI was befielt, wird die entsprechende Funktion des Programms aufgerufen - ohne, dass dem Programm Details der GUI bekannt sind.
Bebu hat geschrieben:Na schön, Spass beiseite, ich hab zwar nicht alles davon verstanden, aber ich vermute mal es heißt, dass das was cloidnerux vorgeschlagen hat, für unsere Zwecke ausreicht. Oder? :(
Nicht direkt... eher, dass cloidnerux ein Problem vielfacht löst, wir aber eher viele Probleme haben, die einmalig gelöst werden müssen.
Bebu hat geschrieben:
Xin hat geschrieben:Heißt das, ich hätte die Frage noch nicht beantworten dürfen? ;-)
Heißt eigentlich, ich hätte die Frage gar nicht stellen dürfen :P
Das ist ein Lernprojekt - es geht darum, Fragen zu stellen - und beantwortet zu bekommen.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
Bebu
Beiträge: 562
Registriert: Mi Okt 21, 2009 6:19 pm
Wohnort: In der Nähe von Salzburg - Bin aber kein Österreicher!

Re: Ereignisprogrammierung

Beitrag von Bebu » Mi Jul 07, 2010 4:56 pm

Xin hat geschrieben: Nicht direkt... eher, dass cloidnerux ein Problem vielfacht löst, wir aber eher viele Probleme haben, die einmalig gelöst werden müssen.
Na gut, könntest du mir dafür einen praktischen Ansatz liefern, wie ich das ganze sinnvoll in meine Klasse integrieren kann? Ich habe zwar jetzt eine grobe Idee, aber damit kriege ich das auch nicht in den Code, wenn mir die Grundlagen fehlen. Ich würde ja auch gerne das Konzept dahinter verstehen und für meine zukünftigen Programme anwenden können.
Wer immer nach dem Unerreichbaren jagt, der wird irgendwann auf die Schnauze fallen!

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Ereignisprogrammierung

Beitrag von Xin » Do Jul 08, 2010 8:05 pm

Bebu hat geschrieben:
Xin hat geschrieben: Nicht direkt... eher, dass cloidnerux ein Problem vielfacht löst, wir aber eher viele Probleme haben, die einmalig gelöst werden müssen.
Na gut, könntest du mir dafür einen praktischen Ansatz liefern, wie ich das ganze sinnvoll in meine Klasse integrieren kann? Ich habe zwar jetzt eine grobe Idee, aber damit kriege ich das auch nicht in den Code, wenn mir die Grundlagen fehlen. Ich würde ja auch gerne das Konzept dahinter verstehen und für meine zukünftigen Programme anwenden können.
Eine Möglichkeit habe ich ja bereits im Code verewigt.

Ansonsten machst Du eine Klasse Controller, die alle relevanten Befehle des Programms kennt, die der User mit der Benutzeroberfläche auslösen kann

Code: Alles auswählen

class Controller
{
  public:
    void AddFile( DedupeFile & newFile );
    void RemoveFile( DedupeFile & toRemove );

    bool Quit( void );
    void CreateIndex( std::list< DedupeFile * > files );
    ...
}
Das Objekt übergibt man der GUI und die GUI ruft die entsprechenden Funktionen auf, z.B. Quit() wenn das X gedrückt wird. Das Programm sichert alle Einstellungen usw... Die GUI fragt ab, ob true zurückkommt und beendet sich dann. Wir sind wieder in der Hauptanwendung, die das GUI-Objekt killt und dann das Programm beendet.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
Bebu
Beiträge: 562
Registriert: Mi Okt 21, 2009 6:19 pm
Wohnort: In der Nähe von Salzburg - Bin aber kein Österreicher!

Re: Ereignisprogrammierung

Beitrag von Bebu » Fr Jul 09, 2010 2:43 am

Super danke, jetzt habe ich es auch verstanden, also das Konzept zumindest. Allerdings muss die Gui ja auch auf bestimmte Ereignisse warten, die über das Controllerobjekt gestartet werden. Als Beispiel sei eine Meldung genannt, die ausgegeben werden soll, wenn ein Suchvorgang abgeschlossen ist. Wie kann man das berücksichtigen? Oder stehe ich gerade mit beiden Füßen auf dem Schlauch?
Wer immer nach dem Unerreichbaren jagt, der wird irgendwann auf die Schnauze fallen!

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Ereignisprogrammierung

Beitrag von Xin » Fr Jul 09, 2010 9:09 am

Bebu hat geschrieben:Super danke, jetzt habe ich es auch verstanden, also das Konzept zumindest. Allerdings muss die Gui ja auch auf bestimmte Ereignisse warten, die über das Controllerobjekt gestartet werden. Als Beispiel sei eine Meldung genannt, die ausgegeben werden soll, wenn ein Suchvorgang abgeschlossen ist. Wie kann man das berücksichtigen? Oder stehe ich gerade mit beiden Füßen auf dem Schlauch?
Der Controller baut die Software auf (Controller::Controller()), also erzeugt er auch ein GUI-Objekt.

Code: Alles auswählen

Controller::Controller()
{
  GUIInterface * myGUI;

  switch( prefs.GUI ) 
  { 
    case GUI::wxWidgets: myGUI = new wxWidgetsGUI( *this ); break;
    case GUI::Qt: myGUI = new QtGUI( *this ); break;

    default:
    case GUI::NCurses: myGUI = new NCursesGUI( *this ); break;
  }

  if( !myGUI )
    fprintf( stderr, "No Gui\n" );
  else
    myGUI.TakeOver( *this );
}

Controller::AddFile( DedupeFile & newFile )
{
  /* Die TakeOver-Funktion eines beliebigen GUIs hat vom User gesagt bekommen, dass er ''newFile'' in die Liste aufnehmen soll,
      darum ruft sie nun diese Funktion */
}
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Antworten