AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

generische Callback-Liste erstellen ?

Ein Thema von himitsu · begonnen am 16. Apr 2010 · letzter Beitrag vom 21. Apr 2010
Antwort Antwort
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.142 Beiträge
 
Delphi 12 Athens
 
#1

generische Callback-Liste erstellen ?

  Alt 16. Apr 2010, 19:21
Ich wollte mir eine grundlegende Eventliste erstellen, also eine Liste womit Callbackprozeduren gespeichert werden und auch aufgerufen werden können.

Als "normale" Liste hab ich schon lange im Einsatz und da ich
Delphi-Quellcode:
// Ausschnitt mit den wichtigsten Headern und Funktionen

Type TEvent = Procedure(Sender: TMyObject) of Object;
     TCallback = Class
       FEventList: Array of TEvent;
       Procedure Add (Const Value: TEvent);
       Procedure Remove(Const Value: TEvent);
       Procedure Call (Sender: TSender);
     End;

Procedure TCallback.Call(Sender: TSender);
  Var i: Integer;

  Begin
    For i := Count - 1 downto 0 do
      FEventList[i](Sender);
  End;
Nun brauch ich grade in einen Projekt mehrere dieser Listen und dachte mir
"och, warum erstellst'e dir nicht einfach ein (generisches) Grundgerüst".
So weit so gut ... die Deklaration funktioniert perfekt, aber das Aufrufen der Funktionen funktioniert einfach nicht.
Delphi-Quellcode:
// meine Deklaration

Type TInternalCallback<TProc> = Class(TList<TProc>)
       Procedure Add (Const Value: TProc);
       Procedure Remove(Const Value: TProc);
     End;
     TCallback<TProc, TSender> = Class(TInternalCallback<TProc>)
       Procedure Call(Const Sender: TSender);
     End;
     TCallback<TProc, TSender, TParam1> = Class(TInternalCallback<TProc>)
       Procedure Call(Const Sender: TSender; Const Param1: TParam1);
     End;
     TCallback<TProc, TSender, TParam1, TParam2> = Class(TInternalCallback<TProc>)
       Procedure Call(Const Sender: TSender; Const Param1: TParam1; Const Param2: TParam2);
     End;
     ...
Delphi-Quellcode:
// das Ganze etwas übersichtlicher (inkl. Markierung der Fehlerstelle)

Type TCallback<TProc, TSender> = Class(TList<TProc>)
       Procedure Add (Const Value: TProc);
       Procedure Remove(Const Value: TProc);
       Procedure Call (Sender: TSender);
     End;

Procedure TCallback<TProc, TSender>.Call(Sender: TSender);
  Var i: Integer;

  Begin
    For i := Count - 1 downto 0 do
      Items[i](Sender);
      // ^ genau hier
  End;
Zitat:
[DCC Fehler] OpenToolsAPI.pas(495): E2066 Operator oder Semikolon fehlt
Sowas bringt natürlich die selbe Fehlermldung:
Delphi-Quellcode:
For i := Count - 1 downto 0 do
  TProc(Items[i])(Sender);
  // ^ genau hier
Und dieses geht auch nicht
Delphi-Quellcode:
Type TCallback<TProc: Procedure, TSender> = Class(TList<TProc>)
       Procedure Add (Const Value: TProc);
       Procedure Remove(Const Value: TProc);
       Procedure Call (Sender: TSender);
     End;
Zitat:
[DCC Fehler] OpenToolsAPI.pas(18): E2029 Bezeichner erwartet, aber 'PROCEDURE' gefunden
Und verwenden wollte ich es z.B. so:
(dieses nimmt der Compiler auch kommentarlos entgegen)
Delphi-Quellcode:
Type TEvent = Procedure(Sender: TMyObject) of Object;
  TEventList = TCallback<TEvent, TMyObject>;
Wie kann ich also dem Compiler sagen, daß dieses "TProc" einen Methoden-Zeiger darstellen soll?


[add]
Wenn sich für den Aufruf nichts finden läßt, dann werde ich wohl doch zumindestens die Call-Prozedur ohne Generics lösen und für jede Methoden-Zeiger eine eigene Klasse von dem BasistypenTInternalCallback<TProc> = Class(TList<TProc>) ableiten
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.008 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#2

Re: generische Callback-Liste erstellen ?

  Alt 21. Apr 2010, 06:57
Delphi-Quellcode:
type
  TInternalCallback<T> = class(TList<T>)
    procedure Add(const Value: T); virtual; abstract;
    procedure Remove(const Value: T); virtual; abstract;
  end;
  TCallback<T> = class(TInternalCallback<TProc<T>>)
    procedure Call(const Sender: T);
  end;

procedure TCallback<T>.Call(const Sender: T);
var
  i: Integer;
begin
  for i := 0 to Count - 1 do
    Items[i](Sender);
end;
Man sollte niemals Typenparameter mit konkreten Typen verwechseln. TProc ist ein in SysUtils definierter Typ.

Alternativ:
Delphi-Quellcode:
type
  TEvent = procedure of object;
  TEvent<T> = procedure(Sender: T) of object;

  TInternalCallback<T> = class(TList<T>)
    procedure Add(const Value: T); virtual; abstract;
    procedure Remove(const Value: T); virtual; abstract;
  end;
  TCallback<T> = class(TInternalCallback<TEvent<T>>)
    procedure Call(const Sender: T);
  end;

procedure TCallback<T>.Call(const Sender: T);
var
  i: Integer;
begin
  for i := 0 to Count - 1 do
    Items[i](Sender);
end;
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.142 Beiträge
 
Delphi 12 Athens
 
#3

Re: generische Callback-Liste erstellen ?

  Alt 21. Apr 2010, 07:32
Das mit dem TProc ist eigentlich kein Problem, da hier das TProc aus der SysUtils lokal mit meinem TProc überschrieben wird,
aber ich nehm mich deinem Vorschlag an und werde es ohne die T's schreiben.
type TCallback<Proc, Sender> = class.. Aber die Idee das TEvent nochmals vorzudeklarieren war eine gute Idee, denn so weiß der Compiler jetzt, daß es ein Methodenzeiger ist.
Hatte das Event ja erst nachher deklariert.

Werde das TEvent aber noch mit in den Public-Bereicht des TCallback verschieben.
(ich denke mal, daß sollte auch funktionieren)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:10 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz