Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Sa Jul 12, 2025 03:27

Foren-Übersicht » Sonstiges » Community-Projekte
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 427 Beiträge ]  Gehe zu Seite Vorherige  1 ... 20, 21, 22, 23, 24, 25, 26 ... 29  Nächste
Autor Nachricht
 Betreff des Beitrags:
BeitragVerfasst: Fr Feb 09, 2007 09:17 
Offline
DGL Member

Registriert: Mo Dez 20, 2004 08:58
Beiträge: 442
Wohnort: Mittweida (Sachsen)
Na wenn du nur geschielt hast, dann ist Dir hoffentlich der Fehler aufgefallen: Ich habe grundsätzlich alle Properties gelesen/geschrieben, unabhängig, ob sie überhaupt les-bzw. schreibbar sind. Du musst also vorher gucken, ob die Pointer GetProc bzw. SetProc gültig sind

_________________
Manchmal sehen Dinge, die wie Dinge aussehen wollen, mehr wie Dinge aus, als Dinge.
<Esmerelda Wetterwax>
Es kann vorkommen, dass die Nachkommen trotz Abkommen mit ihrem Einkommen nicht auskommen und umkommen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Feb 09, 2007 10:36 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Nein, das ist mir nicht aufgefallen, weil ich es anders mache als Du. Ich hatte ziemlich zu kämpfen mit dem Herausholen der RTTI-Daten. Zunächst gings (oder heißt es "ging es"?) ganz gut, aber das war ein Trugschluss. Hauptsächlich habe ich die verschiedenen Methoden verglichen, wie die RTTI-Daten herausgeholt werden. Ich lade mal das Demo.


NACHTRAG: ich weiß nicht, ob das deutlich wird: TDGL_DataProvider ist eine Datenpumpe für Objekte. Wenn man z.B. Ein Objekt "Adresse" erzeugt, kann ein existierender konkreter Datenprovider die Daten anliefern und wegspeichern, ohne über die Datenstruktur informiert sein zu müssen. Er nimmt sich nur die Liste der Properties vor und speichert eines nach dem anderen. Der CSV_Dataprovider erzeugt eine unidirektionale Datenmenge, sprich man kann sie nur von Anfang bis Ende lesen. Das Element, das den DataProvider in Betrieb nimmt, sagt z.B. nur: Lade/speichere das nächste Objekt (den nächsten Datensatz). In dem Ding stecken ungeheuer viele Möglichkeiten. Ich meine damit: das Konzept ist nach oben offen: Er bearbeitet JEDES Objekt, und das Objekt schreibt ihm nicht vor, wie die Bearbeitung zu erfolgen hat - landläufig ausgedrückt: jeder kümmert sich um seinen Kram.

Die einzige Einschränkung: die Published Properties können nur ganz bestimmt Datentypen haben. Aber meines Erachtens kann man diese Einschränkung umgehen.


Dateianhänge:
DataProvider.zip [5.5 KiB]
306-mal heruntergeladen
Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Feb 09, 2007 11:38 
Offline
DGL Member

Registriert: Mo Dez 20, 2004 08:58
Beiträge: 442
Wohnort: Mittweida (Sachsen)
Tjaaaa... Du hast aber hierbei (so wie ich dienen Code verstanden habe) das Problem, dass alle speicherbaren Objekte von TRTTI abgelitten sein müssen. Du kannst also kein TEdit serialisieren. Um dieses Problem zu umgehen habe ich eben ein Interface benutzt. Man kann dieses Interface jeder beliebigen Klasse zuordnen und schon geht die Serialisierung. Ausserdem hast Du auf diese Weise keine Chance, Array-Propertys zu serialisieren. Dies regle ich über die OnOwnerStream propetries des Delegaten (auch Records sind dann möglich, müssen aber von Hand bearbeitet werden. Hatte einen konkreten Fall, da habe ich die Members des Records als Attributwerte in den Knoten gespeichert).
Der Vorteil Deiner Version ist alerdings, dass ich die Art der Serialisierung von außen steuern kann. Das geht bei der Version mit dem Interface (noch) nicht.
p.s.: Man könnte auch problemlos einen Delegaten schreiben, der eine CSV erstellt.

_________________
Manchmal sehen Dinge, die wie Dinge aussehen wollen, mehr wie Dinge aus, als Dinge.
<Esmerelda Wetterwax>
Es kann vorkommen, dass die Nachkommen trotz Abkommen mit ihrem Einkommen nicht auskommen und umkommen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Feb 09, 2007 11:42 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Das Basis Widget also die Grundglage für alle Komponenten hat soviele Attribute wie nur möglich und natürlich die passenden funktionen.
Hierzu gehören z.B. top,left,width,height,visible,show(),hide(),parent,canvas,theme,...
Caption gehört nicht in das Basis Widget, da es auch komponenten gibt die keine schrift brauchen und auch ein caption(z.B. Panel,shape).
Ich werde morgen mit den weiteren Widgets weiter machen, denn momentan hab ich nur ne handvoll aus meiner x-dream gui übernommen.
Praktisch tu ich das auch austesten, ich nutzte DGLGUI als basis für mein PGD Contest Beitrag. Dadurch hab ich auch schon ein paar Fehler gefunden und beseitigt.

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Feb 09, 2007 16:42 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Hallo Sidorion,

Sidorion schrieb:
Zitat:
Tjaaaa... Du hast aber hierbei (so wie ich dienen Code verstanden habe) das Problem, dass alle speicherbaren Objekte von TRTTI abgelitten sein müssen. Du kannst also kein TEdit serialisieren.


Hmm. Was meinst Du mit serialisieren?


NACHTRAG: Meinst Du sowas: Ich habe eine Datei mit Datensätzen und will diese nacheinander einlesen? Oder bin ich da jetzt ganz falsch? Oder meinst Du, dass alle speicherbaren Objekte direkte Nachfahren von TRTTI sein müssen?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Feb 09, 2007 20:10 
Offline
DGL Member

Registriert: Di Jun 06, 2006 09:59
Beiträge: 474
Serialisieren bezeichnet die umwandlung eines Objektes in einen Datenstrom. Also stört ihn, dass er nur von TRTTI abgeleite Objekte speichern/laden kann.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Feb 09, 2007 21:49 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
@The-Winner: Danke für den Hinweis. Übrigens, die Übersetzbarkeit ist vermerkt.

@Sidorion:
Serialisieren bedeutet also, ein Objekt zu speichern. Die Frage lautet dann, ob ich ein (VCL-)TEdit speichern kann. Nein, das kann ich nicht. Wenn Du das mit dem Delegat kannst, dann alle Achtung, der Punkt geht an Dich. Allerdings lautet mein Auftrag auch nicht, ein VCL-Objekt zu speichern. Aber - wenn ichs mir recht überlege - ich werde Deinen Code nochmal unter diesem Aspekt anschauen - ist schliesslich eine geniale Idee.

Und ich kann auch keine Array-Properties speichern. Aber ich kann ja folgenden Workaround machen: Ich habe z.B. ein IntegerArrayObject, das ein privates Integer-Array und ein nicht indiziertes Integer-Published-Property hat. Voraussetzung: der Dataprovider erzeugt die Klasse NICHT, wenn er sie lädt (das tut er nämlich derzeit - da fällt mir ein: noch deutlicher wäre es für den Benutzer, wenn die derzeitige Lademethode nicht "LoadClient" sondern "CreateClientFromSource" oder irgendwie so heißt). Also die Instanz des IntegerArrayObject existiert schon:

Code:
  1. Procedure TIntegerArrayObject.LoadIntegerArray;
  2. Begin
  3.    While Not XYZ_DataProvider.EndOfSource
  4.       Do LoadClient(Self);
  5. End;


Das Objekt übergibt sich als "Self". Der DataProvider lädt daraufhin EINEN Integer rein: die Set-Methode des Integer-Property hängt ein Element an die Liste dran. Das wiederhole ich, bis irgendeine Ende-Bedingung eingetreten ist.

Für reine Integer-Arrays ist sowas nicht sinnvoll. Bei Datensätzen siehts schon wieder anders aus (wie wärs mit einem Vertex-Loader? :wink: ). Aber ein Integer-Array sehe ich als eine Art 'Blob' Type, nehmen wir z.B. ein 32-Bit RGBA-Bitmap. Kein Mensch würde auf die Idee verfallen, das so zu laden, denn:

Man kann diesem DataProvider vorwerfen, dass er nicht der schnellste ist. Ich habe versucht, das in den Griff zu kriegen, indem die Daten nicht einzeln geladen werden, sondern die StringListe liest sie en bloc von der Festplatte und der DataProvider klaubt sie mit spitzen Fingern aus den einzelnen Zeilen der Liste (macht übrigens die XML-Library, die Tak verwendet, auch so).

Ein ParentObjekt könnte sich aber auch vom DataProvider Objekte erzeugen lassen und in eine Liste speichern, der Phantasie sind keine Grenzen gesetzt. Mit dieser Methode plane ich, den GUI-Baum zu laden. Das ParentObjekt weiss weder, welche Objekte es genau in der Liste hat, weil die Objekte in der Liste sich alle nur als TRTTI tarnen (aber in Wirklichkeit RTTI-Enkel und Urenkel sind), noch weiß es, wieviele es kriegen wird, denn das weiß es erst, wenn der DataProvider fertig ist. Man stelle sich vor: jemand geht in die Geburtsklinik und erfährt: "Ihre Frau hat 18 Kinder bekommen. Es sind drei grüne, sieben blaue und acht rote." :D

Traude


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Feb 10, 2007 00:25 
Offline
DGL Member

Registriert: Di Jun 06, 2006 09:59
Beiträge: 474
Habe mal einen Blick auf deine dglRTTI.pas geworfen. Außer deinem etwas ungewöhnlichen Codestil ;) ist mir aufgefallen, dass die fast nur für sequentiellen zugriff gemacht zu sein schein, und für skriptzugriffe eher ungeeignet. Das kann jedoch auch an meinem mangelnden Codeverständnis liegen. Bin auch gerade am schreiben einer RTTI unit, jedoch mit schwerpunkt aus skripts, und weniger auf serialisierung.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Feb 10, 2007 01:06 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
Die Datei dglRTTI.pas ist nicht gut, da sie gegenüber TypInfo keinerlei neue Funktionen bietet. Die Daten werden einfach nochmal kopiert. Die andere Sache mit der Vererbung wurde ja bereits geschrieben. Warum soll man extra von TRTTI ableiten müssen wenn doch sowieso jede Klasse, die mit {$M+} kompiliert wurde RTTI unterstützt. Die Funktionen aus TRTTI zum einfachen Zugriff auf die Properties gehören in den Datenprovider, damit er mit beliebigen Objekten zusammenarbeiten kann.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Feb 10, 2007 10:52 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Hallo, Ihr beiden,

The-Winner schrieb:
Zitat:
ist mir aufgefallen, dass die fast nur für sequentiellen zugriff gemacht zu sein schein, und für skriptzugriffe eher ungeeignet.

dies in Verbindung mit
Lars schrieb:
Zitat:
Die Funktionen aus TRTTI zum einfachen Zugriff auf die Properties gehören in den Datenprovider, damit er mit beliebigen Objekten zusammenarbeiten kann.


bedeutet,
1) dass ich die Routinen zum Zugriff auf RTTI falsch platziert habe
2) wenn man es so macht hätte ich auch eine Funktionalität mitgeben müssen, die das Published Property auch per Namen aufrufbar macht
3) und Zeit verschwendet habe (unnötiges Zwischenkopieren)

Das heißt: Zurück ans Reißbrett, würde ich sagen. Die VCL scheint doch recht zu haben. :(



@The-Winner: das mit dem sequentiellen Zugriff stimmt. Für Skriptzugriffe sollten sie wohl über den Namen aufrufbar sein? Aber Skripte sind im Konzept vorgesehen. Wenn ich jetzt hier Fehler mache, wäre das fatal. Nach Euren Antworten ist mir jedenfalls klar, dass ich es ohnehin umschreiben muss.

Tja, mein Codestil: ich bin eben kein gelernter Informatiker. Und außerdem ein Gewohnheitstier. Aber ich gebe mir Mühe. Ich habe sogar ein Tool geschrieben, das alle Zwischen-Sternchen-Zeilen rausschmeißt und alle Dreier-Einrückungen auf Zweier-Einrückungen zurücknimmt. Aber ich hab vergessen, es drüberlaufen zu lassen.

@Lars: Es sollte die Funktionalität auch gar nicht erweitern, sondern nur leichter zugänglich machen, schließlich sind es undokumentierte Funktionen. Bei Classinfo steht sogar, dass man es nicht verwenden soll. Aber ich sehe ein, dass Du recht hast, auch mit dem doppelt kopieren. Eine Anmerkung dazu habe ich: wenn ich es so mache, wie Du es meinst, zwinge ich damit jeden konkreten Datenprovider die [in Delphi] undokumentierten TypInfo-Funktionen zu benutzen, und das wollte ich vermeiden.

Traude



NACHTRAG: He! Bedeuted das eigentlich, dass das Skript auf das Objekt zugreift, und darauf ANGEWIESEN ist, das das Objekt antworten kann? Ich meine, wäre es dann kontraproduktiv, wenn ich die Zugriffsfunktionen jetzt aus dem Objekt herausnehme und in den DataProvider stecke?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Feb 10, 2007 12:43 
Offline
DGL Member

Registriert: Di Jun 06, 2006 09:59
Beiträge: 474
Außerdem speicherst du wenn ich das richtig sehe die typinfos pro objekt, und nicht pro Klasse. Ich schreibe auch gerade an einer RTTI Klasse, die möglichst schnellen zugriff für skripte auf die objekte bieten soll, bei gleichzeitig minimalen overhead pro Objekt.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Feb 10, 2007 12:55 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Ich speichere nur den Wert. Da muss ich mit dem Objekt arbeiten, weil der für jedes Objekt verschieden sein kann.

Beim Laden des Property hast Du recht: Name und Typ gelten pro Klasse. Aber ich greife auf die Instanz zu. Logisch gesehen ein Fehler. Ich hatte Zugreifen auf die Klasse mal ausprobiert mit GetTypeInfo. Aber da hats mich auf die Nase geschmissen.


N.B.: Ich muss mich leider ausklinken. Kann am Abend (ca ab 19 Uhr) wieder antworten.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Feb 11, 2007 02:35 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Guten Abend,
Ich habe mir die Source Codes noch mal angesehen und die Kritikpunkte überdacht. Weil ich mich hier in einer grundlegenden Projektphase befinde, glaub ich, dass es wieder mal Zeit ist, einen alten Lösungsansatz zu versuchen: den minimalistischen.

Was will ich? Einen Data-Provider implementieren. Was brauche ich dazu?
--- eine Datenschnittstelle: es bietet sich RTTI an, weil es so allgemein ist (Alternative: objekt-individuelles Speichern)
--- ein Objekt, das Lade- und Speicherfunktionalität hat (ein klassischer Interface-Fall)
--- ein Objekt, das gespeichert wird (möglichst jedes Objekt)

Ich habe mich heute Abend mit der Datenschnittstelle befasst. Die Kritikpunkte an der ersten Version waren:
1. Nicht alle Objekte können die Schnittstelle benutzen
2. Der Schnittstelle fehlten wesentlich Funktionen (Notwendigkeiten für Skripte waren nicht berücksichtigt)
3. In den Methoden waren unnötige Kopiervorgänge implementiert
4. Vorhandene Routinen wurden zwar benutzt, aber es wurden keine Erweiterungen hierzu implementiert, daher fehlt der Schnittstelle die Existenzberechtigung


Ich habe also ein neues Objekt entworfen (ich habe hier nur die Klassendefinition):
Code:
  1.    TDataExchange = (dxBinary, dxString);
  2.  
  3.    TRTTI_Info = Class(TObject)
  4.    Private
  5.       fClient: TObject;
  6.       fDataExchange : TDataExchange;
  7.       fPropCount: Integer;
  8.  
  9.       Procedure SetClient(AClient: TObject);
  10.  
  11.       Function GetPropertyName(AIndex: Integer): String;
  12.       Function GetPropertyType(AIndex: Integer): TTypeKind;
  13.  
  14.       Function GetValueByIndex(AIndex: Integer): Variant;
  15.       Procedure SetValueByIndex(AIndex: Integer; AVariant: Variant);
  16.  
  17.       Function GetValueByName(AName: String): Variant;
  18.       Procedure SetValueByName(AName: String; AVariant: Variant);
  19.  
  20.       Procedure OpenRTTI;
  21.       Procedure CloseRTTI;
  22.    Public
  23.       Property Client: TObject Read Write SetClient;
  24.       Property DataExchange: TDataExchange Read fDataExchange Write fDataExchange;
  25.       Property PropertyCount: Integer Read fPropCount;
  26.  
  27.       Property PropertyName[Index: Integer]: String Read GetPropertyName;
  28.       Property PropertyType[Index: Integer]: TTypeKind Read GetPropertyType;
  29.  
  30.       Property ValueByIndex[Index: Integer]: Variant
  31.          Read GetValueByIndex Write SetValueByIndex;
  32.  
  33.       Property ValueByName[Index: String]: Variant
  34.          Read GetValueByName Write SetValueByName;
  35.  
  36.       Constructor Create; Reintroduce;
  37.       Destructor Destroy; Override;
  38.    End;



Die Methoden haben noch keinen Inhalt, ich habe mir über die Implementierungsdetails noch nicht den Kopf zerbrochen. Dieses Objekt ist eine Datenschnittstelle, aber es ist m.E. kein Fall für ein Interface weil es keine allgemeine Richtlinie darstellt, sondern eine besondere Verarbeitung im Auge hat (das soll heißen es ist KEINE allgemeine Datenschnittstelle, sondern eine konkrete RTTI-Schnittstelle).

Es nicht dazu gedacht, aus ihm Objekte abzuleiten, sondern es bearbeitet ein Objekt, das man ihm übergibt, und zwar jedes Objekt. Es soll das bearbeitete Objekt öffnen, Daten auslesen und eingeben können.

Da es ein Objekt ist, kann man damit alles machen, was man mit Objekten machen kann:
--- es kann ein Stand-Alone-Objekt sein
--- es kann eine Eigenschaft eines Objekts sein, das eine solche Schnittstelle benötigt
--- ......?

Beispiel für ein Stand-Alone-Objekt:
Code:
  1.  Var MyEdit: TEdit;
  2.     RTTI: TRTTI_Info;
  3.     LocalPropName: String;
  4.     LocalPropType: TTypeKind;
  5.     LocalPropCount: Integer;
  6.     LocalValue: Variant;
  7. Begin
  8.    RTTI:= TRTTI_Info.Create;       // RTTI-Instanz erzeugen
  9.    RTTI.DataExchange:= dxString;   // Alle Werte werden als String gelesen/geschrieben
  10.  
  11.    MyEdit:= TEdit.Create(Nil);     // Ein TEdit erzeugen und ....
  12.    RTTI.Client:= MyEdit;           // .... an RTTI anschliessen
  13.  
  14.    LocalPropCount:= RTTI.PropertyCount;    
  15.  
  16.    LocalPropName:= RTTI.PropertyName[0];    // PropertyName per Index
  17.    LocalPropType:= RTTI.PropertyType[0];    // PropertyType per Index
  18.  
  19.    RTTI.ValueByIndex[0]:= LocalValue;       // Wert per Index eingeben (!!!)
  20.    LocalValue:= RTTI.ValueByIndex[0];       // Wert per Index auslesen
  21.  
  22.    RTTI.ValueByName['Color']:= LocalValue;  // Wert per Name eingeben (!!!)
  23.    LocalValue:= RTTI.ValueByName['Color'];  // Wert per Name auslesen
  24.  
  25. .................
  26.  
  27. End.

Die (!!!) drei Rufzeichen bedeuten, dass hier ein mögliches Sicherheitsrisiko besteht.

Jetzt gehe ich die Kritikpunkte durch:

1. Nicht alle Objekte können die Schnittstelle benutzen
-------------Die neue Version kann alle Objekte benutzen
2. Der Schnittstelle fehlten wesentlich Funktionen (Notwendigkeiten für Skripte waren nicht berücksichtigt)
-------------Ich hoffe, das bereinigt zu haben, siehe meine Frage unten
3. In den Methoden waren unnötige Kopiervorgänge implementiert
-------------Ich werde keine "Zwischenvariablen" mehr benutzen
4. Vorhandene Routinen wurden zwar benutzt, aber es wurden keine Erweiterungen hierzu implementiert, daher fehlt der Schnittstelle die Existenzberechtigung
-------------Nach reiflicher Überlegung kann ich sagen: ich möchte die Schnittstelle doch haben, es gibt nämlich ein paar gewichtige Argumente dafür:

ERSTENS, angenommen, viele Programmierer benutzen eine solche Schnittstelle, und die Funktionen der Unit Typinfo werden DOCH geändert, dann genügt es, diese Schnittstelle anzupassen, und es muss nicht jeder seinen Code ändern

ZWEITENS, es gibt zumindest noch eine Anwendung außer dem DataProvider, die eine solche Schnittstelle gut brauchen kann, nämlich das Skript

DRITTENS, ich selber finde die Funktionen der Unit TypInfo am besten, wenn sie am weitesten von mir weg sind, denn sie sind undokumentierte Funktionen, an denen man nicht vorbeikommt und so etwas sollte man nur mit einer Feuerzange anfassen (oder in ein Objekt wegschließen).


UND JETZT DIE FRAGE AN DIEJENIGEN, DIE SCHNITTSTELLEN FÜR SKRIPTE ERARBEITEN: Könnt Ihr die Schnittstelle so brauchen?

Traude


NACHTRAG: NOCH ein Argument für diese Schnittstelle ist mir eingefallen: RTTI gefährdet die Sicherheit des Systems, wenn sie von aussen (von einem Skript) benutzt wird. An dieser Schnittstelle könnte man ein paar Sicherheitsfunktionen einbauen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Feb 12, 2007 16:02 
Offline
DGL Member

Registriert: Mo Dez 20, 2004 08:58
Beiträge: 442
Wohnort: Mittweida (Sachsen)
Hab dazu einige Fragen:
1. Wann hört Dein RTTI-Objekt auf zu parsen? (Thema ObjectProp-> mitspeichern oder nicht? z.B.: Font des Edits)
2. Wie kann ich nicht-published-Eigenschaften speichern?
3. Wie kann ich Record/Array-Properties speichern (zweiter Fall kann ja sowieso nicht published sein also siehe zusätzlich 2.)?

_________________
Manchmal sehen Dinge, die wie Dinge aussehen wollen, mehr wie Dinge aus, als Dinge.
<Esmerelda Wetterwax>
Es kann vorkommen, dass die Nachkommen trotz Abkommen mit ihrem Einkommen nicht auskommen und umkommen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Feb 13, 2007 00:12 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Hallo, Sidorion,
Zitat:
1. Wann hört Dein RTTI-Objekt auf zu parsen? (Thema ObjectProp-> mitspeichern oder nicht? z.B.: Font des Edits)

Es parst das Objekt ganz durch (wenn es auf ein Object-Property trifft, ruft es rekursionsartig wieder ein LoadClient auf, sollte eigentlich nur duch den Stack begrenzt sein; beim Speichern ist es genauso - das ist im Demo enthalten). Eine Beschränkung habe ich derzeit betreffend der Datentypen, die sind nicht vollständig. In der ersten Version war ein TRTTIValue (ein Record) definiert, in dem die derzeit unterstützten Datentypen aufgelistet sind. Interfaces z.B. waren nicht drin.

Zitat:
2. Wie kann ich nicht-published-Eigenschaften speichern?

Gar nicht. Möchte ich eigentlich auch so lassen.

Zitat:
3. Wie kann ich Record/Array-Properties speichern (zweiter Fall kann ja sowieso nicht published sein also siehe zusätzlich 2.)?

Man kann es so machen, wie ich einem obigen Beitrag beschrieben habe: Ein nicht-Array Published Property hängt in seiner Set-Methode ein Element an eine Liste (das wäre die Lade-Methode); in seiner Get-Methode müsste er immer das nächste Element aus der Liste holen (das wäre die Speichern-Methode, mit einem anfänglichen Reset). Verschiedene Möglichkeiten kann ich mir dazu vorstellen: man kann zB.

Code:
  1. // Liest einfach eine Datei durch und lädt jedes Objekt
  2. Procedure TIntegerArrayObject.LoadIntegerArray;
  3. Begin
  4.    While Not XYZ_DataProvider.EndOfSource
  5.       Do LoadClient; // hier wird immer ein neues Element an die Liste gehängt
  6. End;


oder
Code:
  1. // Liest alle Children (wenn welche da sind) und bleibt bei
  2. // EndOfChildren stehen (eine solche Methode wird den GUI-Baum laden)
  3. // Children müssen eine Parent-Identity im Header haben
  4. Procedure TIntegerArrayObject.LoadIntegerArray;
  5. Begin
  6.    While Not XYZ_DataProvider.EndOfChildren
  7.       Do LoadChild(Self); // hier wird immer ein neues Element an die Liste gehängt
  8. End;


Bei Datensätzen ist es das Gleiche: Das Objekt repräsentiert durch seine published Properties einen Datensatz: jedes Published Property ist ein Feld; wenn Du das Objekt einmal mit LoadClient lädst, erzeugt es einen neuen Datensatz in einer Liste (das macht die Set-Methode des Published Property, und die steht im Objekt, nicht im DataProvider). Und dann ist es auch nichts anderes als

Code:
  1. While Not XYZ_DataProvider.EndOfSource
  2.    Do LoadClient;


So könnte man eine Vertex-Liste laden, eine AdressListe, usw. Im Zusammenspiel mit einem Baum kann man auch einen Baum laden. Das ist jetzt aber grundsätzlich ANDERS als es der TReader/TWriter macht, denn wenn ich das richtig verstanden habe, sichert die VCL das TForm und alle seine SubObjekte. Ich möchte aber den GUI-Baum speichern, und bei mir sind das solche Objekte, wie wir sie besprochen haben: TGUIDescendants (inklusive SubObjekte), die Children haben, die in einer TObjectListe hängen, die wieder Children haben können, die.....


--------------------------------------------------------------------------------------------------------------

GEGENFRAGE:
Ich habe mit meinem neuen TRTTI-Objekt jetzt aber ein Problem: Dadurch, dass es das Objekt, das Daten herausgeben oder empfangen soll, als "Klient" behandelt, sind die beiden Objekte total unabhängig voneinander. Und das hat folgenden Nachteil:

Code:
  1. MyRTTI:= TRTTI_Handler.Create;          // Create RTTI-handler
  2. MyRTTI.DataExchange:= dxString;      // agree upon exchanging strings
  3.  
  4. MyObject:= TTestObject1.Create;      // Create object
  5. MyRTTI.Client:= MyObject;            // Plug object in RTTI-handler
  6.  
  7. MyRTTI.StrValByName['Name']:= 'Rudi';           // Input values
  8. MyRTTI.StrValByName['NumberInt']:= '24';        // into object using
  9. MyRTTI.StrValByName['NumberFloat']:= '123,45';  // RTTI-handler
  10.  
  11. MyObject.Free; // Object is destroyed, TRTTI_Handler cannot recognize that
  12.  
  13. StringValue:= MyRTTI.StrValByName['NumberFloat'];   // <===== CRASH
  14.  



Als ich die RTTI-Funktionen noch im Objekt selbst hatte, war das kein Problem. Wie kann ich so etwas verhindern?
Der RTTI-Handler hat vielleicht die Möglichkeit, an die Destroy-Methode des Objekts zu kommen, um so die Chance zu kriegen, zu merken, wenn man ihm seinen Klienten unkontrolliert löscht. Was besseres ist mir bisher nicht eingefallen.
Traude

NACHTRAG: @Sidorion: Deine Methode mit dem Delegat ist eine Lösungmöglichkeit, aber dazu muss man ein neues Objekt definieren, einfach ein TEdit zu speichern, würde nicht gehen. Ich zitiere mal Deinen Text von Seite 14 dieses Threads:

Sidorion schrieb:
Zitat:
Ich hatte das bei meiner XML-SChnittstelle so gemacht: Wenn ein Objekt XML-Fähig werden wollte, hat es das Interface implementiert, und zwar über eine Delegatenklasse TXMLParser.
Diese musste sich das Objekt dann instantiieren und wenn jemand xml lesen oder schreiben wollte, hat er einfach die Methoden am Interface gerufen, die natürlich dann dem Delegaten weitergereicht wurden. Dieser hat dann die published-Eigenschaften in XML geschrieben.
Da dies nicht ausreichend war und ich auch entscheiden können wollte, ob eine best. Eigenschaft geschrieben werden muss, habe ich zwei Events eingeführt.
Das Erste Event wurde bei jeder published-Eigenschaft gerufen und das Objekt konnte nun entscheiden, ob der Parser schreibt und/oder das Objekt selber was schreiben will (thema komplexe Strukturen)
Das zweite Event wurde einmal nach dem Schreiben aller published-Eigenschaften gerufen und das Objekt konnte zusätzlich in das Dokument schreiben.
Damit das funktioniert, muss einfach das Objekt beim instanzieren des Parsers diesen beiden Events behandlungsroutinen zuweisen.

p.s.: alle vorkommen von 'schreiben' können auch durch 'lesen' ersetzt werden. Hier passiert dann das selbe.


Ich könnte jetzt auf die Idee verfallen, nicht einen Delegaten XMLParser zu haben, sondern noch einen Schritt zurückgehen und sagen: mein Delegat heisst RTTI_Handler; damit erweitere ich das Konzept (durch Rückschritt) und mache damit das Objekt auch für andere Dinge leichter zugänglich (Lars würde sagen: zugänglich ist es ohnehin schon). Meine Gründe für die Schnittstelle habe ich oben schon angeführt. Der Haken dabei ist: Ich müsste dem TEdit dann ein solches Delegaten-Property mitgeben, und damit muss ich ein neues Objekt von TEdit ableiten.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 427 Beiträge ]  Gehe zu Seite Vorherige  1 ... 20, 21, 22, 23, 24, 25, 26 ... 29  Nächste
Foren-Übersicht » Sonstiges » Community-Projekte


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.012s | 15 Queries | GZIP : On ]