RegisterVariable* Rückgabeparameter verändern?

Ich habe mir die Problematik noch einmal angesehen, dass man beim Erstellen von Status Variablen keinen echten Standardwert setzen kann, da nie bekannt ist, ob die Variable erstellt wurde, oder nicht. (Es wäre aufwendig möglich, indem man vor dem Aufruf prüft, ob die SV vorhanden war…)

Die damalige Idee war, dass man als Rückgabeparameter nicht die ID, sondern einen Boolean Wert liefert. Das würde jedoch die Abwärtskompatibilität beeinträchtigen. Zur 5.0 hätten wir die Chance dies zu ändern. Insgesamt würde die Änderung auch sehr einfach zu bewerkstelligen sein und (sofern man das neue Feature nicht nutzt) wäre eine einfache Kompatibilität zu 4.4 und älter und gleichzeitig 5.0 sehr einfach möglich.

Vorschlag zur 5.0


//Setze 18.5 als Standardwert beim Erstellen der Variable
if($this->RegisterVariableInteger("SollTemperatur", "Soll Temperatur", "Temperature", 0)) {
  SetValue($this->GetIDForIdent("SollTemperatur"), 18.5);
}

Was müsste angepasst werden in alten Modulen, sofern der Rückgabewert genutzt wird?

Vorher:


$id = $this->RegisterVariableInteger("SollTemperatur", "Soll Temperatur", "Temperature", 0);
SetValue($id, 18.5);

Nachher:


//Da die ID nicht mehr kommt, müsste zur Zeit GetIDForIdent genutzt werden*
$this->RegisterVariableInteger("SollTemperatur", "Soll Temperatur", "Temperature", 0);
SetValue($this->GetIDForIdent("SollTemperatur"), 18.5);

Was haltet ihr von dem Vorschlag?

Anmerkung: Da in Zukunft ein neues $this->SetValue kommt, um das ReadOnly Flag und Sandboxing korrekt zu verwirklichen (@Nall-Chan erklärt euch gerne warum das wichtig ist :D), wird diese Änderung sowieso irgendwann notwendig. Jedoch ist diese Änderung jetzt ein Breaking Change - die SetValue Geschichte könnte man langsam über eine Deprecated Warning einführen. Sobald diese also „durch ist“, ist der Rückgabewert obsolete. Wir könnten also ggf. die Änderung des Rückgabewertes bis zur 6.0 zurückstellen, wodurch es kein Breaking Change mehr wäre.

Bonus: In dem Zuge würden wir auch die ConnectParent, RequireParent und ForceParent Funktionen anpassen, sodass dort auch ein Boolean Rückgabewert vorhanden ist, der das Erstellen der Instanz signalisiert.

Zuerst eine Frage:
Warum überhaupt ein Startwert ?

Sinnvoller ist es ja eigentlich Variablen erst anzulegen wenn sie auch benötigt werden; aber das ist ja Sache jedes Modul-Entwicklers.

Ich nutze eigentlich lieber MaintainVariable, wenn ich viele unterschiedliche Statusvariablen habe und diese z.B. in einer Schleife mit den bearbeiteten zerlegten Nutzdaten erstellt und beschrieben werden sollen.
MaintainVariable hatte gar keinen Rückgabewert, oder ?

Von daher habe ich auch jetzt schon Module wo $this->SetValueInteger deklariert wird, welches bei Bedarf die Statusvariable anlegt. Die Daten für Profil und EnableAction liegen dazu in einem Array vor.


    /**
     * Setzte eine IPS-Variable vom Typ integer auf den Wert von $value.
     *
     * @access protected
     * @param string $Ident Ident der Statusvariable.
     * @param integer $value Neuer Wert der Statusvariable.
     */
    protected function SetValueInteger($Ident, $value)
    {
        if (is_null($value))
            return false;
        $vid = $this->GetStatusVariable($Ident, vtInteger);
        SetValueInteger($vid, $value);
    }

    protected function GetStatusVariable($Ident, $Type)
    {
        $vid = @$this->GetIDForIdent($Ident);
        if ($vid === false)
        {
            $Profile = (array_key_exists($Ident, self::$StatusvarProfile]) ? self::$StatusvarProfile[$Ident] : "");
            $this->MaintainVariable($Ident, $Ident, $Type, $Profile, 0, true);
             if (in_array($Ident, self::$StatusvarAction))
             {
                $this->EnableAction($Ident);
             }
            $vid = $this->GetIDForIdent($Ident);
        }
        return $vid;
    }

Oder für weniger Variablen und Profile ohne Action so etwas:

    /**
     * Setzte eine IPS-Variable vom Typ integer auf den Wert von $value.
     *
     * @access protected
     * @param string $Ident Ident der Statusvariable, darf aber auch Leerzeichen für den Namen enthalten.
     * @param int $Value Neuer Wert der Statusvariable.
     * @return bool true wenn Variable vorhanden sonst false.
     */
    protected function SetValueInteger($Ident, $Value, $Profile = "")
    {
        $id = $this->RegisterVariableInteger(str_replace(' ', '', $Ident), $this->Translate($Ident), $Profile);
        SetValueInteger($id, $Value);
    }

Andere Punkt ist, wann braucht man diese Info ob die Variable neu erstellt wurde sonst noch ?

Vorschlag:
Den Startwert möchte ich dann lieber als optionalen Parameter in RegisterVariable haben.
Somit auch kein Breaking Change :smiley:

Alternativ, wenn ihr RegisterVariable den Rückgabewert ändert, auch zeitgleich $this->SetValue*($Ident) einführen.
Dann bearbeitet man diesen Part im Modul nur einmal und nicht zwei bis dreimal :wink:
Das Read-Only Flag kann ja gerne später kommen.
Michael

Verstehe das Problem nicht. RegisterVariableInteger liefert doch eine Id zurück. Da sieht man doch direkt ob was angelegt wurde oder nicht. Auch finde ich das der Defaultwert wenn direkt als ein Argument übergeben werden sollte.

Auch wäre es mal praktisch dass MaintainVariable mal die InstanzId ebenfalls zurück gibt.

Die ID wird auf lange Sicht nicht mehr notwendig sein, da du nur über den Ident diese ansprechen kannst.

Warum überhaupt ein Startwert ?

z.B. Wenn du ein Modul hast welches eine Aktiv/Inaktiv Variable hast, und du sicherstellen willst, dass nach dem Erstellen des Modul diese Variable aktiv ist.

Ich überlege aber gerade, ob ich das mit dem optionalen Parameter mache… Das wäre in der Tat elegant und abwärtskompatibel möglich.

paresy

Spätestens wenn man auf Veränderungen der eigenen Statusvariable sich mit RegisterMessage anmelden möchte, braucht es die ID.
So ganz ohne wird es wohl nie funktionieren :wink:
Warum man so etwas machen möchte?
Um weitere Aktionen entkoppelt vom ursprünglichen PHP-Thread durchzuführen.
Sonst läuft man im Datenaustausch gerne in einen deathlock.

Michael

Ich stelle das Thema erstmal zurück und baue den einen optionalen Parameter ein, der den Default Wert angeben kann. Das ist dann auch Konsistent zu den RegisterProperty Befehlen.

paresy