eugeneloza / decoherence

Project moved to https://gitlab.com/EugeneLoza/decoherence
GNU General Public License v3.0
10 stars 7 forks source link

Writer and reader for every object #499

Closed eugeneloza closed 6 years ago

eugeneloza commented 6 years ago

Define

procedure WriteToFile(doc: DFile); virtual; abstract;
procedure ReadFromFile(doc: DFile); virtual; abstract;

maybe in DObject, maybe in WObject (not to mess with abstract classes where it's not needed).

Iterate(list, doc);
Iterate(array, doc); overload;

Still thinking about it. Should replace #55 and #351 - looks like a cleaner and nicer solution.

eugeneloza commented 6 years ago

Would require using AdvancedRecords to work on records.

eugeneloza commented 6 years ago

Or write those through Interface. While it would not work for records, the implementation is still different for every data element.

eugeneloza commented 6 years ago

The only thing that actually is the problem in Modular or This approach is Iterators, which would work differently for different data types. I need to create some convenient API to use those, otherwise each save/load operation would require enormous amount of creativity, each time with different approach. However, starting at least somewhere is a good start (e.g. iterating on TStringList, etc.). Thou, I don't want to do it in the wrong way to be forced to rewrite too much in future.

Hmmm, can I pass a "Generic TObjectList" as a procedure parameter to use such stuff as Count to iterate on items? Should work, needs testing. Or is there any reliable way to iterate on "any" list type / array type?

Writing integers/records can be implemented by Type Helpers as it's done for integer.ToString in SysUtils, etc.

eugeneloza commented 6 years ago

Thinking aloud:

WriteInteger(const Doc: TXMLDocument; const Parent: TDOMElement; const Name: string; const Value: integer);
WriteString(const Doc: TXMLDocument; const Parent: TDOMElement; const Name: string; const Value: string);
WriteFloat(const Doc: TXMLDocument; const Parent: TDOMElement; const Name: string; const Value: DFloat);
...
WriteIntegerXYZ(const Doc: TXMLDocument; const Parent: TDOMElement; const Name: string; const x, y, z: integer);
WriteFloatXYZ...
...
type TReaderProcedure = procedure(const Parent: TDOMElement; const Name: string) of object;
ReadIterator(const Parent: TDOMElement; const Name: string; const Reader: TReaderProcedure);
eugeneloza commented 6 years ago

I don't like passing Doc: TXMLDocument, we can make it a global variable (as there will always be only one XML file open at the moment secured by TCriticalSection), thou it doesn't look clean for me.

eugeneloza commented 6 years ago

We're using XMLdoc.CreateElement and XMLdoc.CreateTextNode at the moment. So passing a procedure pointer as a parameter is also a bad solution.

eugeneloza commented 6 years ago

Practically I'd better be with this one: SomeList := ReadSomeList(Parent; Name); WriteSomeList(Document, Parent, Name, SomeList);

eugeneloza commented 6 years ago

Almost there. Creating 2 data-type specific issues and closing this one.