Godot: Anmerkungen in GDScript

Erstellt am 21. Juli 2018  ·  45Kommentare  ·  Quelle: godotengine/godot

Vor etwa einem Jahr gab es eine PR, die Anmerkungen für GDScript hinzufügte (#9469). Es wurde hauptsächlich abgelehnt, weil es keine direkte Verwendung dafür gab (keine Daten im Parse-Baum, nur Tools von Drittanbietern würden davon Gebrauch machen).

Dieser Vorschlag besteht darin, Anmerkungen auf eine Weise hinzuzufügen, die GDScript erweiterbarer macht, ohne weitere Schlüsselwörter einzuhacken.

Wofür können Anmerkungen verwendet werden?

  • export Tipps. Im Moment verwendet es eine benutzerdefinierte Syntax für jeden Typ. Mit Annotationen könnte es direkt die Verwendung und den Hinweis für die PropertyInfo festlegen, wodurch neue Ergänzungen des Inspektors besser genutzt werden können, ohne eine neue Syntax im GDScript-Parser hacken zu müssen.
    Um das klarzustellen, würde ich das Schlüsselwort export belassen, nur die Hinweise würden zu Anmerkungen verschoben. Typ kann mit Typhinweisen definiert werden.
  • Dazu gehören auch Kategorien für export (#4378, #10303).
  • Ersetzen Sie das Schlüsselwort onready durch eine Anmerkung.
  • Deaktivieren bestimmter Warnungen. #19993 fügt Warnungen mit einer Ad-hoc-Syntax hinzu, um sie zu deaktivieren, aber es könnten stattdessen Anmerkungen verwendet werden.
  • setget (es ist eine seltsame Syntax, wenn Sie nur den Getter haben wollen).
  • RPC-Schlüsselwörter ( master , slave , sync , remote ).
  • Neue Präprozessor-Anweisungen, wie das Kompilieren einer Funktion nur im Editor (mit tool ) oder nur im Debug-Modus (bezogen auf #12837).
  • Eventuelle Diskussion über neue Syntax (wie Signal, das bei Variablenänderung ausgegeben wird: #6491).
  • Vielleicht die Möglichkeit, benutzerdefinierte "Dekoratoren" hinzuzufügen.

Vorteile
Jedes Mal, wenn ein neues Schlüsselwort hinzugefügt wird, sind Änderungen am GDScript-Tokenizer und -Parser erforderlich, um damit umzugehen. Insbesondere das export Parsing ist ziemlich kompliziert und wird mit anderen klassenbezogenen Parsings vermischt.

Bei Annotationen wäre weniger Arbeit erforderlich, um ein bestimmtes Attribut hinzuzufügen (wie export, setget, onready), stattdessen müsste nur überprüft werden, welche Annotationen vorhanden sind.

Nachteile
Das Hinzufügen von Anmerkungsunterstützung würde mehr Änderungen am Parser erfordern als jedes Schlüsselwort allein. Es kann auch dazu führen, dass Benutzer neue Funktionen als "nur eine Anmerkung" vorschlagen.

Syntax
Ich habe keine besondere Vorliebe für Syntax, aber ich stelle mir so etwas wie Python-Dekoratoren vor. Dies kann jedoch für Python-Benutzer verwirrend sein, da Annotationen nicht mit Dekoratoren identisch sind.

<strong i="41">@onready</strong>
var my_sprite = $Sprite

Für die Übergabe von Argumenten könnte es wie Funktionen funktionieren:

@export_hint(ENUM)
@export_hint_string("Attack,Defense")
export var my_enum : int = 0

Vielleicht ohne Klammern:

<strong i="48">@export_hint</strong> ENUM
<strong i="49">@export_hint_string</strong> "Attack,Defense"
export var my_enum : int = 0

Oder verwenden Sie benannte Parameter (und vermeiden Sie das Schlüsselwort):

<strong i="53">@export</strong> type=String hint=MULTILINE
var my_text = ""

Oder etwas anderes.

Benutzerdefinierte Anmerkungen
Unbekannte Anmerkungen werden einfach ignoriert (evtl. mit einer Warnung). So können Tools von Drittanbietern die Anmerkungen analysieren, um andere Funktionen anzubieten, wie z. B. die Dokumentationserstellung.

Es ist auch möglich, eine Introspektion-API hinzuzufügen: get_method_annotations() , get_property_annotations() oder so ähnlich. Auf diese Weise können Plugins, die beispielsweise Skripte erwarten, Annotationen verwenden, um zu entscheiden, welche Methode aufgerufen werden soll, anstatt einen hartcodierten Namen zu verwenden.

archived discussion feature proposal gdscript

Hilfreichster Kommentar

Warum wird die Syntax von gdscript so stark modifiziert? Es wurde ursprünglich so konzipiert, dass es einfach, leicht zu erlernen und intuitiv ist. ich fürchte, mit all diesen neuzugängen (getippte gds, annotationen) wird es für neue entwickler sehr verwirrend.

Die meisten (wenn nicht alle) Änderungen der GDScript-Syntax sind mit altem Code kompatibel. Das Hauptziel besteht darin, die Produktivität von Entwicklern zu steigern, die GDScript verwenden, z. B.:

  • match Anweisungen ermöglichen Switch-Case-Anweisungen (die durchaus gewünscht wurden) und verbessern dies sogar, indem sie es den Leuten ermöglichen, Arrays und Wörterbücher mit Leichtigkeit abzugleichen.
  • onready Variablen (die in 2.x neu waren) konkretisieren ein oft benutztes Muster, nämlich die Initialisierung von Variablen in _ready .
  • Mit typisiertem GDScript können sich Entwickler endlich darauf verlassen, dass keine Fehler mit falschem Typ auftreten, und gleichzeitig von einer besseren Autovervollständigung profitieren. Es ist optional, sodass Neulinge es nicht für ihr erstes Spiel lernen müssen.

Ich habe nur das Gefühl, dass es eine mögliche Trennung zwischen den tatsächlichen Spielentwicklern und den Mitwirkenden geben könnte.

Dies ist eine offene Gemeinschaft. Spieleentwickler sind herzlich eingeladen, ihre Meinung zu äußern, genau wie Sie. Jedenfalls wird noch einige Zeit vergehen, bis Annotationen Realität werden.

[...] ich befürchte nur, dass gds sich immer weiter von seiner einfachheit entfernt, das ist alles. es ist schon mehr als genug...

Wenn es bereits gut genug wäre, würden wir keine Funktionsanfragen dafür erhalten.

Außerdem ist es sehr umständlich, 3 Zeilen für ein Export-Schlüsselwort zu haben, im Vergleich dazu, alles in einer Zeile anzugeben. zum Beispiel: onready var my_sprite = $Sprite ist viel sauberer

Die Syntax ist noch nicht finalisiert. Es ist sehr wahrscheinlich, dass es die Schlüsselwörter onready und export sofort ersetzt.

Alle 45 Kommentare

Nur damit ich die benutzerdefinierten Anmerkungen richtig verstehe, könnte ich so etwas haben:

<strong i="6">@description</strong> "Adds two numbers and returns the result."
<strong i="7">@parameter</strong> name=num1 type=float description="The first number"
<strong i="8">@parameter</strong> name=num2 type=float description="The second number"
<strong i="9">@returns</strong> type=float description="num1 and num2 added together"
func add(num1, num2):
    return num1 + num2

Und ich könnte eine Funktion aufrufen, sagen wir get_annotations("add") , die diese Anmerkungen zurückgibt? Auch wenn diese Anmerkungen von Godot nicht als eingebautes Schlüsselwort/eine eingebaute Anmerkung erkannt werden?

@ LikeLakers2 ja, das ist das Wesentliche.

Ich mag es, ich weiß nicht für die Implementierung dahinter, aber im GDscript-Code würde es viel sauberer aussehen, als es jetzt aussieht. Vor allem für das Setget-Beispiel.

Dies ist sehr nützlich, sollte aber aus Gründen der Lesbarkeit einzeilige Anweisungen ermöglichen. Zum Beispiel,
<strong i="6">@onready</strong> var a = $A sollte erlaubt sein. Andernfalls fügt dies eine Menge Zeilenumbrüche hinzu und würde in diesem Fall das Nützliche von onready verschwenden.

Etwas wie

<strong i="10">@onready</strong>
    var a = $A
    var b = $B
    var c = $C

Es wäre sinnvoll, dieselbe Annotation auf mehrere Anweisungen anzuwenden.

Außerdem könnte ein Doppelpunkt verwendet werden, um anzugeben, wo die Anmerkung endet und wo die betroffene(n) Anweisung(en) beginnen, um mit dem Rest von GDScript konsistent zu sein.

Wenn Anmerkungen mit einem klaren Anfang und Ende geparst werden können, sind keine Semikolons erforderlich und können dann bei Bedarf in dieselbe Zeile gestellt werden (wenn sie beispielsweise '()' verwenden oder argumentlos sind)

Ich glaube nicht, dass vnen alte Shortcut-Keywords entfernen wollte?

Auch Textmarker handhaben diese kann helfen.

Zu spät zur Party hier, aber sehr daran interessiert, wie dies Kategorien für Export-Variablen bereitstellen und Tool-/Debug-Skript-Unterteilungen erstellen könnte?

Vorläufig die 3.2-Roadmap aufsetzend, würde ich es wirklich gerne sehen, dass dies früher als später implementiert wird, um dem Editor Verbesserungen der Benutzerfreundlichkeit zu bieten.

#### unpopuläre Meinung eingehend:

Warum wird die Syntax von gdscript so stark modifiziert? Es wurde ursprünglich so konzipiert, dass es einfach, leicht zu erlernen und intuitiv ist. ich fürchte, mit all diesen neuzugängen (getippte gds, annotationen) wird es für neue entwickler sehr verwirrend. Wenn sich beispielsweise eine neue Person bei Godot ein Tutorial ansieht und den Code im Beitrag von LikeLakers2 sieht, würde ich mir vorstellen, dass das ihren Kopf explodieren lässt. wenn überhaupt, müssten sie eine Menge Fragen dazu stellen / wie es funktioniert usw.

Ich verstehe total die Liebe aller für GDS und wie die Mitwirkenden es besser machen wollen usw. Ich habe einfach das Gefühl, dass es eine mögliche Trennung zwischen den tatsächlichen Spielentwicklern und den Mitwirkenden geben könnte (ich sage nicht, dass Mitwirkende keine Spieleentwickler sind, sondern nur, wie einige Funktionen werden nicht wirklich benötigt). nicht jeder muss diese Funktionen nutzen. ich befürchte nur, dass gds sich immer weiter von seiner einfachheit entfernt, das ist alles. es ist schon mehr als genug...

Außerdem ist es sehr umständlich, 3 Zeilen für ein Export-Schlüsselwort zu haben, im Vergleich dazu, alles in einer Zeile anzugeben. zum Beispiel: onready var my_sprite = $Sprite ist so viel sauberer (für mich jedenfalls)

und zu Punkt #4, dies kann im Editor AFAIK erfolgen. Imo auch, wenn überall im Code Anmerkungen zum Deaktivieren bestimmter Warnungen vorhanden sind, kann dies zu sehr unordentlichem Code führen

Warum wird die Syntax von gdscript so stark modifiziert? Es wurde ursprünglich so konzipiert, dass es einfach, leicht zu erlernen und intuitiv ist. ich fürchte, mit all diesen neuzugängen (getippte gds, annotationen) wird es für neue entwickler sehr verwirrend.

Die meisten (wenn nicht alle) Änderungen der GDScript-Syntax sind mit altem Code kompatibel. Das Hauptziel besteht darin, die Produktivität von Entwicklern zu steigern, die GDScript verwenden, z. B.:

  • match Anweisungen ermöglichen Switch-Case-Anweisungen (die durchaus gewünscht wurden) und verbessern dies sogar, indem sie es den Leuten ermöglichen, Arrays und Wörterbücher mit Leichtigkeit abzugleichen.
  • onready Variablen (die in 2.x neu waren) konkretisieren ein oft benutztes Muster, nämlich die Initialisierung von Variablen in _ready .
  • Mit typisiertem GDScript können sich Entwickler endlich darauf verlassen, dass keine Fehler mit falschem Typ auftreten, und gleichzeitig von einer besseren Autovervollständigung profitieren. Es ist optional, sodass Neulinge es nicht für ihr erstes Spiel lernen müssen.

Ich habe nur das Gefühl, dass es eine mögliche Trennung zwischen den tatsächlichen Spielentwicklern und den Mitwirkenden geben könnte.

Dies ist eine offene Gemeinschaft. Spieleentwickler sind herzlich eingeladen, ihre Meinung zu äußern, genau wie Sie. Jedenfalls wird noch einige Zeit vergehen, bis Annotationen Realität werden.

[...] ich befürchte nur, dass gds sich immer weiter von seiner einfachheit entfernt, das ist alles. es ist schon mehr als genug...

Wenn es bereits gut genug wäre, würden wir keine Funktionsanfragen dafür erhalten.

Außerdem ist es sehr umständlich, 3 Zeilen für ein Export-Schlüsselwort zu haben, im Vergleich dazu, alles in einer Zeile anzugeben. zum Beispiel: onready var my_sprite = $Sprite ist viel sauberer

Die Syntax ist noch nicht finalisiert. Es ist sehr wahrscheinlich, dass es die Schlüsselwörter onready und export sofort ersetzt.

Ich mag die Idee wirklich, sehr wie Attribute in C#.

Klassen- und Signalanmerkungen könnten ebenfalls interessant sein.

Inspektor-Plugins, die automatisch in Aktion treten, unabhängig davon, ob eine Eigenschaft, Methode oder Klasse eine bestimmte benutzerdefinierte Annotation hat, wäre ein Kinderspiel.
Was die Syntax angeht, würde ich etwas bevorzugen, das optional auch in einer einzigen Zeile geschrieben werden könnte, aber es ist nicht so wichtig.

Wie könnte der Prozess der Definition benutzerdefinierter Anmerkungen aussehen? Ich würde es vorziehen, dass sie nicht jedes Mal im Code frei definiert sind, sondern vom Benutzer mit einer eindeutigen Definition erstellt werden, genau wie Klassen.

Ich denke, dies muss genauer untersucht werden. Ich denke, es wäre großartig, die Sprache (als optionale Syntax usw.)

Ich denke, die folgende Syntax könnte in Ordnung sein:

<strong i="7">@export</strong> type=String, hint=MULTILINE

Das Hinzufügen des Kommas zwischen den "Parametern" würde es meiner Meinung nach etwas konsistenter mit der aktuellen Syntax machen:

export (String, MULTILINE) var my_var

die erste Version ist etwas ausführlicher, aber ich denke, es macht es auch expliziter und mit Autovervollständigung sollte es nicht allzu weh tun :)

Weitere Syntaxdiskussionen sollten in Zukunft stattfinden. Insgesamt gefällt mir die Idee.

Anmerkungen sind eine gute Möglichkeit der Konfigurationsinjektion. Aber die Trennung von Konfiguration und Code kann IMO ein saubererer Ansatz sein. Vielleicht ist es hilfreicher, sie als Header-Dateien hinzuzufügen.

Aus dem Kommentar von @bojidar-bg...

Jedenfalls wird noch einige Zeit vergehen, bis Annotationen Realität werden.

Kann jemand erklären, was das "Blockierungsproblem" ist, das diese Implementierung verzögern würde? Ist es nur Vertrautheit mit GDScript / Manpower oder müssen bestimmte Funktionen im Voraus implementiert werden, um Annotationen zu unterstützen?

Nun, seit meinem Kommentar ist schon einige Zeit vergangen, also denke ich, das beweist es schon?

Der Hauptblocker für die Unterstützung von Annotationen wäre, dass sich die Kernentwickler auf die Syntax und Semantik einigen. Danach sollte die Implementierung relativ einfach sein.

Wir müssen dies mit @reduz besprechen, da er es vorzieht, dass Annotationen nur für Metadaten gedacht sind, sie sollten das Skript- oder Editor-Verhalten nicht beeinflussen. Das würde meinen ursprünglichen Vorschlag ziemlich sinnlos machen.

Ich denke immer noch, dass Anmerkungen klar genug sind, insbesondere wenn einzelne Schlüsselwörter ersetzt werden ( onready , master , puppet usw.). Aber wir müssen noch einen Konsens erzielen.

Ich denke, dies wäre eine fantastische Ergänzung zu GDScript, wie beschrieben. Ich denke nicht, dass es auf Metadaten beschränkt sein sollte, es sollte definitiv viele der Schlüsselwörter überholen, die für Variablen verwendet werden, insbesondere export das in einigen Fällen etwas schwer zu lesen sein kann; Die Aufteilung in mehrere Aussagen hilft mir beim Verständnis.

Es kann auch verwendet werden, um das 3 Jahre alte Problem #6204 auf elegante Weise zu lösen:

<strong i="8">@export</strong>
<strong i="9">@export_tooltip</strong> "The name used when displaying this item in the inventory and in shops."
var display_name := ""

Ich stimme auch zu, dass sie mehr als nur Metadaten unterstützen sollten. Es würde eine Menge Logik vereinfachen und die Lesbarkeit imo verbessern.

Ich stimme @willnationsdev zu und würde gerne Signale per Code mit Annotationen verbinden, so etwas kann die Lesbarkeit des Codes wirklich verbessern:

@connect("timeout")
func _on_Timer_timeout():
   ...

@rluders unter der Annahme, dass sich das Skript auf einem Timer Knoten befindet, vielleicht.

@Zylann natürlich. Nur ein einfaches Beispiel. Es könnte die "Ziel"-Parameter unterstützen und für die Selbstverbindung weglassen. Wenn das Skript beispielsweise außerhalb von Timer :

@connect("timeout", $Timer)
func _on_Timer_timeout():
  ...

Ich habe keine Ahnung, wie das implementiert werden könnte, würde aber sehr gerne Anmerkungen in gds sehen, insbesondere für Keywords. Und fürs Protokoll würde ich es vorziehen, wenn '()' anstelle von Semikolons oder Zeilenumbrüchen verwendet wird, um Anmerkungen zu trennen.

Es wäre noch besser, wenn wir unsere eigenen Anmerkungen + vollwertige Anmerkungsprozessoren erstellen könnten.

@Zylann natürlich. Nur ein einfaches Beispiel. Es könnte die "Ziel"-Parameter unterstützen und für die Selbstverbindung weglassen. Wenn das Skript beispielsweise außerhalb von Timer :

@connect("timeout", $Timer)
func _on_Timer_timeout():
  ...

Das könnte irgendwie von einem Plugin unterstützt werden, ich würde es nicht zu einem Kernfeature machen.
Plugins könnten noch leistungsfähiger werden.

Ich kann nur sagen, dass ich froh bin, dass ich Gdscript gelernt habe, bevor diese Dinge implementiert wurden, weil

@export_hint(ENUM)
@export_hint_string("Attack,Defense")
export var my_enum : int = 0

wäre für mich als Anfänger sehr entmutigend und schwer zu analysieren gewesen

@sleepcircle Wir werden versuchen, GDScript in allen Fällen einfach zu halten. Also, kein Grund, hier sarkastisch zu sein: Der von Ihnen zitierte Code war nur ein Vorschlag, nicht _die_ zukünftige Syntax.

Es tut mir leid, ich wollte nicht sarkastisch sein. Ich nahm nur an, da die Mehrheit diese Ergänzungen zu billigen schien, dass sie unvermeidlich waren.

Wollte nur meine 0,02 Dollar als Game Dev Instructor werfen. Warnung: Unnötig langer Kommentar, der nicht viel beiträgt, nur meine Erfahrung aus dem Programmieren von 5 Jahren darüber, wie neue Entwickler das wahrnehmen werden.

Ich denke, es ist wichtig, wenn Sie neue Sprachidiome wie Anmerkungen entwickeln, dass Sie jedes Angebot, das Ihnen möglich ist, huckepack tragen. Zum Beispiel mit connect funktioniert es jetzt gut, da es für einen neuen Entwickler sinnvoll ist, eine Funktion aufzurufen , die Parameter aufnimmt und einige Nebenwirkungen hat.

Wenn @ ausschließlich für Metadaten verwendet wurde, erkennt ein neuer Entwickler jedes Mal, wenn er ein @ sieht, es als Metadaten an, die seine Codelogik nicht beeinflussen. Wenn es sich auf die Logik auswirken sollte, ist es wichtig, dass wir keine neuen Idiome hinzufügen, die manchmal als x und manchmal als y verwendet werden .

Um eine Variable zu ändern, gibt es derzeit var-Präfixe, -Suffixe und -Alternativen. Es gibt einige Dinge, die ich auflisten werde, die nicht unbedingt "variable Modifikatoren" sind, aber neue Entwickler könnten sie so sehen

  • Präfixe: onready , export(...)

    • Diese haben jeweils ein anderes Verhalten. onready beeinflusst das Laden von Laufzeitvariablen, export ist eine Art Editorhinweis/Metadaten. Wenn sie am selben Ort verwendet werden, fühlt es sich an, als ob ihr Verhalten irgendwie verbunden sein sollte, obwohl dies wirklich nicht der Fall ist

  • Alternativen: class_name , extends , signal , enum , const , func

    • Diese alternativen Formate fühlen sich gut an, aber die Unterscheidung zwischen "Enum" und "Const" von beispielsweise Ints oder Strings scheint eine seltsame Wahl zu sein

  • Suffixe: setget

    • Setget in seiner eigenen Kategorie ist in Ordnung, aber es ähnelt export darin, dass es eher ein Zuckerschlüsselwort für Entwickler ist und nicht so sehr eine logische Verschiebung. Aber ich kann sehen, dass hier Leute unterschiedliche Meinungen haben

  • Irgendwo dazwischen: Eingabe von var x : int = 5

    • Diese Eingabe zwischendurch fühlt sich seltsam an, besonders wenn "enum" und "const" alternative Schlüsselwörter zu var sind, um dasselbe darzustellen. Definitiv ein Argument, dass const ähnlich wie setget ist, da es die Erfahrung des Entwicklers mehr als ein Werkzeug für die Spiellogik selbst modifiziert.

Schauen wir uns nun das Hinzufügen von Anmerkungen an.

Anmerkungen wären ein brandneues Konzept/Idiom , das neuen Entwicklern beigebracht werden müsste. Im Idealfall sollten neue Entwickler in der Lage sein, sich auf den neuesten Stand zu bringen und die Dinge so wenig wie möglich zu kennen, damit sie neue Idiome organisch aufnehmen können, wenn sie für sie nützlich sind. Stellen Sie es sich wie einen Tech-Baum vor.

  • (Stufe 1) Sie können ein Spiel erstellen, das nur func, var und einige grundlegende Programmierkonzepte wie Funktionsaufrufe, Bedingungen und Schleifen kennt
  • (Stufe 2) Dann gehen sie weiter, um nützliche Zucker / Funktionen zu lernen, wie Signale, const, enum
  • (Stufe 3) Sie lernen Abkürzungen, wie setget, onready
  • (Tier 3.1) Sie lernen Zucker nur für Entwickler, der ihr Spiel nicht verändert, aber ihren Prozess ändert, mit Dingen wie Exporten, Editorbeschreibungen, Tools und Tippen
  • (Tier 4) Reine Dokumentation und Projektstruktur

Ich glaube, dass Tier 3-4 die Hauptziele für Anmerkungen sind. Es gibt zwei Elevator Pitches, die ich meinen Studenten für die beiden verschiedenen Implementierungen geben würde:

  • Reine Metadaten: "Um Sie bei Ihrer Dokumentation und Zusammenarbeit zu unterstützen, erfahren Sie mehr über Anmerkungen, um Ihren Skripten Metadaten hinzuzufügen. Sie sind leistungsfähiger als nur die Verwendung von Kommentaren."
  • Dev-Shorthands/Zucker: "Wenn Sie Ihren Code reduzieren oder besser lesbar machen möchten, sehen Sie sich die Anmerkungen an. Sie ermöglichen es Ihnen, Variablen und Funktionen zu beschreiben und gleichzeitig einige Editor-Tools und Shortcuts bereitzustellen."

Ich habe einer Reihe von Entwicklern Godot beigebracht, und ich denke, das Erstellen von Anmerkungen ist mindestens eine Option auf Stufe 3 und höchstens auf Stufe 4. Ich möchte ihnen lieber kein @ Symbol zeigen, bis sie es bereits sind Erstellung ganzer, einigermaßen komplexer Spiele und möchten ihren Prozess verbessern .

Das bedeutet, dass meine Meinung bei uns landet, dass wir Annotationen ausschließlich für Dev-Shorthands verwenden, die für die Spielfunktionalität nicht wichtig sind / alternative Implementierungen haben oder nur für die Dokumentation, da es leicht ist, den Leuten zu sagen, dass "Annotationen lernen, wenn Sie größere Projekte erstellen, die Dokumentation benötigen".

Konkrete Punkte aus dem Thread:

  • Sie sollten für Exporte in Ordnung sein, da Exporte für kein Spiel entscheidend sind
  • Onready ist zu Beginn eine praktische Abkürzung, aber nicht notwendig, da neue Entwickler mit _ready und die Aussicht auf verschachtelte Anmerkungen bedeutet, dass onready viel seltener geschrieben werden muss
  • setget ist schon so eine seltsame Syntax und bereits ein eigenes Idiom als einziges Suffix, dass es total drin sein könnte
  • Connect: Wie ich leite, ist es mit dem Funktionsaufruf-Idiom bereits perfekt. Mehrere Möglichkeiten zum Herstellen einer Verbindung könnten den Tutorial-/Beispielcodebereich verschmelzen. Vielleicht wäre es besser, den Leuten zu erlauben, ihre eigenen Anmerkungen zu schreiben, als dies zu standardisieren, damit Entwickler, die an geschlossenen Projekten arbeiten, eine Bibliothek mit Anmerkungen erstellen können, die den öffentlichen Raum nicht unbedingt vermischen.
  • Typen: Typen befinden sich gerade an einer seltsamen Stelle, an der einige Typenmodifikatoren Alternativen sind und einige Typenmodifikatoren dazwischen liegen. Vielleicht funktioniert es, sie als Anmerkungen zu haben: @type(const int) @type(enum) , was sie alle als entwicklerorientierter Zucker vereinen würde

Auch hier kein großer Beitrag, aber ein Denkanstoß, wenn man darüber nachdenkt, welche Funktionalität unter Anmerkungen abgedeckt werden sollte. Ich denke, sie sind eine großartige Idee, aber unklar, wo sie genau hinpassen. Sorry für die Länge, ich bin immer ein bisschen zu ausführlich.

Ich mag das nicht.
Ich möchte nicht für jedes Feld, jede Eigenschaft und jede Methode eine Reihe von Anmerkungen haben

Ich hätte lieber mehr Keywords

Wenn die Leute viele Keywords nicht mögen, können wir einige davon entfernen

export MyClass : Node2D # export replaces class_name, : replaces extends 

signal mySignal #signal is kept

group(MyHeader, "res://icon.png" )
export var my_property : Array(int) setget _set_my_property, _get_my_property # : replaces export type

var test = 0 # no need for onready. variables declared outside of _ready automatically try to be onready vars

#others are kept

Ich stimme dem ursprünglichen Vorschlag voll und ganz zu.

Ich bin mit den obigen Kommentaren nicht einverstanden, aber die Vorteile überwiegen bei weitem die Nachteile.

@Shadowblitz16 Viele dieser Vorschläge sind aus folgenden Gründen für die Leute hier verwirrend ...

export MyClass : Node2D # export replaces class_name, : replaces extends

export , class_name , : und extends konfigurieren jeweils 4 völlig separate Datenpunkte und Systeme. Sie können sie nicht einfach umschalten, ohne andere Dinge unwiederbringlich zu beeinflussen.

  • export konfiguriert das generierte PropertyInfo-Objekt, das an den Inspector gesendet wird, um die Editor-GUI zu erstellen.
  • class_name registriert das Skript als globale Klasse im ScriptServer. Es hat technisch nichts mit dem Typensystem zu tun. Es ist nur insofern Teil der "statischen Typisierung" von GDScript, als es zufällig eine globale Instanz des Skripts zur Analysezeit und nicht zur Laufzeit erstellt.
  • : wird für optionale Typhinweise verwendet. Wenn Sie die Leute nicht davon überzeugen, GDScript immer statisch typisiert zu machen und/oder eine alternative Typhinweissyntax vorzuschlagen, gibt es keine Möglichkeit, das Doppelpunkt-Token wiederzuverwenden.
  • extends wird für die geerbte Klasse verwendet (wie Sie wissen). Dies ist eine ziemlich gängige Syntax in anderen Sprachen, und alle Dokumentationen und Tutorials folgen bereits dieser Methode. Es wird keinen starken Anreiz geben, davon abzuweichen und aus rein kosmetischen Gründen mehr Arbeit zu schaffen.
group(MyHeader, "res://icon.png")

Mir ist nicht klar, was das bewirken soll. Ich meine, es scheint, als würde der Knoten der Gruppe "MyHeader" hinzugefügt (was Sinn machen könnte), aber wofür ist das Symbol? Gruppen sind keine Symbole zugeordnet.

export var my_property : Array(int) setget _set_my_property, _get_my_property # : replaces export type

Wie bereits erwähnt, betreffen diese Dinge alle verschiedene Systeme, nicht dasselbe System. Darüber hinaus kann es vorkommen, dass der Typ eines Werts oder seine Initialisierung flexibel sein soll. In dynamischem GDScript können Sie beispielsweise Folgendes tun:

onready export(NodePath) var the_node = get_node(the_node)
var test = 0 # no need for onready. variables declared outside of _ready automatically try to be onready vars

Die Initialisierung von Daten vor der Bereitschaftsmeldung wäre nicht sinnvoll. Skripte sind der Object-Klasse zugeordnet, nicht der Node-Klasse. Skripteigenschaften werden während der Konstruktion initialisiert. Das ändert sich auch nicht, wenn Sie zum Konstruktor der Node-Klasse gelangen. Die _ready() Benachrichtigung erfolgt viel später nach der Instanziierung. Wenn das Standard-Timing der Variableninitialisierung zwischen Objekten und Knoten unterschiedlich ist, wäre das extrem verwirrend und würde zu viel unvorhersehbarem Verhalten für diejenigen führen, die Godot lernen und verwenden.


Ich möchte Ihre Vorschläge nicht abschießen, sondern nur erklären, warum die Leute die Begründung für diese vorgeschlagenen Änderungen nicht sehen.

@willnationsdev ist in Ordnung, ich verstehe
Was ist mit Anmerkungen und zusätzlichen Schlüsselwörtern?
Auf diese Weise können Benutzer Anmerkungen verwenden, wenn sie möchten, und Schlüsselwörter, wenn sie nicht Dutzende von Anmerkungen pro Feld haben möchten

Bearbeiten: Beachten Sie C# als Attribute, mit denen Sie sie so kombinieren können.
[Attribute1(), Attribute2()]
Obwohl dies zwar helfen könnte, die Zeilenanzahl zu reduzieren, ist es immer noch ein bisschen hässlich

@Shadowblitz16 Wir würden es vorziehen, wenn möglich nur eine offensichtliche Möglichkeit zu haben, Dinge zu tun. Zwei unterschiedliche Syntaxen zu haben, würde diesem Ziel zuwiderlaufen.

@Calinou Ich denke, gdscript sollte so belassen werden, wie es ist, wenn die Leute keine Kompromisse eingehen können.
1 - es unterbricht die Abwärtskompatibilität unnötig
2 - es erstellt größere Dateien und weniger lesbaren Code
3 - es zwingt die Leute, zu einem neuen System zu wechseln, an das sie nicht gewöhnt sind.
4 - es zwingt die Leute, ein System zu verwenden, das sie vielleicht nicht wollen

1 - es unterbricht die Abwärtskompatibilität unnötig
2 - es erstellt größere Dateien und weniger lesbaren Code
3 - es zwingt die Leute, zu einem neuen System zu wechseln, an das sie nicht gewöhnt sind.
4 - es zwingt die Leute, ein System zu verwenden, das sie vielleicht nicht wollen

Ehrlich gesagt sind das ziemlich schlechte Argumente. 3 dieser 4 Punkte sind bei jeder großen Änderung in einer API inhärent, und der erste von ihnen könnte umgangen werden, indem man noch eine Weile die Kompatibilität mit dem älteren schlüsselwortbasierten System aufrechterhält (wahrscheinlich mit einer Veraltungswarnung).

_Edit: Wir könnten auch ein automatisches Konvertierungstool anbieten, denke ich._

Bei Punkt 2 sind sich zwar alle darin einig, dass Anmerkungen zu Dateien mit mehr Zeilen führen können, aber die meisten Leute hier sind anderer Meinung, dass dadurch weniger lesbarer Code erzeugt wird.

@groud dies verwendet Anmerkungen für unnötige Dinge
1 - Warum müssen wir etwas abschaffen, das funktioniert?
2 - es ist weniger lesbar, wenn Sie 5 Zeilen nach unten scrollen müssen, um ein Feld zu sehen

  • export ist im Grunde ein öffentliches Schlüsselwort für den Editor
  • onready ist im Grunde eine var-Deklaration, bevor das Skript ausgeführt wird

beide eignen sich nicht als Anmerkungen

Member-Definitionen sind das einzige, wofür ich das wirklich gut finden kann, und sie müssten zusammenklappbar sein, in diesem Fall sind sie es nicht.

@groud dies verwendet Anmerkungen für unnötige Dinge

In diesem Thread wurden viele Anwendungsfälle vorgestellt. Ob Dokumentation, Introspektion, komplexere Plugins... es gibt unzählige Anwendungsfälle für Annotationen, die nicht mit Schlüsselwörtern abgedeckt werden können.

1 - Warum müssen wir etwas abschaffen, das funktioniert?

Es gibt viele Gründe, so etwas zu tun. Jedes Feature muss möglicherweise weiterentwickelt werden, um eine sauberere API, mehr Flexibilität usw. zu ermöglichen. Und sobald eine neue Version weit verbreitet ist, ist es besser, die Kompatibilität mit der vorherigen Version nach Möglichkeit zu entfernen, da dies definitiv Wartungskosten verursacht.

2 - es ist weniger lesbar, wenn Sie 5 Zeilen nach unten scrollen müssen, um ein Feld zu sehen

Kein Grund zu übertreiben. Das Ziel der Diskussion eines solchen Vorschlags besteht darin, eine Syntax zu ermöglichen, die intelligent genug ist, um solche Probleme zu vermeiden. IMHO, die Exporthinweise könnten als Argumente in die Exportannotationen integriert werden (vorausgesetzt, wir könnten ein benanntes Argumentsystem haben, denke ich). In solchen Situationen könnte das System sogar noch weniger Platz beanspruchen als zuvor.

Wir könnten uns auch vorstellen, die Anmerkungen auf den gleichen Zeilen wie das Feld zu haben. Ich denke nicht, dass dies zu Problemen führen kann.

export ist im Grunde ein öffentliches Schlüsselwort für den Editor
onready ist im Grunde eine var-Deklaration, bevor das Skript ausgeführt wird
beide eignen sich nicht als Anmerkungen

Nun, Sie haben wahrscheinlich vorgefasste Meinungen darüber, wozu Anmerkungen dienen. Ich denke, diese Anwendungsfälle passen perfekt zu einem Anmerkungssystem (und es sieht so aus, als ob das viele Leute tun). Aber ich denke, jede Situation sollte von Fall zu Fall besprochen werden.

Ich finde das Argument "Linien" nicht besonders gut. Auch wenn die Annotationen nicht direkt mehrere Anweisungen pro Zeile (oder ein "Präfix"-Formular) zulassen, können Sie immer noch ; als Trennzeichen verwenden.

<strong i="7">@onready</strong> var my_sprite = $Sprite
@onready; var my_sprite = $Sprite


@export_hint_string("Attack,Defense")
@export_hint(ENUM) export var my_enum : int = 0

@export_hint_string("Attack,Defense")
@export_hint(ENUM); export var my_enum : int = 0


<strong i="8">@export_hint_string</strong> "Attack,Defense";
<strong i="9">@export_hint</strong> ENUM export var my_enum : int = 0

<strong i="10">@export_hint_string</strong> "Attack,Defense"
<strong i="11">@export_hint</strong> ENUM; export var my_enum : int = 0


<strong i="12">@export</strong> type=String hint=MULTILINE; var my_text = ""

# more options

@export(type = String, hint = MULTILINE) var my_text = ""
@export(type = String, hint = MULTILINE); var my_text = ""

@export(String, hint = MULTILINE) var my_text = ""

# I personally prefer this one (positional and named args supported, default/optional args too)
@export(String, MULTILINE) var my_text = ""
@export(String, hint = MULTILINE) var my_text = ""
@export(type = String, hint = MULTILINE) var my_text = ""
@export(int, ENUM, "Attack,Defense") var my_enum:= 0

Bearbeiten: Oh, ich war zu langsam, @groud hat das

das ist die Meinung deiner Jungs.
Ich persönlich finde das @ hässlich

BEARBEITEN:
Wie würde also die Deklaration von Mitgliedern funktionieren?
das wäre schrecklich

<strong i="10">@description</strong> "Adds two numbers and returns the result."
<strong i="11">@parameter</strong> name=num1 type=float description="The first number"
<strong i="12">@parameter</strong> name=num2 type=float description="The second number"
<strong i="13">@returns</strong> type=float description="num1 and num2 added together"
func add(num1, num2):
    return num1 + num2

es sei denn, es konnte vom Anfang von @description bis zum Anfang von func

Ich glaube, Anmerkungen sind nicht dazu gedacht, Typen zu ersetzen (wie Ihr Beispiel es zu tun scheint). Wenn Sie keine Dokumentationsanmerkungen wünschen, werden Sie nicht gezwungen, diese zu verwenden:

func add(num1: float, num2: float) -> float: return num1 + num2

Diese Verwirrung rührt wahrscheinlich von der weniger als idealen Situation mit Exporthinweisen her, in denen Sie meines Wissens keine echten Typen verwenden können (und das Problem, keine generischen Typen zu haben, die überraschenderweise Exporthinweise für einige Typen wie ein Array unterstützen).

Ich persönlich finde das @ hässlich
Wie würde also die Deklaration von Mitgliedern funktionieren?
das wäre schrecklich

In anderen Sprachen dient dieser Zweck normalerweise Kommentaren, nicht Anmerkungen und ist normalerweise gleichwertig oder ausführlicher als das, was vorgeschlagen wurde. In einer C-Sprachfamilie (den beliebtesten Sprachen) ist @ für Annotationen ziemlich häufig (zB Java, JavaScript, TypeScript, Scala und von dem, was ich gelesen habe auch Python).

TypeScript (ich glaube, die Typen in den Dokumenten sind nicht erforderlich und Tools können tatsächliche Typen verwenden):

/** Adds two numbers and returns the result.
 * <strong i="16">@param</strong> num1 {float} The first number
 * <strong i="17">@param</strong> num2 {float} The second number
 * <strong i="18">@return</strong> {float} num1 and num2 added together
  **/
const add = (num1: number, num2: number): number => num1 + num2;

funkähnlicher Geschmack:

@description("Adds two numbers and returns the result.")
@parameter(num1, "The first number", type=float)
@parameter(num2, "The second number", type=float)
@returns("num1 and num2 added together", type=float)
func add(num1: float, num2: float) -> float:
    return num1 + num2

ohne doppelte Typen:

@description("Adds two numbers and returns the result.")
@parameter(num1, "The first number")
@parameter(num2, "The second number")
@returns("num1 and num2 added together")
func add(num1: float, num2: float) -> float:
    return num1 + num2

parenloser Geschmack:

<strong i="28">@description</strong> "Adds two numbers and returns the result."
<strong i="29">@parameter</strong> num1 "The first number"
<strong i="30">@parameter</strong> num2 "The second number"
<strong i="31">@returns</strong> "num1 and num2 added together"
func add(num1: float, num2: float) -> float:
    return num1 + num2

Diese Syntax gefällt mir am besten für Doc-Kommentare. Ich bin immer noch nicht davon überzeugt, Annotationen für Dokumentationszwecke zu verwenden, da ich für Nicht-Doc-Annotationen eine funkähnliche Syntax bevorzugen würde.

Ich habe Annotationsnamen aus dem vorherigen Beispiel verwendet, @parameter könnte einfach @param wie in anderen Sprachen, @description könnte @desc , @descr oder @func .

In GodoDoc verwende ich Syntax basierend auf TypeScript (TypeDoc, das selbst auf JSDoc und Javadoc basiert) und meiner Meinung nach scheint es recht gut zu funktionieren:

## Same as [[bool_]], but `on_false`/`on_true` are functions.
## Only selected function will be called and its return value will be returned from `bool_lazy`.
## <strong i="44">@typeparam</strong> T {any} Return type
## <strong i="45">@param</strong> cond {bool} Condition
## <strong i="46">@param</strong> on_false {FuncLike<T>} Function to call and return its result when `cond` is `false`
## <strong i="47">@param</strong> on_true {FuncLike<T>} Function to call and return its result when `cond` is `true`
## <strong i="48">@return</strong> {T}
func bool_lazy_(cond: bool, on_false, on_true): return GGI.bool_lazy_(cond, on_false, on_true)
var bool_lazy = funcref(self, "bool_lazy_")

es sei denn, es konnte vom Anfang von @description bis zum Anfang von func zusammengeklappt werden

Ja, generell wären das Falten und Optionen für das Standardfalten eine nette Ergänzung zum Editor (das Falten basiert auf einem Blocktyp, zB könnte man in den Einstellungen aktivieren, dass innere Klassen standardmäßig reduziert werden).

Ich mag die Möglichkeit, eine Anmerkung voran oder darüber zu setzen, dafür ist @annotation(a, b) nett, mit Klammern optional, wenn keine Parameter angegeben sind. Die Möglichkeit, vorne zu setzen, ermöglicht die gleiche Schreibgeschwindigkeit wie das heutige Schlüsselwort, da export und onready bei Eigenschaften sehr verbreitet sind.

In Bezug auf die Verwendung mag ich jedoch auch keine Dokumentation. Ich bin es gewohnt, dass sich Anmerkungen auf das Programm auswirken (auch wenn sie indirekt sind), während die Dokumentation ihre Menge für die kommentarartige Verwendung oft verdreifacht, dann überall auftaucht und genauso hervorgehoben wird wie funktionale Anmerkungen ... es ist für so etwas nicht geeignet das allgegenwärtig. Grundsätzlich mag ich die gleiche Verwendung von Annotationen wie in C#, was dazu führt, dass weit weniger Annotationen über Member geschrieben werden müssen (sie sind normalerweise ziemlich selten, nicht jeder muss 5 Zeilen schreiben, wie einige Beispiele gezeigt haben). . Wenn das Argument darin besteht, dass Godot keine API zum Angeben von Skriptdokumenten hat, ist dies das Problem, das nicht allein mit Anmerkungen IMO gelöst werden kann. Zumindest denke ich, dass man das optional verwenden könnte, aber ich möchte nicht gezwungen werden, dies auf diese Weise zu tun, was ich für eine vollständige Dokumentation unpraktisch finde. (Außerdem sind Skripte nicht nur GDScript, und der Randfall der Verwendung von _get_property_list macht dies noch umständlicher)

Ich glaube, ich stimme dir voll und ganz zu, Zylann. Ich persönlich würde eine solche Syntax für den Export (oder sofort) wie Schlüsselwörter zulassen:

# No parenthesis when there are no parameters
<strong i="6">@export</strong> var myvar
# With parenthesis for parameters
@export(ENUM, "Up,Down,Left,Right") var myvar2
# Being able to write the annoation on the line before
@export(ENUM, "Up,Down,Left,Right") 
var myvar2

In Bezug auf den Dokumentationsteil würde ich die Syntax noch weiter vereinfachen (am Beispiel von @mnn ):

<strong i="11">@description</strong> "Adds two numbers and returns the result."
<strong i="12">@parameter</strong> "The first number" # No need to name the args if they are ordered
<strong i="13">@parameter</strong> "The second number"
<strong i="14">@returns</strong> "num1 and num2 added together"
func add(num1: float, num2: float) -> float:
    return num1 + num2

Ich stimme jedoch zu, dass es zwingend erforderlich ist , ein anderes System zu entwickeln, damit die Dokumentation an anderer Stelle geschrieben werden kann. In einer json-, XML- oder rst-Datei würde ich sagen. Die In-Code-Dokumentation passt nicht zu jedem Projekt, und ich stimme zu, dass das Hinzufügen vieler Anmerkungen nur für die Dokumentation ärgerlich sein kann und in einigen Fällen das Lesen des Codes erschweren kann.

Verlinkung nach Relevanz: Godotengine/godot-proposals#177

Ziemlich spät zur Party, aber als Entwickler, der sich bei der Entwicklung von Plugins stark auf Metadaten und Reflexion verlässt, würde ich es wirklich gerne sehen, wenn Anmerkungen in Godot ein Thema werden.

Obwohl ich denke, dass es einige Dinge schöner macht (wie den Export und die Onready-Sachen), wäre mein Hauptargument für benutzerdefinierte Plugins, die Anmerkungen in vollem Umfang nutzen können.

In Bezug onready Schlüsselwort

Ich denke, man kann mit Sicherheit sagen, dass die meisten Leute onready , um Knotenreferenzen frühzeitig zu initialisieren. Abgesehen davon, dass dies auf lange Sicht möglicherweise nicht ohne Probleme machbar ist, denn wenn Sie einige Szenen inszenieren, die von _ready abhängig sind, können Sie auf ein Problem mit der Referenzierung von null :

func explode():
    var bomb = preload("res://explosion.tscn").instance()
    # Oops, forgot to `add_child(bomb)` earlier
    bomb.fuse.wait_time = 5.0 # ERROR: fuse is `null`
    add_child(bomb)
    # ... because `fuse` is a $Timer node 
    # which is only initialized once added to the scene tree.

Natürlich müssen Sie die instanzierte Szene add_child() fuse , aber was ist, wenn andere Knoten/Objekte die genaue Sicherung kennen müssen, bevor die Szene zum Szenenbaum hinzugefügt wird? ?

Nach einiger Zeit habe ich eine Lösung wie in https://github.com/godotengine/godot/issues/33620#issuecomment -559999681 beschrieben gefunden. Wie Sie dort vielleicht bemerken, ist onready nur NOTIFICATION_READY , während ich eigentlich NOTIFICATION_INSTANCED brauchte und meine Referenzen noch früher initialisieren sollte. Das einzige Problem ist, dass es kein oninstanced Schlüsselwort gibt, und ich denke, Sie können herausfinden, wozu ich führe. 🙂

Ich denke also, es wäre schön, das Schlüsselwort onready tatsächlich als Anmerkung neu zu erstellen und gleichzeitig einige andere Eckfälle (wie meine, wie immer!) mit @oninstanced Funktionalität zu unterstützen, ohne die Skriptsprache aufzublähen , sowie Unterstützung für andere Benachrichtigungen im Zusammenhang mit der Initialisierung ( _init , _enter_tree usw.).

Verwandter Vorschlag: Godotengine/godot-proposals#260.

Angebot mit genaueren Details geöffnet :

Wird durch den obigen Vorschlag ersetzt.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen