Sauber vorzeitig Skriptablauf beenden

  • Hallo Leute.


    Ich taste mich grade ganz vorsichtig an das Skripten in Arma3 ran und suche aktuell nach einer sauberen Lösung, Skripte oder Schleifen vorzeitig zu beenden.
    Dabei sehe ich oft Gebilde in der folgenden Art.

    Code
    1. if ( condition ) exitWith{...};


    Auf https://community.bistudio.com/wiki/exitWith lese ich, dass es nur den aktuellen Scope verlässt.
    Weiter lese ich, dass das Verhalten u.U. nicht klar definiert ist, wenn man diese Anweisung nicht innerhalb einer Schleife verwendet.
    So wie ich das im Moment sehe, entstehen damit unschöne Konstrukte mit Hilfsvariablen. Insbesondere dann, wenn man innerhalb einer Schleife eine Abbruchbestimmtung für das gesamte Skript definieren will.


    Auf der selben Seite gibt es noch den Hinweis auf scopeName, breakTo und breakOut; klingt nach Goto.
    Ist es eurer Meinung nach gutes oder schlechtes KungFu, wenn man innerhalb seiner SQF-Dateien per breakTo und/oder breakOut aus Scopes ausbricht?


    Als Beispiel hier der Aufbau einer /foo/bar.sqf

    Code
    1. scopeName "foo_bar.sqf"; // <-- erste Zeile im Skript.
    2. ...
    3. if ( fatal_error ) then {
    4. ...
    5. breakOut "foo_bar.sqf";
    6. };
    7. ...

  • es ist im grunde das "return" von arma


    breakOut & breakTo werden jedoch kaum genutzt da es sich nicht richtig anfühlt sie zu nutzen
    mit ihnen kann man jedoch einiges simulieren sodass auch richtige return anweisungen möglich sind


    der richtige weg um aus einem loop (bsp) auszubrechen ist übrigens mit besagten breakOut und breakTo lösungen

  • X39: Vielen Dank für deine Antwort.
    Magst du mir ein Beispiel für deine simulierte return-Variante geben?
    Ich stelle mir das grad etwas schwierig vor - besonders wenn aus tief verschachtelten Scopes ausgebrochen werden soll.

  • vorrausgesetzt du nutzt CfgFunctions (sonst musst du die _fnc_scriptName variable selbst setzen)

    Made with KK's SQF to BBCode Converter


    wie unschwehr zu erkennen ist funktioniert das ganze mit einer kombination aus variable setzen und breakTo


    ist jedoch minimal langsamer durch den kleinen overhead des zweiten calls


  • Danke sehr! :-)
    Warum am Ende _returnValue und nicht ___returnValue___ steht, traue ich mich aber nicht zu fragen.


    Nachtrag:
    Oh, das Beispiel in deinem Spoiler gefällt mir wesentlich besser!
    Ich versuche über dieses Forum mehr dazu in Erfahrung zu bringen.
    Abschließend muss ich doch noch mal nachfragen.
    Warum steht am Ende _returnValue? Einfach nur ein Flüchtigkeitsfehler? Oder hängt das mit CfgFunctions zusammen?
    Sorry, dass ich frage. Bin ganz am Anfang ;-)



  • ist ein flüchtigkeits fehler ...
    sollte ebenfalls ___returnValue___ sein :P

  • Wenn man seinen Code vernünftig strukturiert braucht man weder breakTo noch breakOut. Auch scopeName ist meiner Meinung nach ein Befehl den man eigentlich nicht braucht.
    Solche Sachen kommen noch aus dem Assemblybereich und sind nur dann sinnvoll wenn man keine Funktionsaufrufe nutzen kann.


    Ich stelle mal die Behauptung auf, dass jede Nutzung dieser Befehle auch mit exitWith umgesetzt werden kann.


    Wenn du in einer Schleife das Script verlassen willst, impliziert das immer, dass du auch die Schleife verlassen willst. Also verlässt du erst die Schleife und nach der Schleife dann das Script.
    Eventuell bietet sich es auch an solch ein Abbruchbedingung vorab in einer separaten Schleife zu prüfen.
    Beispielcode:

    PHP
    1. if (({ abbruchBedingung } count _meinArray) > 0) exitWith {};

  • Code
    1. if(<IrgendEineBedingung>) then
    2. {
    3. if(<NochEineBedingung>) exitWith {/*Wir wollen hier raus aus der funktion, ups ... nicht möglich*/};
    4. }
    5. <MehrCode>


    sie sind nicht nötig jedoch mehr als nur ein bisschen hilfreich
    gerade bei der emulierung von return (was im grunde auch nichts anderes ist als eine sprung anweisung)

  • NetFusion:
    Nur beendet exitWith immer nur den aktuellen Scope, richtig?
    Intuitiv bin ich an soetwas hängen geblieben und hatte das Thema SQF mit übelsten Beschimpfungen lange Zeit bei Seite geschoben.

    Code
    1. if ( true ) then { exitWith{}; };


    Sicherlich hast du Recht; mit Planung lässt sich vieles vermeiden.
    Aber dafür muss man sich erst einmal ausreichend mit der Sprache auskennen (damit meine ich mich!) ;-)

  • Nur beendet exitWith immer nur den aktuellen Scope, richtig?


    Korrekt


    Code
    1. if ( true ) then { exitWith{}; };


    PHP
    1. if (true) exitWith {};


    Du hast ja auch noch die Möglichkeit in den Codeblock des exitWith Schleifen zu schreiben:

    PHP
    1. if (true) exitWith {
    2. {
    3. if (true) exitWith {};
    4. } forEach _meinArray;
    5. };


    Am meisten lernt man indem man einfach mal Sachen in der Debugkonsole ausprobiert und sich die Erkenntnisse merkt oder irgendwo aufschreibt.
    Wichtig ist meiner Meinung nach aber bevor man irgendwas veröffentlicht (oder andere Spieler drauf los lässt) sollte man sich Gedanken machen ob man alle Möglichkeiten bedacht hat und ob es nicht einen besseren Ansatz gibt die Idee umzusetzen.
    Meistens gehen die Anforderungen dann schon über die Grundidee hinaus und man findet einen besseren Weg. Dann sollte man auch wenn es viel Arbeit ist neu starten und nicht den Code versuchen zu verbiegen.

  • Bezüglich der Unterschiede in SQF zwischen

    Code
    1. if ( true ) then { exitWith{}; };


    und

    Code
    1. if ( true ) exitWith{};


    Das ist mir heute bewusst.
    Erwartet habe ich das unterschiedliche Verhalten aber nicht und vermutlich sind viele vor mir darüber gestolpert und es werden noch viele nach mir kommen.


    Bez. deines letzten Beispiels:

    Code
    1. scopeName "myScope";
    2. {
    3. if ( true ) then {
    4. breakTo "myScope";
    5. };
    6. } forEach _myArray;


    Finde ich schöner.
    Spart einen Kontextwechsel und eine If-Abfrage.
    Aber ich kenne SQF noch nicht so genau und weiß nicht, was besser ist.
    Um so mehr freue ich mich über Beispiele wie du sie mir gibst.
    Danke!



    Nachtrag:
    Ich glaube, deine Variante beendet das ganze Skript. Sorry ;-)