Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Hallo Tak,
hab den Link überlesen. Auch nicht schlecht, hab bei der Suche was gelernt. Fazit vom ganzen: dieses TXD-RTTI-Objekt finde ich wirklich gut. Ich schlage vor, dass wirs einbauen.
Traude
P.S.: Kann er auch Arrays speichern, z.B. Array of Record?
Registriert: Di Mai 18, 2004 16:45 Beiträge: 2623 Wohnort: Berlin
Programmiersprache: Go, C/C++
Records sind in FreePascal noch nicht implementiert und arrays werden, wenn ich mich recht erinner im published bereich von beiden nciht unterstützt.
Dieses ist aber kein Problem, denn das kann man über Methoden regeln.
_________________ "Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren" Benjamin Franklin
Was ich meinte, war nicht den TReader/TWriter von Delphi für .dfm zu nehmen, sondern die XML Ausgabe mit dieser Schnittstelle auszustatten, so dass es mit den TPersistent und TComponent zusammenarbeitet. Die beiden Klassen sind beide von TFiler abgeleitet und fast alle Methoden sind virtuell. Das hätte dann z.B. den Vorteil, dass Delphi TPersistent Klassen wie z.B. TStringList automatisch auch mit dem System funktionen.
Ansonsten sollte man vielleicht nicht TPersistent als Grundlage nehmen, denn man würde eine Schnittstelle anbieten, die verspricht mit den TFiler kompatibel zu sein, aber nicht implementieren.
Registriert: Di Mai 18, 2004 16:45 Beiträge: 2623 Wohnort: Berlin
Programmiersprache: Go, C/C++
Hast du schon mal Tcomponent mit TReader benutzt ?
Wenn ja kannst du mal ein Beispielcode geben, denn ich hab in Inet geguckt und der Codeaufwand ist riesig.
Ich hab damit bisher noch nicht gearbeitet und weiß daher nicht wie eine solche Implementierung wirklich aussieht.
_________________ "Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren" Benjamin Franklin
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Hallo,
ich glaube, ich bin Euch etwas schuldig. Zu sagen: "Finde ich gut, bauen wirs ein", ist definitiv zu wenig. Daher möchte ich Euch heute an meinem Dilemma teilnehmen lassen. Es geht um das Prinzip der Lade/Speicherfunktion.
Meiner Meinung nach sind grundsätzlich folgende Varianten vorstellbar, eine Prozedur "LoadFromFile" zu implementieren:
VARIANTE 1: LoadFromFile ist eine Methode des TGUIItem
Die Methode speichert alle (zu speichernden) Felder des Objekts in einem festgelegten Format (z.B. XML) selbst. Decendants des TGUIItem speichern nur mehr zusätzliche Felder.
Vorteil: Übersichtlicher, klarer Aufbau, jeder kennt sich aus.
Nachteil: Die nachträgliche Implementierung der Speicherung in einem anderen Format ist kaum mehr möglich: zuviel Aufwand (wenns schon viele Descendants gibt, muss man den ganzen Hierarchiebaum abkraxeln und auf den neuesten Stand bringen, das kann zu einer schier unmöglichen Aufgabe werden, überhaupt in Open Source, wo es dann vermutlich so endet, dass das ganze System nach einem Update inkonsistent wird, weil der Benutzer eigene Descendants gebastelt hat und die Lade/Speicherfunktion nicht auf den neuesten Stand bringt - zwingen kann man das ja nicht.)
VARIANTE 2: LoadFromFile ist die Methode eines externen Datenprovider-Objekts.
Hier bedient sich das TGUIItem eines externen Objekts, um seine Daten zu speichern (wie auch immer). Es ist eine Schnittstelle zwischen dem TGUIItem und dem Datenprovider zu definieren. Das Datenprovider-Objekt kann von einem abstrakten Basisobjekt abgeleitet werden und dann verschiedene Ausformungen haben: TXMLDataProvider, TBinaryDataProvider....
Vorteil: Die nachträgliche Implementierung der Speicherung in einem anderen Format ist mit vertretbarem Aufwand möglich
Nachteile: Die Schnittstelle kann nur eine endliche Anzahl von Datentypen umfassen, dadurch sind manche (komplexeren) Datentypen vom Speichern ausgeschlossen. Die Implementierung ist komplizierter als bei Variante 1.
Frage: WIE MACHT DIE VCL DAS? Die VCL implementiert ein MISCHSYSTEM. Sie hat eine Schnittstelle (nämlich RTTI), lässt dem TComponent aber auch die Möglichkeit, Daten zu speichern, die (warum auch immer) keine published Properties sind. Das bedeutet: um das Laden/Speichern von Published Properties braucht sich TComponent nicht zu kümmen. Wenn es Extrawünsche beim Laden/Speichern hat, so muss es die genauen Daten dafür in der Methode "DefineProperties" bekannt geben (TPersistent.DefineProperties), es definiert seine spezifische Schnittstelle. Das ist eine Lösung, die offenbar aus der Not geboren ist.
So wie es die VCL macht, ist das aber nur EINE Möglichkeit, das Ganze aufzufassen Man kanns auch anders machen. Die VCL übergibt das TComponent dem TWriter (Dataprovider). Die beiden führen eine Art "Tanz" auf, bei dem der TWriter sozusagen "führt". Ich könnte mir auch eine Möglichkeit vorstellen, wo es genau umgekehrt ist (ich weiß das, weil ich so etwas schon mal gemacht habe, auf eine einfachere Art und Weise, dort "führte" das Objekt, das gespeichert werden wollte und benutzte den Datenprovider als seine "Marionette"). Es lässt sich auch eine andere Schnittstelle denken.
Das ist jetzt mein Dilemma: es gibt viele Möglichkeiten, an so etwas heranzugehen. Allerdings bin ich schon etwas eingeengt, weil die published Properties so was wie eine "eierlegende Wollmilchsau" sind, die offenbar in vielen Zusammenhängen benutzt werden können, und die es einem ziemlich nahe legen, das System der VCL zu klonen, nämlich mit RTTI als Schnittstelle. Einen Datenprovider (denn die Union TReader/TWriter ist ja auch nichts anderes als ein Datenprovider) wird man wohl oder übel benutzen müssen.
Mein Fazit: wir werden an einer Lösung, wie Lars sie vorgeschlagen hat, nicht vorbeikommen.
Traude
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.
_________________ 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.
Ja und Ja. Dabei liegt allerdings die Entscheidung darüber, wie zu parsen ist, beim Objekt selber, da es sich den Parser Instanziert. Man könnte hier allerdings einen Event einführen, ähnlich wie bei TTreeView, der den Klassentyp des zu instanzierenden Parsers abfragt.
_________________ 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.
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Ich hatte das so gemacht, dass ich beim Create des zu speichernden Objekts gleich einen passenden DataProvider mitgegeben habe: TXYZObject.Create(ADataProvider: TDataProvider). Oder es könnte dieses Ding kann ja auch wieder ein Property sein, wo man einfach den DataProvider-Typ, der gewünscht ist einstöpselt: DataProvider:= TBlaBlaDataProvider, wobei ein Defaultwert (Default TXMLDataProvider) eingestellt werden kann.
@edit: Ach ja übrigens, weil es grade so toll passt:
Ich habe, wie in einem vorherigen Beitrag geschrieben, den DataProvider als meine "Marionette" gesehen. Mein Hauptaugenmerk lag auf dem Objekt, das gespeichert werden sollte. Ratet mal, wie der Code wohl aussieht, wenn der Programmierer beauftragt wurde, einen Datenprovider zu schreiben.
Traude
Ich werd heute abend mal die Quellen für mein XML-Intf incl Parser und Beispielobjekt reinstellen. Da könnt ihr euch mal nen Bild machen, wie sowas aussehen könnte.
_________________ 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.
Hast du schon mal Tcomponent mit TReader benutzt ? Wenn ja kannst du mal ein Beispielcode geben, denn ich hab in Inet geguckt und der Codeaufwand ist riesig. Ich hab damit bisher noch nicht gearbeitet und weiß daher nicht wie eine solche Implementierung wirklich aussieht.
Es reicht der Aufruf von TReader.ReadRootComponent aus. Habe es gerade mal mit einer Form getestet.
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Ja der TReader ist eben auch ein echter Datenprovider. Bei uns sollte ja auch ausreichen:
MyGUIManager.LoadFromXMLFile('XYZDatei.XML');
Die Tree-Funktionen des GUI-Baums sollten dafür sorgen, dass das GUI aufsteht wie ein Zombie aus seinem Grab. (Allerdings hoffentlich etwas schneller.)
Traude
Nachtrag: Und, weil der GUIManager die Methode "LoadFromXMLFile" vom TGUIItem erbt, kann auch jedes einzelne Element oder auch ein Teilbaum auf diese Weise gespeichert/geladen werden und ich wette, das ist bei TReader auch so.
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Lars schrieb:
Zitat:
Ansonsten sollte man vielleicht nicht TPersistent als Grundlage nehmen, denn man würde eine Schnittstelle anbieten, die verspricht mit den TFiler kompatibel zu sein, aber nicht implementieren.
Wollt Ihr mit der VCL kompatibel sein? Sehe nämlich keinen Grund dafür.
Na schon kompatibel in dem Sinne, dass mans mit VCL benutzen kann, aber nicht im Sinne, dass es exakt so läuft bzw. die gleichen Mechanismen genutzt werden. Weil wenn, müssen (sollten) wir über TPersistent gehen und das kann zu Portabilitätsproblemen führen.
_________________ 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.
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.