Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Ein Event 2 Empfänger? Geht das? (https://www.delphipraxis.net/51774-ein-event-2-empfaenger-geht-das.html)

Corelgott 18. Aug 2005 14:26


Ein Event 2 Empfänger? Geht das?
 
Hi @ all,

ich habe gerade mal ein kleines Grundsatz-Problem mit Events.

Ich habe ine Componente die ein OnChange Event zur Verfügung stellt.

Nun ist die Compo nur dafür gedacht, daten zu handeln.
WEnn Sich ihre daten ändern dann *schreit* sie .

Nun Kommt's

Ich habe 2 weitere Komponenten, die ihre Daten anzeigen. und bei jedem OnChange sollen die sich dann auch aktuallisieren.
Hmm 1 Event... 2 Empfänger? Oo

geht das überhaupt?!

Delphi-Quellcode:
myComp.OnChange := viewer1.Handler1;
myComp.OnChange := viewer1.Handler1;
????

Hmm ich hatte schon mal an ein gekapseltes Event-Array gedacht...
nach dem Motto:

Delphi-Quellcode:
property OnChange : TNotifyEvent read getEv write setEv;

procedure setEv(Sender : TObject);
begin
  // ein array nimmt dann den Sender auf...
  // und wenn es los gehen soll wird das array abgegrasst
  array.add(Sender);
end;

function getEv : Sender;
begin
  // hmm und was zum geier kommt hier denn nu?
end;
hmm also für so was fehlen mir auch ein wenig die google suchwörter... ^^
Vielen Dank für's nachdem im Vorraus!

Thx & Cya
Corelgott

Dax 18. Aug 2005 14:29

Re: Ein Event 2 Empfänger? Geht das?
 
Multicast delegates gibts *leider* nur unter .net. Unter Win32 musst du dir was anderes ausdenken.. Zum Beispiel eine Methode AddHandler die einen Handler zum array hinzufügt (hast du ja schon fast). Zum Aufrufen musst du durch das Array iterieren und jeden Handler aufrufen, als wärs der einzige ;)

Bernhard Geyer 18. Aug 2005 14:33

Re: Ein Event 2 Empfänger? Geht das?
 
Definier doch ein addEventListener/removeEventListener-Methode und speichere die Listener in einem Array.
Ein einfaches Property kann dies nicht.

Corelgott 18. Aug 2005 14:43

Re: Ein Event 2 Empfänger? Geht das?
 
hmm ok...
Array / ObjectList Lösung angenommen

aber wenn ich das über eine Property kapseln will:

was für ein read mache ich da?

Dax 18. Aug 2005 14:44

Re: Ein Event 2 Empfänger? Geht das?
 
Eins für Arrays oder keins. Wenn du eine Eventliste hast, musst du dich zwischen den beiden Möglichkeiten entscheiden.

Corelgott 22. Aug 2005 12:57

Re: Ein Event 2 Empfänger? Geht das?
 
Zitat:

Zitat von Dax
Eins für Arrays oder keins. Wenn du eine Eventliste hast, musst du dich zwischen den beiden Möglichkeiten entscheiden.

hmm also irgendwie peile ich deine aussage nicht ganz...

Angenommen ich habe ne liste mit 5 events drin...
und nun ruf wer aus irgend nem dummen grund read auf...
welches gebe ich dem dann? Der aufrufer erwartet ja nur EIN event..
Ich kann ihm ja immer nur das erste geben... aber das kann's ja uahc ned sein...
ein dummy event... wäre auch etwas umüberlegt...

wenn ich den read teil weglasse dann kommen die tollsten und buntesten fehler.. so wie '%p ist ungültig oder incompatible' // hat echt gedauert bis ich das auf meine events zurück verfolgen konnte...

zur zeit habe ich das problem, dass diese meldung "nur noch" kommt wenn ich das programm beende...
Ich vermute mal ganz stark wegern meiner unsauberen getter & setter...

Wie macht man so was richtig? bzw. sauber? hat das wer ne idee?

thx im Voraus
Corelgott

Corelgott 23. Aug 2005 11:09

Re: Ein Event 2 Empfänger? Geht das?
 
:wiejetzt:

**push**

sry... tut mir leid...
:?

Olli 23. Aug 2005 11:36

Re: Ein Event 2 Empfänger? Geht das?
 
Jain. Natürlich kannst du das über einen eigenen Dispatchmechanismus erreichen (zB über Subclassing und in der eigenen Fensterfunktion dann den Dispatcher). Allerdings muß man sich mal den Mechanismus vor Augen halten. Ein Event (welches du jetzt meinst) ist ja nicht in dem Sinne ein Event, sondern vielmehr eine entweder zugewiesene oder eben nicht zugewiesene Callbackfunktion. Damit sollte klar sein, daß zwar mehrere Objekte die selbe Callbackfunktion benutzen können, aber diese Callbackfunktion bei einem bestimmten Event nicht für mehrere Objekte aufgerufen wird, sondern gerichtet für nur eines der Objekte.

Corelgott 23. Aug 2005 11:56

Re: Ein Event 2 Empfänger? Geht das?
 
:shock:
hmm...

**Olli, bitte nicht übel nehmen wenn ich dich falsch verstehe**

Also mir ist klar, dass ein "event" nur eine "zugewiesene prozedur" ist. d.h. wenn ich mein event auslöse, dass ich damit nur die hinterlegte funktion aufrufe.
(ist doch so!? :gruebel:)

also wenn ich nun mein eines (!) Event per property nach draußen reiche dann wird dies immer wieder durch ein anderes obj, dass seine eigne call-back Funktion hinterlegt, überschrieben.

also habe ich mir eine Funktion in den property-write-part hineingelegt...
Was das ganze intern in ein Array schreibt...
Wenn ich nun mein Event auslöse, dann wird jede hinterlegte callback funktion aufgerufen... :?

Aber was ich nicht so ganz peile, (selbst || gerade) nach Olli's Antwort, was ich da am besten im read-teil hineinlege / im getter zurückgebe...

aber dennoch erst mal THX Olli!
& thx generell @ all für's Nachdenken..

Hat sonst wer dafür noch nen Kommentar übrig?

thx & cya
Corelgott

Olli 23. Aug 2005 12:22

Re: Ein Event 2 Empfänger? Geht das?
 
Zitat:

Zitat von Corelgott
Aber was ich nicht so ganz peile, (selbst || gerade) nach Olli's Antwort, was ich da am besten im read-teil hineinlege / im getter zurückgebe...

Okay, kapiert. Die frage ist, ob du überhaupt was zurückgeben mußt. Das sollte doch nur in einer abgeleiteten Klasse wichtig sein.

Ich würde es so lösen:
- die Set-Methode schreibt in ein Array, verändert aber nicht den eigentlichen Wert (i.e. deine eigene Methode)
- die Get-Methode gibt den Pointer auf deinen eigenen OnEvent-Handler zurück
- Dein OnEvent-Handler arbeitet als Dispatcher für das Array.

So ist es konsistent und du arbeitest dennoch alle Handler ab. Allerdings könnte es sein, daß die Handler auf sowas nicht vorbereitet sind - also ist die Frage ob die Reihenfolge noch entscheidend ist.

Corelgott 23. Aug 2005 12:37

Re: Ein Event 2 Empfänger? Geht das?
 
hmm würde dann jungefähr so aussehen:

Delphi-Quellcode:
...
_events       : Array of TNotifyEvent;
...


procedure TObj.raiseOnChange;
var
  i : Integer;
begin
  if length(_events) > 0 then
    for i := 0 to length(_events) - 1 do
     _events[i](self);
end;

function TObj._getEvent: TNotifyEvent;
begin
  result := _events[0];
end;
oder?

was mache ich mit dem fall, dass _events[0] nix is? nil kann ich nicht zurückgeben...
(bzw. habe ich keinen plan wie ich dann "nil" zu TNotifyEvent casten sollte / kann :shock: )

Und noch was zur generellen lösung:
da bekomme ich wenn ich mein Programm beende den Fehler s.o. "%p ungültig oder Argument nicht kompatibel"...
hmmm.... so ganz kann es das ned sein... glaube ich...

Oder missverstehe ich dich?

thx
Corelgott

Olli 23. Aug 2005 12:54

Re: Ein Event 2 Empfänger? Geht das?
 
Nicht ganz!
Zitat:

Zitat von Corelgott
was mache ich mit dem fall, dass _events[0] nix is? nil kann ich nicht zurückgeben...

Eben deswegen sollst du ja deinen eigenen statischen Eventhandler immer zurückgeben, niemals einen der dynamischen.

Corelgott 23. Aug 2005 13:13

Re: Ein Event 2 Empfänger? Geht das?
 
hmmm... aso.... klar...
sry nicht genau genung gelesen...

!!aber das scheint zu funzen...!!

hatte noch dazu nen Free-Fehler, den ich gerade gefunden habe ^^

Thx Olli für das ganze Denken tun und die Hilfestellung

cya
Corelgott

Olli 23. Aug 2005 13:34

Re: Ein Event 2 Empfänger? Geht das?
 
Bin jetzt allerdings nicht ganz sicher, ob es sauber ist über den Adress-Operator (@) eine Methodenadresse zurückzugeben. Könnte auch fehlschlagen (ich sage nur VTable). Also da müßtest du eventuell nochmal testen.

Viel Erfolg.

Dax 23. Aug 2005 13:45

Re: Ein Event 2 Empfänger? Geht das?
 
Wie wäre es denn mit sowas?

Delphi-Quellcode:

type
  TMyType ...
  private
    _events = array of TNotifyEvent;
    procedure myOnChange(Sender: TObject);
    procedure raiseOnChange(Sender: TObject);
 
    function GetEvent: TNotifyEvent;
    procedure SetEvent(Event: TNotifyEvent);
  public
    property OnChange: TNotifyEvent read GetEvent write SetEvent;

...

procedure TMyType.myOnChange(Sender: TObject);
begin
  raiseOnChange(Sender);
end;

procedure TMyType.raiseOnChange(Sender: TObject);
var i: Integer;
begin
  for i := 0 to High(_events) do
    if Assigned(_events[i]) then
      _events[i](Sender);
end;

functin TMyType.GetEvent: TNotifyEvent;
begin
  Result := myOnChange;
end;

Olli 23. Aug 2005 13:50

Re: Ein Event 2 Empfänger? Geht das?
 
Zitat:

Zitat von Dax
Wie wäre es denn mit sowas?[...]

a.) du kannst einen Funktionspointer einfach so zurückgeben? Ohne @?
b.) wenn nicht, bleibt das von mir direkt drüber beschriebene Problem. Diese Adressen sind dynamisch, daher bin ich nicht sicher. ZB darf man ja auch keine Methoden als API-Callbacks übergeben, selbst wenn man sich um den Self-Pointer selber kümmert.

Corelgott 23. Aug 2005 14:01

Re: Ein Event 2 Empfänger? Geht das?
 
hmm

das scheint alles zu passen...
es stürzt wenigstens nicht mehr ab...
funzen tut das alles insgesammt auch so wie es soll...

(Ok außer dem OI ruft vermutlich "niemand" den getter auf...)

Lol So lange es passt...
Ich mache das nun so wie Dax das vorschlägt...

thx
Corelgott


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:57 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz