JSON ist die aktuelle Sau, die durchs Dorf getrieben wird. Davor war es XML oder CSV oder … ist vergessen. Wie auch immer, JSON wird von 4D unterstützt. Jetzt hatte ich eine Idee, wie ich mir das Aufheben von Voreinstellungen vereinfachen kann, in dem ich die Objektnamen der Formularobjekte als JSON-Key (der key in key-value oder Eigenschaft in 4Ds Objekt-Befehlen) verwende.

Lokale Daten

JP_backupPrefsSo sehr ich mich bemühe eine Komponente unabhängig zu gestalten, die ein oder andere Einstellung brauche ich vom Nutzer. Also Dialog gestalten und die Einstellungen aufheben. Ich könnte die Daten in eine Externe.4dd packen. Das ist mir zu viel Aufwand und umstände, für die wenigen Werte, die ich brauche. Also erzeuge ich ein JSON und sichere dieses im Resources-Ordner der Komponente.

Einstellungen

In diesem Fenster mische ich die Einstellungen, die ich vom Anwender brauche – Backup, Ziel-Ordner, Planung – mit Werten, die die Komponente dem Anwender zurückmeldet – zuletzt gesichert, den letzten Fehler, Versions-Nummer.

JP_dialogDesign

Keine der Variablen im Formular hat einen Variablen-Namen. Es sind alles Laufzeit-Variablen, die 4D für mich verwaltet und zum Schluß wieder aufräumt. Jede Variable hat einen Objektnamen, hier identisch zum Schlüssel (key) für den JSON-Eintrag.

JP_GetSetContentVerwaltungsmethode

faßt den Aufwand in gut 100 Zeilen zusammen. In Abfolge sind dies

  • den Pfad zum JSON-Dokument
  • ein Array mit den Objektnamen = JSON-Keys
  • in einem Case of die Direktzugriffe auf einen Wert (getter/setter)
  • im Else die Schleife über das Objektnamen-Array, um alle Werte zu lesen (get) oder zu schreiben (set)
  • die Uhrzeit ist in Millisekunden im JSON abgelegt (4:00 h entspricht 14.400 sec), darum zwinge ich in Zeile 444 den Wert als Zeit auszulesen, sobald ein Zielobjekt vom Zeit der Empfänger ist
  • ist es ein Set-Aufruf, also ein Wert verändert, wird das JSON am Ende dieser Zeilen als Text auf die Platte geschrieben.

In Zeile 440 habe ich mir zusätzlich die Option eingebaut, mir nur einen bestimmten Wert zu holen (der key steht in $checkVar). Die For-Schleife ist die allgemeine Vorgehensweise gegenüber den speziellen Zugriffen in den Zeilen 379 .. 420

Fehlerbehandlung

  • prüfen, ob das Ziel-Objekt mit diesem Namen existiert Nil($P_Object),
  • erst OB is defined abfragen, ehe ein OB Get gestartet wird, sonst meckert 4D.

JP_DefineVarsIch mag es nicht, wenn ich Objektnamen überall im Code verteilt habe. Darum übergebe ich lokalen Variablen die Objektnamen an einer Stelle – im Kopf der Methode, damit ich weiß wo ich sie finde – und verwende nur die lokalen Variablen im Code. Ändert sich ein Objektname passe ich ihn nur einmal an.

Ich könnte mir alle Objektnamen über FORM GET OBJECTS holen, dann wäre der Code generischer. Das Generische ist hier weniger komfortabel. Ich ziehe dieses Mal das komfortablere vor und verstehe im nächsten Jahr noch, was ich mir heute gedacht hatte.



JSON is a big fuss about of the current years. Before that it was XML or CSV or … forgotten. Never mind, 4D supports JSON. These days I had the idea to simplify stored preferences, by reusing the object names of forms objects as JSON-key (which is the key in key-value or property in 4Ds OB commands descriptions).

Local data

JP_backupPrefsAlways in the need to keep a component as self-contained as possible, there is hardly a situation not to ask the user for some settings. Which means build a dialog, receive, store and retrieve those settings. Could be done by an external.4dd. Too much efforts for hardly a dozen of settings. Seems much less efforts to store them as JSON inside the Resources-folder of the component.

Settings

I’m combining settings I need from the user – backup, destination-folder, planing – with information I’ll present the user – last saved, last error, version-number.

JP_dialogDesign

None of the form-variables has a variable-name. All of them are runtime-variables 4D takes care of while running and when the job is done clearing up. Every variable has an objectname, which is identical to the key of a  JSON-datapoint.

JP_GetSetContentManaging method

  • get the path to the JSON-document
  • an array containing the objectnamec = JSON-keys
  • a case of to access directly (getter/setter)
  • else runs a for-loop across the objects array, to read (get) or write (set) all values
  • time is transferred to JSON as milliseconds (4:00 h equals 14.400 sec), that’s the reason to force reading as time in line 444
  • in case it’s a setter, the current state of JSON will be saved as text to disk.

Line 440 opens up an extra option to get a single value. This is the more generic version of the code in lines 379 .. 420.

Errorhandling

  • checking if there is an object to receive the value Nil($P_Object), which is important.
  • first check if OB is defined before trying OB Get, which is recommended.

JP_DefineVarsI don’t like messy code. That’s why I transfer objectnames into local variables. And I set the variables in the header-area of the method not to search where, but to know where.

Using FORM GET OBJECTS to access objectnames, the code could be more generic. More generic would be less comfortable in this case. I prefer comfortable and easier reading a couple weeks later.