Wie man Konfigurationen und den Storage benutzt


Die Konfiguration

Der einfachste Weg, Blöcke und Einstellungen in Skripten zu konfigurieren, besteht darin, alles fest zu in den Code zu schreiben. Allerdings gibt Fälle - besonders wenn Du vor hast, Dein Skript zu veröffentlichen - die Konfigurationen den Benutzer vornehmen zu lassen. Keen hat dazu das Feld CustomData eingeführt. Diese Feld steht allen Blöcken zu Verfügung, und jeder Benutzer kann dort beliebigen Text eingeben. Skripter können das zu ihrem Vorteil nutzen, indem sie ihre Benutzer die Konfiguration dort eingeben lassen, anstatt das er, vielleicht unversiert, Skript und Code öffnen muss um umständlich Wert anzupassen. Das kann leicht zu Fehlern führen.

Auf dieses Feld wird als einfache CustomData-Eigenschaft zugegriffen und hat den String. Wie Du bereits weißt, wird beispielsweise auf den aktuell laufenden programmierbaren Block über die Skript-Eigenschaft Me zugegriffen. Um also zu den CustomData-Feld des programmierbaren Blocks zu gelangen, musst du ledeglich foglendes tun:

public void Program() 
{
    var customData = Me.CustomData;
}

Allerdings ist nur eine reine Zeichenkette nicht sonderlich nützlich. Um den Umgang mit Konfigurationsinformationen zu erleichtern, wurde die Klasse MyIni eingeführt. Diese Klasse hilft Ihnen beim Parsen und Lesen von Zeichenketten im althergedienten INI-Format.

Hinweis: Wenn Sie eine IDE wie Visual Studio verwenden und diese Klasse in einem bestehenden Skript verwenden möchten, müssen Sie möglicherweise mit VRage.Game.ModAPI.Ingame.Utilitiesals Using Direktive einbinden.

[ErsterDatenAbschnitt]
;Kommentare werden mit Semikolon eingeleitet und werden nicht geparsed
EinSchluessel=Der Wert dieses Schluessels
NocheinSchluessel=Noch ein Wert

[AndererAbschnitt]
EinSchluessel=15

Das ist ein sehr einfaches Format, und es ist auch für diejenigen ohne Programmierkenntnisse leicht zu erlernen. Es wird nur das einfache INI-Format unterstützt, keine der Escapes oder anderen erweiterten Funktionen - hier geht es alleine um hohe Leistungsfähigkeit. MyIni fügt jedoch noch ein kleines aber feines Feature hinzu:

Mehrzeilige Werte

Das Konstrukt für Mehrzeilige Werte ermöglicht es Dir Texte mit Zeilenumbrüchen auf relativ einfache Weise einzubinden:

[Abschnitt]
;Die folgende Zeilen sind ein spezielles Format welches mehrzeilige Texte erlaubt:
MehrzeiligerWert=
|Die erste Ziele 
|Die zweite Zeile
|Und so weiter

Beachte, dass nach dem = nichts stehen darf, der gesamte Wert wird im Abschnitt mit den Pipe-Zeichen (|) definiert.

INI-File abschließen

Drei Bindestriche in einer separaten Zeile weisen den Parser an, mit dem Parsen aufzuhören und den Rest des Inhalts einfach in der EndContent-Eigenschaft von MyIni zu speichern:

---


Die Grundlagen

Um diese Daten zu lesen, müssen Sie zunächst eine Instanz der Klasse MyIni instanziieren. Wie immer wird empfohlen, eine einzelne Instanz zu erstellen und diese Instanz im gesamten Skript wiederzuverwenden.

Baue einen programmierbaren Block und öffne den Editor. Trage in das Feld CustomData folgende Konfiguration ein:

[demo]
jetztAusgeben=true
ausgabe=LCD Panel
textZurAusgabe=Dieser Text wird auf dem LCD erscheinen

Füge dem Grid jetzt noch ein LCD-Panel hinzu, stelle sicher, dass er "LCD Panel" heißt - oder ändern Sie den Namen in den CustomData des programmierbaren Blocks entsprechend.

Öffnen Sie den Code-Editor des programmierbaren Blocks und geben Sie den folgenden Code ein. Vergiss nicht, die erklärenden Kommentare im Code zu lesen:

// Instantiiere ein Instanz des MyIni Parser
MyIni iniParser = new MyIni();

bool _jetztAusgeben;
string _ausgabe;
string _textZurAusgabe;
IMyTextPanel _ausgabeLCD;

public Program()
{
    // Rufe die TryParse-Methode auf das CustomData-Feld auf. Diese Methode wird false
    // zurückgeben wenn die Eingabe nicht kompatibel ist
    MyIniParseResult ergebnis;
    if (!iniParser.TryParse(Me.CustomData, out ergebnis)) {
        throw new Exception(ergebnis.ToString());
    }

    // Hole den Wert vom "jetztAusgeben" Schluessel im "demo"-Abschnitt.
    // Dann rufe ToBoolean() auf, damit der Wert in den Typ 
    // bool konvertiert wird.
    _jetztAusgeben = _ini.Get("demo", "jetztAusgeben").ToBoolean();
    
    // Hole jetzt den Wert des Schluessel "ausgabe". Diese mal konvertieren wir ihn
    // in einen string.
    _ausgabe = _ini.Get("demo", "ausgabe").ToString();

    // Dann schließlich der Ausgabe Text
    _textZurAusgabe = _ini.Get("demo", "textZurAusgabe").ToString();

    // Wenn in der Konfiguration steht das Text direkt ausgegeben wird
    // müssen wir dem programmierbaren Block sagen das er sich selbst einmal ausführen soll.
    if (_jetztAusgeben) 
    {
        Runtime.UpdateFrequency = UpdateFrequency.Once;
    }
}

public void Main() 
{
    // Gibt den konfigurierten Text jedesmal dann aus, wenn der Skript ausgeführt wird
    // Wenn der Ausgabe LCS-Panel mnoch nicht zugwieesen wurde, hole ihn jetzt
    if (_ausgabeLCD == null) 
    {
        // Nimm den ausgabe LCD der in der Konfiguration in den CustomData eingestellt wurde
        _ausgabeLCD = GridTerminalSystem.GetBlockWithName(_ausgabe) as IMyTextPanel;
    }
    if (_ausgabeLCD == null) {
        // Keine Ausgabe wenn der LCD nicht gefunden werden kann und beende das Skript
        Echo("Kein Ausgabe LCD gefunden");
        return;
    }

    // Füge den konfigurierten Text an den Text des LCD-Panel
    _ausgabeLCD.WritePublicText(_textZurAusgabe, true);
    // Und füge einen Zeilenumbruch ein
    _ausgabeLCD.WritePublicText("\n", true);
}

Du kannst die Werte der CustomData-Konfiguration ändern (lassen Sie die Namen der Abschnitte und Schlüssel so wie er ist, ändere einfach die Werte) und sieh Dir die Ergebnisse an. Für eine Erläuterung der Update-Frequenz siehe das Kapitel Programmierbare Blöcke dauerhaft und wiederkehrend ausführen.

Typkonvertierungen

Im obigen Beispiel sehen wir die Verwendung von .ToBoolean(); und .ToString(); in Bezug auf die iniParser.Get-Aufrufe. Für die Konfigurationswerte stehen mehrere Typkonvertierungsmethoden zur Verfügung. Jeder Typ hat zwei Varianten: Das To* und das TryGet*. Ersteres wird versuchen, den Wert zu konvertieren, und wenn er fehlschlägt, wird er einfach auf den Standardwert zurückgesetzt. Die zweite gibt einen Boolean zurück, der Ihnen mitteilt, ob die Konvertierung erfolgreich war oder nicht. Verwenden Sie das, was am besten zu Ihrem Skript passt.

  • bool ToBoolean(bool defaultValue = default(bool))
  • bool TryGetBoolean(out bool value)
  • char ToChar(char defaultValue = default(char))
  • bool TryGetChar(out char value)
  • sbyte ToSByte(sbyte defaultValue = default(sbyte))
  • bool TryGetSByte(out sbyte value)
  • byte ToByte(byte defaultValue = default(byte))
  • bool TryGetByte(out byte value)
  • ushort ToUInt16(ushort defaultValue = default(ushort))
  • bool TryGetUInt16(out ushort Wert)
  • short ToInt16(short defaultValue = default(short))
  • bool TryGetInt16(out short value)
  • uint ToUInt32(uint defaultValue = default(uint))
  • bool TryGetUInt32(out uint Wert)
  • int ToInt32(int defaultValue = default(int)))
  • bool TryGetInt32(out int Wert)
  • ulong ToUInt64(ulong defaultValue = default(ulong))
  • bool TryGetUInt64(out ulong value)
  • long ToInt64(long defaultValue = default(long))
  • bool TryGetInt64(out long value)
  • float ToSingle(float defaultValue = default(float))
  • bool TryGetSingle(out float value)
  • double ToDouble(double defaultValue = default(double))
  • bool TryGetDouble(out double value)
  • dezimal ToDecimal(dezimal defaultValue = 0)
  • bool TryGetDecimal(out dezimaler Wert)
  • string ToString(string defaultValue = default(string))
  • bool TryGetString(out string value)

Es gibt auch die Methodevoid GetLines(List<string> lines), die die angegebene Liste mit den einzelnen Zeilen des Konfigurationswertes füllt.