Definitionsbereich Variablen in Lua kapieren

Willkommen in der Transport Fever Community

Wir begrüßen euch in der Fan-Community zu den Spielen Transport Fever und Train Fever, den Wirtschaftssimulatoren von Urban Games. Die Community steht euch kostenlos zur Verfügung damit ihr euch über das Spiel austauschen und informieren könnt. Wir pflegen hier einen freundlichen und sachlichen Umgang untereinander und unser Team steht euch in allen Fragen gerne beiseite.

 

Die Registrierung und Nutzung ist selbstverständlich kostenlos.

 

Wir wünschen euch viel Spaß und hoffen auf rege Beteiligung.

Das Team der Transport-Fever Community


  • Im Moment versuche ich, die modularen Konstruktionen zu kapieren. Bei den modularen Bahnhöfen (modular_station.con) stolpere ich innerhalb der updateFn() über folgendes Konstrukt:


    Code
    ...
            local slotId2Coord = { }
    ...
            result.GetCoord = function(slotId)
                return slotId2Coord[slotId]
            end
    ...

    Für mich, der ich im Pascal/Modula-2/C/C++-Universum groß geworden ist, sieht das so aus, daß in result eine riesige Struktur zurückgegeben wird, die unter anderem die Funktion GetCoord enthält. Diese sollte dann auch außerhalb des Kontextes von updateFn aufrufbar sein, sonst brauche ich sie ja nicht zurückzugeben. Außerhalb dieses Kontextes ist aber die lokale Variable slotId2Coord nicht definiert, es kommt also, weil lua wenig meckert, irgend ein Mist zurück.


    Frage: Verstehe ich die Lebensdauer von slotId2Coord falsch oder ist das ein Bug (der vielleicht nicht zuschlägt, weil niemand GetCoord aufruft)?

    13! = 13*12!

  • https://www.lua.org/manual/5.2/manual.html#3.5


    Und lua tabellen sind referenzen, dies muss man beachten wenn man doch ein deepcopy braucht...


    Sprich, dein result ist eine Tabelle, das ist intern eine Key Value Store und gar nicht mit c++ struct sondern eher mit std::unordered_map zu vergleichen.

    https://www.lua.org/pil/2.5.html


    Für C++ Indianer wichtig, man fängt bei 1 für numerische Indizes in einer Tabelle an, UGs API sind aber C++, so das wenn man zu TPF2 spricht, meist mit 0 beginnt, zum Beispiel defaultIndex bei der UI.



    PS: Und wenn du erst mal LUA Tabellen denkst zu verstehen, kommen metatable ins Spiel und versauen dir den Tag.

  • Danke für die Informationen. Was ich aber immer noch nicht verstehe, ist, daß die Funktion GetCoord mit in der result-Tabelle ist. Ich müßte sie also von außerhalb der updateFn aufrufen können, also außerhalb des Bereichs, in dem slotId2Coord definiert ist. Oder merkt sich lua den gesamten Zustand der Engine bei jeder "abgespeicherten" Funktion oder wenigstens sämtliche innerhalb der Funktion verwendeten lokalen Variablen?

    13! = 13*12!

  • Ja, jede Funktion fügt Referenzen zu genutzten upValues hinzu, so das sie weiterhin im Scope sind.


    Zum guten Stil gehört daher, seine Variablen soweit lokal zu deklarieren, d.h. lokal zum Modul, zur Funktion usw.

    Einerseits, damit dein Mod nicht andere Mods beeinflussen bzw. dein Mod beeinflusst wird.

    Nichts ist ärgerlich wenn Mod A mit B nicht funktioniert und man dann stundenlang Debugging machen muss.


    Lua schaut technisch jeweils die upValues in den nächsten Variablenscope (auch ne interne Tabelle), ist da nix in der Tabelle, geht es in den nächst höheren Variablen Scope usw.


    PS: Die interne sind etwas komplizierter und das ist jetzt nur grob gesagt.

    Die Funktions-Deklarationen sind technisch eigentlich eine Zuweisung Variable = Funktionsobjekt, also syntaktischer Zuckerguss
    local function myFn() end
    ist dann:
    local myFn = function() end

  • Ich habe noch mal rumgespielt (allerdings mit dem Lua-Interpreter von Linuchs)

    Es druckt tatsächlich "Zweite Festlegung". Es ist also so, daß die Lebensdauer von text erst endet, wenn die letzte Referenz verschwunden ist und nicht, wenn die Umgebung geschlossen wird (Die Garbage Collection kommt ja erst nach Ende der Lebensdauer ins Spiel).

    13! = 13*12!

BlueBrixx