AGB  ·  Datenschutz  ·  Impressum  







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

Callbacks: Interface und/oder Methode? (DEC 6.0)

Ein Thema von himitsu · begonnen am 23. Dez 2020 · letzter Beitrag vom 29. Dez 2020
Antwort Antwort
generic

Registriert seit: 24. Mär 2004
Ort: bei Hannover
2.416 Beiträge
 
Delphi XE5 Professional
 
#1

AW: Callbacks: Interface und/oder Methode? (DEC 6.0)

  Alt 23. Dez 2020, 11:30
Moin, du hast dir gute Gedanken gemacht und alles sehr schön abgewogen.

Auch wenn ich ein großer Fan von Interfaces bin, solltest du auf Callback-Funktionen setzen.
Die DEC wird in Konsolen-, VCL, FMX und Diensten eingesetzt.
Würdest du die Interfaces wählen, dann müsste zumindest für die Konsole überhaupt erstmal eine Klasse her, welche das Interface implementiert.
Du zwingst dann den Entwickler mehr zu machen als Notwendig wäre.

Daher würde ich es gut finden, wenn der Entwickler, den Callback als anonyme Funktion übergeben kann.
(oder halt auch ein Zeiger auf eine Funktion)


Für alle, welche gerade Bahnhof verstehen im CodingBott Youtube-Channel gibt es Videos zu dem Thema:

Zurück zum Aufrufer - Strategien zum zurückgeben von Daten
https://www.youtube.com/watch?v=cWaQkXX02gM

Zeiger auf Methoden und Funktionen in Delphi
https://www.youtube.com/watch?v=7PL_H2aBUOI

Der Weg zum Interface und deren Vorteile
https://www.youtube.com/watch?v=S5kX1N2G5hg

Geändert von generic (23. Dez 2020 um 11:32 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Callbacks: Interface und/oder Methode? (DEC 6.0)

  Alt 23. Dez 2020, 14:43
Ja, dieses ein-prozedurige Interface ist eh "blöd".
Zitat:
das Originale Interface hat den Nachteil, dass man den Anfang und vorallem das Ende nicht sicher erkennen kann
Daher würde ich es gut finden, wenn der Entwickler, den Callback als anonyme Funktion übergeben kann.
(oder halt auch ein Zeiger auf eine Funktion)
Jupp, wenn Callback-Methode, dann hatte ich eh an reference to procedure gedacht, damit der Entwickler da ganz frei alles übergeben kann.
Bezüglich dem FPC muß ich noch nachsehn ob/wie das dort geht.

* man könnte das einfache Interface ersetzen oder ein zweites "Besseres" danebenlegen (Abwärtskompatibilität)
* man kann einen einfachen Prozedurzeiger zusätzlich daneben hinzufügen oder das Interface komplett ersetzen (rauswerfen)

Demos:
der aktuelle Hauptthread zum Projekt
https://www.delphipraxis.net/206356-...erfuegbar.html
Code eigentlich hier (diese Demo steckt noch in der Entwicklung fest, drum nicht im Master)
https://github.com/MHumm/DelphiEncry...elopment/Demos
aber bei mir liegt da grade der aktuellere Code (hab grad erst die ProjekteOptionen aufgeräumt, und Dergleichen)
https://github.com/geheimniswelten/D...s/Progress_VCL
https://github.com/MHumm/DelphiEncry...endium/pull/11
und Seite 3 ganz oben, da hat jemand die Demo grade nochmal überarbeitet (hab ich mir noch nicht angesehn)
https://www.delphipraxis.net/206356-...ml#post1479751

[edit]
Ich denk mal so wäre es doch eine gute Lösung?
Delphi-Quellcode:
// alt
IDECProgress = interface
  procedure Progress(const Min, Max, Pos: Int64);
end;

// neu
TDECProgressState = (Start, Progress, Finish, Error);
TDECProgressParams = record
  Sender: TObject;
  Min, Max: Int64;
  Pos: Int64;
  Percent: Single;
  State: TDECProgressState;
  function ErrorMessage: string; // die Exception.Message aus dem umgebenden Try-Except-Block (oder als "function Error: Exception;", falls wer nicht selber auf System.ExceptObj zugreifen kann)
end;
TDECProgress = reference to procedure(const Progress: TDECProgressParams);
Bei Objekt-Methode und anonymer Methode bekommt man eigene Daten in den Callback.
Und bei einer Prozedur kann man sich über den Sender (die übergeordnete DEC-Klasse) als Vergleichswert zu einer Datenquelle durcharbeiten.

Oder sollte man hier vielleicht auch noch eine Data-Variable durchschleifen? (NativeInt, Pointer oder TObject)
Eigentlich nicht nötig, denn wer was braucht, der kann ja Methode statt Prozedur benutzen.

Nur die neue coole Interface-CallbackDemo muß dann wer umbauen.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (23. Dez 2020 um 15:21 Uhr)
  Mit Zitat antworten Zitat
TurboMagic

Registriert seit: 28. Feb 2016
Ort: Nordost Baden-Württemberg
3.038 Beiträge
 
Delphi 12 Athens
 
#3

AW: Callbacks: Interface und/oder Methode? (DEC 6.0)

  Alt 23. Dez 2020, 16:21
Hallo,

soweit ich es derzeit abschätzen kann wäre ich auch für die Variante mit der Anonymen Methode.
Dann kann man entweder eine Methode oder eine normale Prozedur übergeben oder was direkt tun
(Anonyme Methode "in-place"). Verstehe ich das richtig?

Und auf die FPC Kompatibilität lege ich momentan ehrlich gesagt keinen übertriebenen Wert.
Wenn wir das dazu kompatibel hinbekommen, ok, aber das soll uns nicht ausbremsen.

Grüße
TurboMagic
  Mit Zitat antworten Zitat
generic

Registriert seit: 24. Mär 2004
Ort: bei Hannover
2.416 Beiträge
 
Delphi XE5 Professional
 
#4

AW: Callbacks: Interface und/oder Methode? (DEC 6.0)

  Alt 23. Dez 2020, 16:41
Wenn du eine Function draus machst, könnte ein FALSE sagen "weiter machen" und ein TRUE als "Abbruch" gewertet werden für die Callbackfunktion bzw. deren Rückgabe.
Also ist das Result die Antwort auf "Soll der Vorgang abgebrochen werden?"

Bei dem MIN-Wert bin ich mir auch nicht so sicher, ob der gebraucht wird. Übergibst du jemals was anderes als 0?
Coding BOTT - Video Tutorials rund um das Programmieren - https://www.youtube.com/@codingbott
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Callbacks: Interface und/oder Methode? (DEC 6.0)

  Alt 23. Dez 2020, 16:51
(wenn ich es richtig gesehen/verstanden habe)
Pos ist "eigentlich" nicht die "absolute" Position der Progess, sondern die Position im Stream.
Und per se kann der Stream auch erst ab der Mitte für x Bytes lang ver-/entschlüsselt werden.

Aber man könnte sich auch darauf einigen, dass es ab jetzt nur die Position des aktuellen Ver-/Entschlüsselungsproesses ist, dann kann MIN auch weg.

Verstehe ich das richtig?
Jupp.


Hab grade (seit gestern) das Delphi ein zweites Mal neu installiert. (erstes Mal im Schlaf von 10.4 zu 10.4.1 und dann nochmal iOS/OSX dazu ... brauch es zwar nicht, aber Delphi schmeißt sonst unnetterweise die Einträge aus den Projekten )
Und wollte mir dann mal wieder (nach Jahren) ein Lazarus installieren und es in das TestScript aufnehmen ... dann sieht man erstmal, ob es noch kompatibel ist (Änderungen dann auch kompatibel zu halten, ist eine andere Sache und könnte man später nachholen)
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (23. Dez 2020 um 17:00 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Callbacks: Interface und/oder Methode? (DEC 6.0)

  Alt 24. Dez 2020, 21:01
Bei dem MIN-Wert bin ich mir auch nicht so sicher, ob der gebraucht wird. Übergibst du jemals was anderes als 0?
Jo, MIN ist die StartPosition des Streams.
Aber ich denke, dass alle damit übereinstimmen, dass es mit 0 bis Anzahl-1 ganz OK wäre, also Min=0 (nicht vorhanden) und Pos=aktueller Verarbeitungsfortschritt.
https://github.com/geheimniswelten/D...progress-event

Den einzigen Vorteil, denn Min=StartPos statt Min=0 hätte, wäre wenn jemand in einem Stream "stückchenweise" mehrere Teile einzeln verschlüsselt/entschlüsselt/hasht,
aber da ist es für den Entwickler bei der Anzeige auch kein Problem, den Offset selbst einzurechnen, womit Min=0 dennoch vollkommen OK wäre.



Allerdings gibt es noch einen Bug, denn TDECHash.CalcStream und TDECFormattedCipher.DoEncodeDecodeStream verhalten sich unterschiedlich
und das hab ich noch nicht behoben. Erstmal nur die Behandlung für den Callback geändert und beim Rest nochmal warten, falls jemand etwas aus gutem Grund anders sieht.

TDECFormattedCipher.DoEncodeDecodeStream (DECCipherFormats) fängt immer mit Min=Stream.Position an
und bei DataSize<0 wird nur noch die Länge automatisch berechnet.

Während TDECHash.CalcStream (DECHashBase) bei DataSize<0 die Stream.Position auf 0 setzt.
Also bei DataSize<0 wird der Stream verschoben und mit Min=0 gearbeitet, während bei DataSize>=0 mit Min=Stream.Position begonnen wird.

Jetzt könnte man sich noch über die Definition von -1 streiten.
  • -1 = "verarbeiter ALLES", also immer von Position 0 aus
  • -1 = bis zum Ende, ab der aktuellen Position (ich bin hierfür, also dass DataSize nur die DataSize beeinflusst und nicht auch noch die Position)
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (24. Dez 2020 um 21:33 Uhr)
  Mit Zitat antworten Zitat
TurboMagic

Registriert seit: 28. Feb 2016
Ort: Nordost Baden-Württemberg
3.038 Beiträge
 
Delphi 12 Athens
 
#7

AW: Callbacks: Interface und/oder Methode? (DEC 6.0)

  Alt 28. Dez 2020, 16:09
DataSize sollte tatsächlich die Stream Position nicht beeinflussen!
Der Stream wird ja erzeugt übergeben und nicht von der DEC erzeugt.

Grüße
TurboMagic
  Mit Zitat antworten Zitat
generic

Registriert seit: 24. Mär 2004
Ort: bei Hannover
2.416 Beiträge
 
Delphi XE5 Professional
 
#8

AW: Callbacks: Interface und/oder Methode? (DEC 6.0)

  Alt 29. Dez 2020, 11:53
Ich finde das Thema gerade schwierig.

Wenn ein Stream verarbeitet wird, steht die Länge nicht fest.
Ich meine man kann auch nicht berechnen, wieviel arbeit zu tun ist.

von, bis und pos zu haben wäre nett, ist das dann aber nicht eher das Problem von dem Streamersteller?
Ist dort nicht der Callback festgelegt und müsste dann nicht im Callback ggf. das ausgerechnet werden, wo der Prozentbalken steht oder ggf. ein Animation gespielt wird?

Kann also die DEC nur ein "STEP" signalisieren und kein genaue Position der Verarbeitung?

Wenn die DEC die Gesamtmenge, welche die DEC verarbeitet ausrechnen kann, dann müsste an den Callback [min,] max und pos übergeben werden, dass hat aber dann nichts mit der Streamsize und POS zu tun.

Versteht mich jemand, was ich meine?


PS:

Code:
alt
procedure TFormMain.OnProgress(const Min, Max, Pos: Int64);

neu
procedure TFormMain.OnProgress(const Progress: TDECProgressParams);


alt
  ProgressBar1.Min := Min;
  ProgressBar1.Max := Max;
  ProgressBar1.Position := Pos;

neu
  ProgressBar1.Min := 0;
  ProgressBar1.Max := Progress.Max;
  ProgressBar1.Position := Progress.Pos;

alt habe ich besser gefunden, weil die Implementierung vom Progress nicht vom Typ TDECProgressParams abhängt und somit bei anderen Programmteilen wiederverwendet werden könnte.

Ich persönlich bevorzuge auch immer weniger Punkte zu nutzen als mehr.
Also
Code:
  ProgressBar1.Min := Min;
vor
Code:
  ProgressBar1.Max := Progress.Max;
Spätenstens bei dem zweiten Punkt würde es hässlich werden, weil man dann abhängig von der internen Umsetzung wird.
Also
Code:
Progress.Max.irgendwas
- nicht relevant hier . nur Beispiel.
Coding BOTT - Video Tutorials rund um das Programmieren - https://www.youtube.com/@codingbott

Geändert von generic (29. Dez 2020 um 11:58 Uhr)
  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 13:51 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