Godot: Anotaciones en GDScript

Creado en 21 jul. 2018  ·  45Comentarios  ·  Fuente: godotengine/godot

Hace alrededor de un año hubo un RP que agregó anotaciones para GDScript (# 9469). Fue rechazado principalmente porque no había un uso directo para él (no hay datos en el árbol de análisis, solo las herramientas de terceros lo utilizarían).

Esta propuesta es para agregar algún uso a las anotaciones de una manera que haga que GDScript sea más extensible sin introducir más palabras clave.

¿Para qué se pueden utilizar las anotaciones?

  • export sugerencias. Ahora mismo usa una sintaxis personalizada para cada tipo. Con anotaciones, podría establecer directamente el uso y la sugerencia para PropertyInfo, haciendo un mejor uso de las nuevas adiciones al Inspector sin tener que piratear una nueva sintaxis en el analizador de GDScript.
    Para ser claros, dejaría la palabra clave export , solo las sugerencias se moverían a las anotaciones. El tipo se puede definir con sugerencias de tipo.
  • Esto incluye categorías para export también (# 4378, # 10303).
  • Reemplace la palabra clave onready con una anotación.
  • Desactivación de determinadas advertencias. # 19993 agrega advertencias con una sintaxis ad-hoc para deshabilitarlas, pero podría usar anotaciones en su lugar.
  • setget (es una sintaxis extraña cuando solo quieres el captador).
  • Palabras clave de RPC ( master , slave , sync , remote ).
  • Nuevas instrucciones de preprocesador, como hacer que una función se compile solo en el editor (con tool ) o solo en modo de depuración (relacionado con # 12837).
  • Discusión eventual de la nueva sintaxis (como señal para emitir cuando la variable cambia: # 6491).
  • Quizás la posibilidad de agregar "decoradores" personalizados.

Ventajas
Cada vez que se agrega una nueva palabra clave, se requieren cambios en el analizador y el tokenizador de GDScript para manejarla. En particular, el análisis sintáctico export es bastante complicado y está mezclado con otros análisis relacionados con la clase.

Con las anotaciones, se haría menos trabajo para agregar un atributo en particular (como export, setget, onready), en su lugar, solo necesitaría verificar qué anotaciones están presentes.

Desventajas
Agregar compatibilidad con anotaciones requeriría más cambios en el analizador que cualquier palabra clave por sí sola. También puede influir en las personas para que sugieran nuevas funciones como "solo una anotación".

Sintaxis
No tengo ninguna preferencia particular por la sintaxis, pero imagino algo como los decoradores de Python. Sin embargo, puede resultar confuso para los usuarios de Python, ya que las anotaciones no son lo mismo que los decoradores.

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

Para pasar argumentos, podría funcionar como funciones:

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

Quizás sin paréntesis:

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

O tal vez use parámetros con nombre (y evite la palabra clave):

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

O algo mas.

Anotaciones personalizadas
Las anotaciones desconocidas simplemente se ignorarán (tal vez con una advertencia). Por lo tanto, las herramientas de terceros pueden analizar las anotaciones para ofrecer otras capacidades, como la generación de documentación.

También es posible agregar una API de introspección: get_method_annotations() , get_property_annotations() o algo así. De esta manera, los complementos que, digamos, esperan scripts pueden usar anotaciones para decidir qué método llamar en lugar de usar un nombre codificado.

archived discussion feature proposal gdscript

Comentario más útil

¿Por qué se modifica tanto la sintaxis de gdscript? originalmente fue diseñado para ser simple, fácil de aprender e intuitivo. Me temo que con todas estas nuevas adiciones (gds escritos, anotaciones) se volverá muy confuso para los nuevos desarrolladores.

La mayoría (si no todos) los cambios de sintaxis de GDScript son compatibles con el código antiguo. El objetivo principal es aumentar la productividad de los desarrolladores que utilizan GDScript, por ejemplo:

  • match declaraciones
  • onready variables _ready .
  • Typed GDScript permite a los desarrolladores descansar finalmente sabiendo que no se producirán errores de tipo incorrecto, y les permite beneficiarse de una mejor función de autocompletado al mismo tiempo. Es opcional, por lo que los recién llegados no necesitan aprenderlo para su primer juego.

Siento que podría haber una posible desconexión entre los desarrolladores de juegos reales y los contribuyentes.

Esta es una comunidad abierta. Los desarrolladores de juegos pueden venir y expresar su opinión, tal como lo hizo usted. En cualquier caso, pasará bastante tiempo antes de que las anotaciones se conviertan en realidad.

[...] sólo temo que los gds puedan alejarse cada vez más de su simplicidad, eso es todo. ya es más que suficiente ...

Si ya fuera lo suficientemente bueno, no recibiríamos solicitudes de funciones para él.

Además, tener 3 líneas para una palabra clave de exportación es muy engorroso, en comparación con especificar todo en una sola línea. por ejemplo: onready var my_sprite = $ Sprite es mucho más limpio

La sintaxis aún no está finalizada. Es muy probable que no reemplace las palabras clave onready y export inmediatamente.

Todos 45 comentarios

Solo para entender correctamente las anotaciones personalizadas, podría tener algo como esto:

<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

Y podría llamar a una función, digamos get_annotations("add") , ¿que devolvería estas anotaciones? ¿Incluso si Godot no reconoce estas anotaciones como una palabra clave / anotación incorporada?

@ LikeLakers2 sí, esa es la esencia.

Me gusta, no sé por la implementación detrás, pero en el código GDscript se vería mucho más limpio de lo que parece ahora. Especialmente para el ejemplo de setget.

Esto es muy útil, pero debería permitir declaraciones de una sola línea para facilitar la lectura. Por ejemplo,
<strong i="6">@onready</strong> var a = $A debería permitir

Algo como

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

Sería útil aplicar la misma anotación a varias declaraciones.

Además, se pueden usar dos puntos para indicar dónde termina la anotación y dónde comienzan las declaraciones afectadas, para ser coherente con el resto de GDScript.

Si las anotaciones se pueden analizar con un comienzo y un final claros, entonces no se necesitan puntos y comas y luego se pueden colocar en la misma línea si es necesario (si usan '()' por ejemplo, o no tienen argumentos)

Sin embargo, no creo que vnen tuviera la intención de eliminar las palabras clave de acceso directo antiguas.

También puede ayudar tener un mango de resaltador.

Llega tarde a la fiesta aquí, pero ¿está muy interesado en cómo esto podría proporcionar categorías para exportar vars y crear divisiones de script de herramienta / depuración?

Poniendo tentativamente en la hoja de ruta 3.2, realmente me gustaría ver esto implementado más temprano que tarde para proporcionar mejoras de usabilidad al editor.

#### opinión impopular entrante:

¿Por qué se modifica tanto la sintaxis de gdscript? originalmente fue diseñado para ser simple, fácil de aprender e intuitivo. Me temo que con todas estas nuevas adiciones (gds escritos, anotaciones) se volverá muy confuso para los nuevos desarrolladores. por ejemplo, si una persona nueva en Godot viera un tutorial y viera el código que está en la publicación de LikeLakers2, me imagino que eso les haría explotar la cabeza. en todo caso, tendrían que hacer un montón de preguntas al respecto / cómo funciona, etc.

Entiendo totalmente el amor de todos por gds y cómo los contribuyentes quieren mejorarlo, etc. Solo siento que podría haber una posible desconexión entre los desarrolladores de juegos reales y los contribuidores (sin decir que los contribuyentes no son desarrolladores de juegos, solo digo que algunos funciones no son realmente necesarias). no todo el mundo necesita utilizar estas funciones. Solo temo que los gds puedan alejarse cada vez más de su simplicidad, eso es todo. ya es más que suficiente ...

Además, tener 3 líneas para una palabra clave de exportación es muy engorroso, en comparación con especificar todo en una sola línea. por ejemplo: onready var my_sprite = $Sprite es mucho más limpio (para mí de todos modos)

y con respecto al punto # 4, esto se puede hacer en el editor AFAIK. Además, en mi opinión, tener anotaciones en todo el lugar en el código para 'deshabilitar ciertas advertencias' podría conducir a un código muy desordenado

¿Por qué se modifica tanto la sintaxis de gdscript? originalmente fue diseñado para ser simple, fácil de aprender e intuitivo. Me temo que con todas estas nuevas adiciones (gds escritos, anotaciones) se volverá muy confuso para los nuevos desarrolladores.

La mayoría (si no todos) los cambios de sintaxis de GDScript son compatibles con el código antiguo. El objetivo principal es aumentar la productividad de los desarrolladores que utilizan GDScript, por ejemplo:

  • match declaraciones
  • onready variables _ready .
  • Typed GDScript permite a los desarrolladores descansar finalmente sabiendo que no se producirán errores de tipo incorrecto, y les permite beneficiarse de una mejor función de autocompletado al mismo tiempo. Es opcional, por lo que los recién llegados no necesitan aprenderlo para su primer juego.

Siento que podría haber una posible desconexión entre los desarrolladores de juegos reales y los contribuyentes.

Esta es una comunidad abierta. Los desarrolladores de juegos pueden venir y expresar su opinión, tal como lo hizo usted. En cualquier caso, pasará bastante tiempo antes de que las anotaciones se conviertan en realidad.

[...] sólo temo que los gds puedan alejarse cada vez más de su simplicidad, eso es todo. ya es más que suficiente ...

Si ya fuera lo suficientemente bueno, no recibiríamos solicitudes de funciones para él.

Además, tener 3 líneas para una palabra clave de exportación es muy engorroso, en comparación con especificar todo en una sola línea. por ejemplo: onready var my_sprite = $ Sprite es mucho más limpio

La sintaxis aún no está finalizada. Es muy probable que no reemplace las palabras clave onready y export inmediatamente.

Me gusta mucho la idea, muy parecidos a los atributos en C #.

Las anotaciones de clases y señales también podrían ser interesantes.

Los complementos de inspector que entran en acción automáticamente, ya sea que una propiedad, método o clase tenga una anotación personalizada en particular, sería muy sencillo.
En cuanto a la sintaxis, preferiría algo que también podría escribirse opcionalmente en una sola línea, pero no es tan crucial.

¿Cómo podría ser el proceso de definición de anotaciones personalizadas? Preferiría que no se definieran libremente cada vez en el código, sino que fueran creados por el usuario con una definición unívoca, al igual que las clases.

Creo que esto necesita más investigación, creo que sería genial agregarlo al lenguaje (como sintaxis opcional, etc., etc.) para no confundir a los novatos completos que intentan ingresar.

Creo que la siguiente sintaxis podría estar bien para mirar:

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

agregar la coma entre los "parámetros" creo que lo haría un poco más consistente con la sintaxis actual así:

export (String, MULTILINE) var my_var

la primera versión es un poco más detallada, pero creo que también la hace más explícita y con el autocompletado no debería doler demasiado :)

Deberían producirse más discusiones sobre la sintaxis en el futuro. En general me gusta la idea.

Las anotaciones son una buena forma de inyección de configuración. Pero separar la configuración y el código puede ser un enfoque más limpio, en mi opinión. Puede agregarlos como archivos de encabezado para ser más útiles.

Del comentario de @ bojidar-bg ...

En cualquier caso, pasará bastante tiempo antes de que las anotaciones se conviertan en realidad.

¿Alguien puede explicar cuál es el problema del "bloqueo" que retrasaría esta implementación? ¿Es solo familiaridad con GDScript / manpower, o hay características específicas que deben implementarse con anticipación para admitir anotaciones?

Bueno, ha pasado bastante tiempo desde mi comentario, ¿así que creo que eso ya lo prueba?

El principal bloqueador para el soporte de anotaciones sería lograr que los desarrolladores principales estuvieran de acuerdo con la sintaxis y la semántica. Posteriormente, la implementación debería ser relativamente fácil.

Necesitamos discutir esto con @reduz, ya que él prefiere que las anotaciones solo estén destinadas a los metadatos, no deberían afectar el comportamiento del script o del editor. Esto haría que mi propuesta original fuera bastante inútil.

Sigo pensando que las anotaciones son lo suficientemente claras, especialmente cuando se reemplazan palabras clave individuales ( onready , master , puppet , etc.). Pero aún necesitamos llegar a un consenso.

Creo que esta sería una adición fantástica a GDScript como se describe. No creo que deba limitarse a los metadatos, definitivamente debería superar muchas de las palabras clave que se utilizan para las variables, especialmente export que pueden resultar un poco difíciles de leer en algunos casos; dividirlo en varias declaraciones ayuda a la comprensión, creo.

También se puede usar para resolver ese problema de hace 3 años # 6204 de una manera elegante:

<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 := ""

También estoy de acuerdo en que deberían admitir más que solo metadatos. Simplificaría mucha lógica y mejoraría la legibilidad en mi opinión.

Estoy de acuerdo con @willnationsdev y me encantaría conectar señales por código usando anotaciones, algo como esto realmente puede mejorar la legibilidad del código:

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

@rluders asumiendo que el script está en un nodo Timer , tal vez.

@Zylann por supuesto. Solo un simple ejemplo. Podría admitir los parámetros "objetivo" y omitirlos para la autoconexión. Por ejemplo, si el script se ejecuta fuera de Timer :

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

No tengo idea de cómo se podría implementar esto, pero realmente me encantaría ver anotaciones en gds, especialmente para palabras clave. Y para que conste, preferiría que se usara '()' en lugar de punto y coma o líneas nuevas para separar anotaciones.

Sería incluso mejor si pudiéramos crear nuestras propias anotaciones + procesadores de anotaciones completos.

@Zylann por supuesto. Solo un simple ejemplo. Podría admitir los parámetros "objetivo" y omitirlos para la autoconexión. Por ejemplo, si el script se ejecuta fuera de Timer :

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

Eso podría ser compatible con un complemento de alguna manera, no lo convertiría en una característica principal.
Los complementos podrían volverse aún más poderosos.

Todo lo que puedo decir es que me alegro de haber aprendido gdscript antes de que se implementaran estas cosas porque

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

hubiera sido muy desalentador y difícil de analizar para mí, como principiante

@sleepcircle Intentaremos que GDScript sea simple en todos los casos. Entonces, no hay necesidad de ser sarcástico aquí: el código que citó fue solo una propuesta, no _la_ sintaxis futura.

Lo siento, no estaba tratando de ser sarcástico. Solo estaba asumiendo, dado que la mayoría parecía aprobar estas adiciones, que eran inevitables.

Solo quería tirar mis $ 0.02 como instructor de desarrollo de juegos. Advertencia: comentario innecesariamente largo que no aporta mucho, solo mi experiencia de enseñar programación durante 5 años sobre cómo los nuevos desarrolladores percibirán esto.

Creo que es importante a la hora de crear nuevos modismos lingüísticos, como anotaciones, que aproveche todas las posibilidades que pueda. Por ejemplo, con connect , ahora funciona bien, ya que tiene sentido para un nuevo desarrollador que llame a una función que toma parámetros y tiene algunos efectos secundarios.

Si @ se usó exclusivamente para metadatos, entonces cada vez que un nuevo desarrollador ve un @ lo reconocen como metadatos que no afectan la lógica de su código. Si afectara la lógica, es importante que no agreguemos nuevos modismos que a veces se usan como x y otras veces como y .

En este momento, para modificar una variable, existen prefijos, sufijos y alternativas de var. Enumeraré algunas cosas que no son necesariamente "modificadores de variables", pero es posible que los nuevos desarrolladores las vean de esta manera.

  • Prefijos: onready , export(...)

    • Cada uno tiene un tipo de comportamiento diferente. onready afecta la carga de variables en tiempo de ejecución, export es una especie de sugerencia / metadatos del editor. Usarlos en el mismo lugar parece que su comportamiento debería estar conectado de alguna manera, cuando en realidad no lo es

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

    • Estos formatos alternativos se sienten bien, pero diferenciar "enum" y "const" de, digamos, ints o strings parece una elección extraña

  • Sufijos: setget

    • Establecer su propia categoría está bien, pero es similar a export en que es más una palabra clave de azúcar para los desarrolladores y no tanto un cambio lógico. Puedo ver gente que tiene opiniones diferentes aquí, aunque

  • En algún lugar intermedio: escribiendo var x : int = 5

    • Esta escritura intermedia se siente extraña, especialmente cuando "enum" y "const" son palabras clave alternativas a var para representar lo mismo. Definitivamente, un argumento de que const es similar a setget en el sentido de que modifica la experiencia del desarrollador más que una herramienta para la lógica del juego en sí.

Así que ahora veamos la adición de anotaciones.

Las anotaciones serían un concepto / modismo completamente nuevo que debería enseñarse a los nuevos desarrolladores. Idealmente, los nuevos desarrolladores deberían poder ponerse al día y hacer las cosas sabiendo la menor cantidad posible de modismos para que puedan aprender orgánicamente nuevos modismos a medida que se vuelven útiles para ellos. Piense en ello como un árbol tecnológico.

  • (Nivel 1) Pueden crear un juego conociendo solo func, var y algunos conceptos básicos de programación como llamadas a funciones, condicionales y bucles.
  • (Nivel 2) Luego pasan a aprender azúcar / funcionalidad útil, como señales, const, enum
  • (Nivel 3) Aprenden atajos, como setget, onready
  • (Nivel 3.1) Aprenden azúcar solo para desarrolladores, que no cambiará su juego, pero cambiará su proceso , con cosas como exportaciones, descripciones del editor, herramientas y mecanografía.
  • (Nivel 4) Estructura del proyecto y documentación pura

Siento que los niveles 3-4 son los principales objetivos de las anotaciones. Hay dos presentaciones de ascensor que les daría a mis estudiantes para las dos implementaciones diferentes:

  • Puramente metadatos: "Para ayudar con su documentación y colaboración, obtenga información sobre las anotaciones para agregar algunos metadatos a sus scripts. Son más poderosos que simplemente usar comentarios".
  • Dev shorthands / sugar: "Si está buscando reducir su código o hacerlo más legible, eche un vistazo a las anotaciones. Le permiten describir variables y funciones al mismo tiempo que proporcionan algunas herramientas de edición y atajos".

He enseñado a varios desarrolladores sobre Godot y creo que hacer anotaciones es al menos una opción de Nivel 3 y, como máximo, el Nivel 4. Preferiría no tener que mostrarles un símbolo @ hasta que ya estén creando juegos completos y razonablemente complejos y están buscando mejorar su proceso .

Esto significa que mi opinión aterriza en que usamos anotaciones exclusivamente para desarrolladores abreviados que no son importantes para la funcionalidad del juego / tienen implementaciones alternativas o simplemente para documentación, ya que es fácil decirle a la gente "aprende anotaciones una vez que estás construyendo proyectos más grandes que necesitan documentación".

Puntos específicos del hilo:

  • Deberían estar bien para las exportaciones, ya que las exportaciones no son críticas para ningún juego.
  • Onready es un atajo útil desde el principio, pero no es necesario, ya que los nuevos desarrolladores pueden comenzar iniciando en _ready y la perspectiva de anotaciones anidadas significa escribir onready muchas menos veces
  • setget ya es una sintaxis tan extraña, y ya tiene su propio idioma como el único sufijo, que podría estar totalmente ahí
  • Conectar: ​​como dirijo con, ya es perfecto con el modismo de llamada de función. Tener varias formas de conectarse podría combinar el espacio de código de ejemplo / tutorial. Quizás permitir que las personas escriban sus propias anotaciones sería mejor que estandarizar esto, de modo que los desarrolladores que trabajan en proyectos cerrados puedan construir una biblioteca de anotaciones que no necesariamente combine el espacio público.
  • Tipos: los tipos se encuentran en un lugar extraño en este momento, donde algunos modificadores de tipo son alternativas y algunos modificadores de tipo están en el medio. Tal vez tenerlos como anotaciones funcione: @type(const int) @type(enum) , lo que los unificaría a todos como un azúcar orientado al desarrollador

Nuevamente, no es una gran contribución, pero es motivo de reflexión cuando se piensa en qué funcionalidad debe cubrirse con las anotaciones. Creo que son una gran idea, pero no está claro exactamente dónde encajan. Perdón por la extensión, siempre soy un poco demasiado detallado.

No me gusta esto.
No quiero tener un montón de anotaciones para cada campo, propiedad y método.

Prefiero tener más palabras clave

Si a las personas no les gustan muchas palabras clave, podemos eliminar algunas de ellas.

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

Estoy completamente de acuerdo con la propuesta original.

No estoy en desacuerdo con los comentarios anteriores, pero los pros superan con creces a los contras.

@ Shadowblitz16 Muchas de estas sugerencias son confusas para la gente aquí, por las siguientes razones ...

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

export , class_name , : y extends configuran cada uno 4 puntos de datos y sistemas completamente separados. No puede simplemente cambiarlos sin afectar otras cosas de manera irrecuperable.

  • export configura el objeto PropertyInfo generado que se envía al Inspector para construir la GUI del editor.
  • class_name registra el script como una clase global en ScriptServer. Técnicamente, no tiene nada que ver con el sistema de tipos. Es parte de la "escritura estática" de GDScript solo en la medida en que simplemente crea una instancia global del script en tiempo de análisis en lugar de tiempo de ejecución.
  • : se usa para sugerencias de tipo opcionales . A menos que convenza a las personas para que hagan que GDScript se escriba estáticamente en todo momento y / o proponga una sintaxis de sugerencia de tipo alternativa, no hay forma de reutilizar el token de dos puntos.
  • extends se usa para la clase heredada (como sabe). Esta es una sintaxis bastante común en otros lenguajes, y toda la documentación y los tutoriales ya siguen este método. No habrá un gran incentivo para alejarse de esto y crear más trabajo por una razón puramente cosmética.
group(MyHeader, "res://icon.png")

No me queda claro qué haría esto. Quiero decir, parece que el nodo se agregará al grupo "MyHeader" (lo que podría tener sentido), pero ¿para qué sirve el ícono? Los grupos no tienen iconos asociados.

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

Como se ha dicho anteriormente, todas estas cosas afectan a diferentes sistemas, no al mismo sistema. Además, puede haber ocasiones en las que desee que el tipo de valor o su inicialización sea flexible. Por ejemplo, en GDScript dinámico, puede hacer algo como esto:

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

Inicializar datos antes de la notificación lista no tendría sentido. Los scripts están asociados con la clase Object, no con la clase Node. Las propiedades del script se inicializan durante la construcción. Eso no cambia incluso cuando llegas al constructor de la clase Node. La notificación _ready() ocurre mucho más tarde después de la instanciación. Hacer que el tiempo predeterminado de inicialización de la variable sea diferente entre Objetos y Nodos sería extremadamente confuso y conduciría a muchos comportamientos impredecibles para aquellos que aprenden y usan Godot.


No pretendo rechazar sus sugerencias, sino simplemente explicar por qué la gente no ve la justificación de estos cambios sugeridos.

@willnationsdev está bien, lo entiendo
¿Qué hay de hacer anotaciones y palabras clave adicionales?
De esta manera, los usuarios pueden usar las anotaciones si lo desean y las palabras clave si no quieren tener docenas de anotaciones por campo.

Editar: tenga en cuenta C # como atributos que le permiten combinarlos así ...
[Attribute1(), Attribute2()]
Sin embargo, aunque esto podría ayudar a reducir el número de líneas, todavía es un poco feo.

@ Shadowblitz16 Preferiríamos tener solo una forma obvia de hacer las cosas cuando sea posible. Tener dos sintaxis diferentes sería contrario a ese objetivo.

@Calinou Creo que gdscript debería dejarse como está si la gente no puede comprometerse.
1 - rompe la compatibilidad con versiones anteriores innecesariamente
2: crea archivos más grandes y código menos legible
3 - obliga a las personas a cambiar a un nuevo sistema al que no están acostumbrados.
4 - obliga a las personas a usar un sistema que tal vez no quieran

1 - rompe la compatibilidad con versiones anteriores innecesariamente
2: crea archivos más grandes y código menos legible
3 - obliga a las personas a cambiar a un nuevo sistema al que no están acostumbrados.
4 - obliga a las personas a usar un sistema que tal vez no quieran

Honestamente, esos son argumentos bastante malos. 3 de esos 4 puntos es inherente a cualquier gran cambio en una API, y el primero de ellos podría solucionarse manteniendo la compatibilidad con el sistema antiguo basado en palabras clave durante un tiempo (probablemente con una advertencia de obsolescencia).

_Editar: también podríamos proporcionar una herramienta de conversión automática, supongo ._

Para el punto 2, aunque creo que todos estarán de acuerdo en el hecho de que las anotaciones pueden conducir a archivos con más líneas, la mayoría de la gente aquí no está de acuerdo con el hecho de que crea un código menos legible.

@groud esto está usando anotaciones para cosas innecesarias
1 - ¿por qué tenemos que desaprobar algo que funciona?
2 - es menos legible si tiene que desplazarse hacia abajo 5 líneas para ver un campo

  • exportar es básicamente una palabra clave pública para el editor
  • onready es básicamente una declaración var antes de que se ejecute el script

ambos no son adecuados para ser anotaciones

las definiciones de miembros son lo único para lo que realmente puedo ver que esto es bueno y tendrían que ser plegables en este caso no lo son.

@groud esto está usando anotaciones para cosas innecesarias

En este hilo se han presentado muchos casos de uso. Ya sea para documentación, introspección, complementos más complejos ... hay un montón de casos de uso para anotaciones que no se pueden cubrir con palabras clave.

1 - ¿por qué tenemos que desaprobar algo que funciona?

Hay muchas razones para hacer algo así. Es posible que cualquier característica deba evolucionar para permitir una API más limpia, más flexibilidad, etc. Y una vez que una nueva versión se usa ampliamente, es mejor eliminar la compatibilidad con la versión anterior cuando sea posible, ya que definitivamente tiene un costo de mantenimiento.

2 - es menos legible si tiene que desplazarse hacia abajo 5 líneas para ver un campo

No es necesario exagerar. El objetivo de discutir tal propuesta es permitir una sintaxis lo suficientemente inteligente para evitar tales problemas. En mi humilde opinión, las sugerencias de exportación podrían integrarse como argumentos a las anotaciones de exportación (siempre que podamos tener un sistema de argumentos con nombre, supongo). En tales situaciones, el sistema podría ocupar incluso menos espacio que antes.

Además, también podríamos imaginar tener las anotaciones en las mismas líneas que el campo. No creo que esto pueda causar problemas.

exportar es básicamente una palabra clave pública para el editor
onready es básicamente una declaración var antes de que se ejecute el script
ambos no son adecuados para ser anotaciones

Bueno, es probable que tengas ideas preconcebidas sobre para qué sirven las anotaciones. Creo que esos casos de uso se ajustan perfectamente a un sistema de anotaciones (y parece que mucha gente lo hace). Pero de hecho, supongo que cada situación debería discutirse caso por caso.

No veo que el argumento de las "líneas" sea particularmente bueno. Incluso si las anotaciones no permiten directamente varias declaraciones por línea (o un formulario de "prefijo"), aún puede usar ; como delimitador.

<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

Editar: Oh, fui demasiado lento, @groud ya abordó el argumento de las líneas. Bueno, al menos esos pocos ejemplos de código agregaron algo a este hilo.

esa es la opinión de tus chicos.
Yo personalmente creo que la @ es fea

EDITAR:
entonces, ¿cómo funcionaría la declaración de miembro?
hacerlo sería horrible

<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

a menos que pudiera colapsarse desde el comienzo de @description hasta el comienzo de func

Creo que las anotaciones no están destinadas a reemplazar tipos (como parece hacer su ejemplo). Si no desea anotaciones de documentación, no se verá obligado a usarlas:

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

Esta confusión probablemente se deba a la situación menos que ideal con sugerencias de exportación donde, hasta donde yo sé, no se pueden usar tipos reales (y el problema de no tener tipos genéricos que sorprendentemente exportan el soporte de sugerencias para algunos tipos como una matriz).

Yo personalmente creo que la @ es fea
entonces, ¿cómo funcionaría la declaración de miembro?
hacerlo sería horrible

En otros idiomas este propósito suele servir para comentarios, no anotaciones y suelen estar a la par o más prolijos de lo que se sugirió. En una familia de lenguajes C (lenguajes más populares) el @ es bastante común para las anotaciones (por ejemplo, Java, JavaScript, TypeScript, Scala y también de lo que leo Python).

TypeScript (creo que los tipos en los documentos no son necesarios y las herramientas pueden usar tipos reales):

/** 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;

sabor a func:

@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

sin tipos duplicados:

@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

sabor sin parentesco:

<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

Me gusta más esta sintaxis para los comentarios de documentos. Todavía no estoy convencido sobre el uso de anotaciones con fines de documentación, ya que para las anotaciones que no son de documento preferiría una sintaxis similar a la de func.

Usé nombres de anotaciones del ejemplo anterior, @parameter podría ser simplemente @param como en otros idiomas, @description podría ser @desc , @descr o @func .

En GodoDoc estoy usando una sintaxis basada en TypeScript (TypeDoc que a su vez se basa en JSDoc y Javadoc) y, en mi opinión, parece funcionar bastante bien:

## 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_")

a menos que pudiera colapsarse desde el comienzo de @description hasta el comienzo de func

Sí, generalmente el plegado y una opción para el plegado predeterminado sería una buena adición al editor (plegado basado en un tipo de bloque, por ejemplo, podría habilitar en la configuración que las clases internas se colapsarían de forma predeterminada).

Me gusta la capacidad de poner una anotación al frente o arriba, para esto el @annotation(a, b) es bueno, con corchetes opcionales si no se dan parámetros. Ser capaz de poner al frente permite la misma velocidad de escritura que la palabra clave actual, dado que export y onready son muy comunes en las propiedades.

Sin embargo, en términos de uso, tampoco me gusta la documentación. Estoy acostumbrado a que las anotaciones tengan un efecto en el programa (incluso si son indirectas), mientras que la documentación a menudo triplicaría su cantidad para uso similar a un comentario, luego aparecería en todas partes y se resaltaría igual que las anotaciones funcionales ... no es adecuada para algo así de omnipresente. Básicamente, me gusta el mismo uso de anotaciones que se puede encontrar en C #, lo que lleva a que se tengan que escribir muchas menos anotaciones encima de los miembros (normalmente son bastante raras, no todo el mundo tiene que escribir 5 líneas como se muestra en algunos ejemplos) . Si el argumento es que Godot no tiene una API para especificar documentos de script, entonces ese es el problema, que no debe resolverse únicamente con anotaciones, en mi opinión. Al menos, supongo que uno podría usar eso opcionalmente, pero no me gustaría que me obligaran a hacerlo de esta manera, lo que me parece inconveniente para la documentación a gran escala. (además, los scripts no son solo GDScript, y el caso extremo de usar _get_property_list hace que esto sea aún más incómodo)

Creo que estoy totalmente de acuerdo contigo, Zylann. Personalmente, permitiría dicha sintaxis para la exportación (o ya) como palabras clave:

# 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

Con respecto a la parte de documentación, simplificaría aún más la sintaxis (tomando el ejemplo de @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

Sin embargo, estoy de acuerdo en que es obligatorio desarrollar otro sistema para que la documentación se pueda escribir en otro lugar. En un json, XML o primer archivo, diría. La documentación en código no se adapta a todos los proyectos, y estoy de acuerdo en que agregar muchas anotaciones solo para la documentación puede ser molesto y puede hacer que el código sea más difícil de leer en algunos casos.

Vinculación de relevancia: godotengine / godot-proposiciones # 177

Bastante tarde para la fiesta, pero como desarrollador que depende en gran medida de los metadatos y la reflexión para desarrollar complementos, me encantaría ver que las anotaciones se conviertan en algo en godot.

Si bien creo que hace que algunas cosas sean más hermosas (como la exportación y las cosas ya listas), mi argumento principal sería para los complementos personalizados que pueden utilizar las anotaciones al máximo.

Con respecto a la palabra clave onready y sus limitaciones.

Creo que es seguro decir que la mayoría de la gente usa onready para inicializar las referencias de nodo desde el principio. Excepto que podría no ser factible sin problemas a largo plazo, porque cuando instalas algunas escenas que son dependientes de _ready , puedes tropezar con el problema de hacer referencia a 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.

Por supuesto, necesita add_child() la escena instanciada antes de intentar configurar el fuse , pero ¿qué pasa si otros nodos / objetos necesitan conocer el fusible exacto antes de que la escena se agregue al árbol de escenas? ?

Después de un tiempo, encontré una solución como se describe en https://github.com/godotengine/godot/issues/33620#issuecomment -559999681. Como puede notar allí, onready es solo NOTIFICATION_READY , mientras que lo que realmente necesitaba era NOTIFICATION_INSTANCED e inicializar mis referencias incluso antes. El único problema es que no hay una palabra clave oninstanced , y supongo que puede averiguar a qué me estoy dirigiendo. 🙂

Entonces, supongo que sería bueno rehacer la palabra clave onready como una anotación de hecho, mientras que también admite algunos otros casos de esquina (como el mío, ¡como siempre!) Con la funcionalidad @oninstanced sin inflar el lenguaje de scripting. , además de agregar soporte para otras notificaciones relacionadas con la inicialización ( _init , _enter_tree , etc.).

Propuesta relacionada: godotengine / godot-proposiciones # 260.

Abrió una propuesta con detalles más específicos: https://github.com/godotengine/godot-proposals/issues/828

Reemplazada por la propuesta anterior.

¿Fue útil esta página
0 / 5 - 0 calificaciones