Einzelnen Beitrag anzeigen

Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.336 Beiträge
 
Delphi 11 Alexandria
 
#1

Komponenten in Stream speichern und wieder herstellen

  Alt 16. Jan 2008, 16:15
{
Einfach nur mal zu Diskussion ein Versuch der Darstellung meines Lösungsansatzes.
Für Profiprogrammierer sicher langweilig
Für Anfänger vielleicht interessant
Möglicherweise auch völlig falsch, weil man´s ganz anders macht
}

Hallo alle,

ich habe Datenkomponenten erstellt, die Daten verwalten, Berechnungen durchführen und miteinander "kommunizieren". Dazu gibt es visuelle Komponenten, die diese Daten anzeigen.

Visuellen Komponenten kann eine Datenkomponente zugeordnet werden. Die Datenkomponente registriert dabei automatisch alle betreffenden visuellen Komponenten in einer TList und informiert diese bei Datenänderungen. Datenänderungen können natürlich auch über die visuellen Komponenten selbst durchgeführt werden.

Delphi-Quellcode:
Data1.Vorname := 'André'
Data1.Nachname := 'Stahl';
Visual1.Data := Data1;
Visual2.Data := Data1;
Beide visuellen Komponenten zeigen dann Änderungen von Data1 sofort an.

Die Datenkomponenten können ihre Daten in einen Stream speichern und wieder laden.
Die visuellen Komponenten können ihre Position und den "Zeiger auf Data" in einen Stream speichern und wieder laden.

Da Visual1.Data ja eine Adresse auf Data1 ist, bringt es aber nichts, diese direkt in den Stream zu speichern. Beim Laden der Daten aus einem Stream wird ja Data1 neu erzeugt und liest dann erst seine Daten ein. Die Speicheradresse ist dann eine völlig andere, als zum Zeitpunkt des Speicherns in den Stream.

Daher mache ich folgendes:

Vor dem Speichern der Daten setze ich eine globale Variable GStreamId auf 0;
Beim Speichern jeder Komponente erhöht diese GStreamId um 1 und speichert zuerst diesen Wert und danach ihre eigenen Daten.
Data1 würde als StreamId z.B. 100 schreiben (danach seine Daten).
Visual1 würde z.B. 500 schreiben und zur Referenzierung auf Data noch die 100 (danach seine Position).
Visual2 würde z.B. 501 schreiben und zur Referenzierung auf Data noch ebenfalls die 100 (danach seine Position).
Nach dem Speichervorgang ist GStreamId unwichtig und wird auf 0 zurückgesetzt. Ebenso die temporär vergebenen StreamId´s der Daten- und visuellen Komponenten.

Beim Laden aus dem Stream verfahre ich so:

Die Komponenten werden erzeugt und laden sich Ihre "StreamId" und ihre zugehörigen Daten (die Komponenten befinden sich jetzt an einer beliebigen Speicheradresse).
Anstelle von Zeigern auf die Datenkomponenten merken sich die visuellen Komponenten erst einmal nur die zugehörigen aus dem Stream gelesenen StreamId der gewünschten Datenkomponente.
Zitat:
Data1.StreamId = 100
Visual1.StreamId = 500
Visual1.DataStreamId = 100
Visual2.StreamId = 501
Visual2.DataStreamId = 100
Nach dem Einlesen des Streams durchsucht eine globale Prozedur die gesamte Application nach Komponenten, denen noch Komponentenadressen zugeordnet werden müssen.
Hier wird nun zuerst Visual1 gefunden, deren DataStreamId = 100 ist.
Eine globale Funktion durchsucht nun wiederum die gesamte Application nach einer Datenkomponente, deren StreamId = 100 ist und liefert deren Speicheradresse zurück. Diese wird Visual1.Data zugewiesen und Visual1.DataStreamId auf 0 gesetzt. Das gleiche erfolgt auch für Visual2, womit wieder alle Datenkomponenten ihren visuellen Komponenten zugeordnet sind (die Registrierung der visuellen Komponenten in den Datenkomponenten erfolgt hier wieder automatisch wie oben beschrieben).
(In meinem Projekt können auch Datenkomponenten wieder andere Datenkomponenten enthalten und die Beziehungen in einem Stream abspeichern.)
Nach dem Einlesen des Streams ist GStreamId wieder unwichtig und wird auf 0 zurückgesetzt. Ebenso auch wieder die temporär vergebenen StreamId´s der Daten- und visuellen Komponenten.

Ich gehe davon aus, dass die IDE dies ähnlich erledigt, die Komponenten jedoch anhand des Komponentennamens sucht.

In meinem Projekt werden jedoch die gesamten Stream-relevanten Komponenten dynamisch erzeugt und sind nicht über einen eindeutigen Namen identifizierbar. Ich möchte/kann auch keine automatischen Namen "DataName12345" o.ä. vergeben, da ich ggf. auch "Sub-Komponenten" aus einem eigenen Stream lesen möchte. Es darf dann ja nicht vorkommen, dass ein bereits in der Application vorhandener automatisch vergebener Name noch einmal benutzt wird.

Mit meiner Lösung lässt sich eine eindeutige Beziehung der Komponenten untereinander zuverlässig realisieren, allerdings nur während dem Speichern in einen Stream bzw. beim Lesen aus dem Selben. Nach dem Einlesen werden die temp. StreamId´s nicht mehr benötigt und verworfen.

Die gesamte Datenlogik und die Daten selbst werden in den Datenkomponenten verwaltet. Die Datenmengen sind nicht sehr groß, aber die Beziehungen recht komplex. Eine Datenbank erschien mir dann doch eher ungeeigneter.


Meinungen?
Beschwerden?
Fragen?

stahli
  Mit Zitat antworten Zitat