Skip to content

Commit b8c0959

Browse files
authored
docs: auto-complete and codegen (#9)
1 parent cdbb8c0 commit b8c0959

14 files changed

+149
-51
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Auto-Completion and Codegen
2+
3+
If you use TypeScript just follow the getting-started and install all [preset files](../getting-started.md#install-preset-files).
4+
5+
By default, the codegen is activated, which will generate new `*.d.ts` files based on you project resources.
6+
7+
Example given `ResourceLoader.load()` will autocomplete like this:
8+
9+
![Resource Loader load auto complete](images/codegen/resource-loader.png)
10+
11+
## .gen.d.ts files
12+
13+
Similarly to scenes, each resource has a generated `.gen.d.ts file` in the `/generated/typings/` subdirectory.
14+
15+
For example, a `hmm.tres` file for a custom Resource whose script looks like:
16+
17+
```ts
18+
export default class LineCardLayout extends CardLayout {
19+
```
20+
21+
will have the following `hmm.tres.gen.d.ts` generated:
22+
23+
```ts
24+
import LineCardLayout from "../../../src/layouts/line-card-layout";
25+
declare module "godot" {
26+
interface ResourceTypes {
27+
"res://scenes/example/hmm.tres": LineCardLayout;
28+
}
29+
}
30+
```
31+
32+
## ResourceLoader.load
33+
34+
Now when you write code to load a resource with a string literal, the type is known:
35+
36+
![ResourceLoader load string literal](images/codegen/resource-loader-string.png)
37+
38+
Built-in resource types are also typed as expected:
39+
40+
![ResourceLoader load typed](images/codegen/resource-loader-typed.png)
41+
42+
Unknown/non-literal resources will fall back to being typed as `Resource`, mimicking the old behavior.
43+
44+
## Scenes
45+
46+
We have special case handling for scenes.
47+
48+
![Scene Typed](images/codegen/scene.png)
49+
50+
In the example above, no explicit types are provided, but the instantiated scene is known to be of type `StandardCard`. This works because `PackedScene` is now `PackedScene<T extends Node = Node>` and the generated contents of `standard-card.tscn.gen.d.ts` are as follows:
51+
52+
```ts
53+
import StandardCard from "../../../src/example/standard-card";
54+
declare module "godot" {
55+
interface ResourceTypes {
56+
"res://scenes/example/standard_card.tscn": PackedScene<StandardCard>;
57+
}
58+
}
59+
```
60+
61+
## Settings
62+
63+
As with scene node codegen, resource codegen can be disabled with editor settings:
64+
65+
![Settings Codegen](images/codegen/settings.png)
66+
67+
## Customization
68+
69+
As with scene node codegen, users can customize the generated type for custom `Resource` by exporting a `codegen` function and handling the codegen request of type `CodeGenType.ScriptResourceTypeDescriptor` e.g.
70+
71+
```ts
72+
export const codegen: CodeGenHandler = (rawRequest) => {
73+
const request = rawRequest.proxy();
74+
75+
switch (request.type) {
76+
case CodeGenType.ScriptResourceTypeDescriptor: {
77+
return GDictionary.create<StringLiteralTypeDescriptor>({
78+
type: DescriptorType.StringLiteral,
79+
value: "FooBar",
80+
});
81+
}
82+
}
83+
84+
return undefined;
85+
};
86+
```
87+
88+
which would lead to the contents of `hmm.tres.gen.d.ts` becoming:
89+
90+
```ts
91+
declare module "godot" {
92+
interface ResourceTypes {
93+
"res://scenes/example/hmm.tres": "FooBar";
94+
}
95+
}
96+
```
97+
98+
_**Note:** This is just for illustrative purposes. It's highly unlikely someone will implement a custom `Resource` that is somehow compliant with the string literal type `"FooBar"`!_

docs/documentation/godot-js-scripts/code-in-editor.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,21 @@
44
> **NOTE:** Read [Godot Docs](https://docs.godotengine.org/en/stable/tutorials/plugins/running_code_in_the_editor.html#what-is-tool) for more details about `@tool`.
55
66

7-
If a GodotJS class is annotated with `tool()`, it'll be instantiated in the editor. Call `Engine.is_editor_hint()` in the script to check if it's running in the editor.
7+
If a GodotJS class is annotated with `@Tool()`, it'll be instantiated in the editor.
8+
Call `Engine.is_editor_hint()` in the script to check if it's running in the editor.
89
It's also possible to show warnings on a `Node` on `Scene` panel with `_get_configuration_warnings` defined. Here is a simple example:
910

1011
```ts
1112
import { Engine, PackedStringArray, Sprite2D, Variant } from "godot";
12-
import { export_, tool } from "godot.annotations";
13+
import { Export, Tool } from "godot.annotations";
1314

14-
@tool()
15+
@Tool()
1516
export default class MyEditorSprite extends Sprite2D {
1617

1718
/**
1819
* get/set property for `export` (both must be defined)
1920
*/
20-
@export_(Variant.Type.TYPE_FLOAT)
21+
@Export(Variant.Type.TYPE_FLOAT)
2122
get speed(): number { return this._speed; }
2223
set speed(value: number) {
2324
if (this._speed != value) {
@@ -29,7 +30,7 @@ export default class MyEditorSprite extends Sprite2D {
2930
/**
3031
* plain field for `export`
3132
*/
32-
@export_(Variant.Type.TYPE_INT)
33+
@Export(Variant.Type.TYPE_INT)
3334
unused_int = 0;
3435

3536
private _clockwise = false;
@@ -81,9 +82,9 @@ This is available in Godot by extending `EditorScript` in a script. This provide
8182

8283
```ts
8384
import { EditorScript } from "godot";
84-
import { tool } from "godot.annotations";
85+
import { Tool } from "godot.annotations";
8586

86-
@tool()
87+
@Tool()
8788
export default class MyEditorScript1 extends EditorScript {
8889
_run() {
8990
console.log("my editor script run");

docs/documentation/godot-js-scripts/decorators.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ There are several decorators to help you define properties, signals, and other m
44

55
## Signal annotation
66

7-
You can define signals in your script using the `@signal` annotation:
7+
You can define signals in your script using the `@ExportSignal` annotation:
88

99
```ts
10-
import { Node, Signal0, Callable } from "godot";
11-
import { signal } from "godot.annotations";
10+
import { Node, Signal } from "godot";
11+
import { ExportSignal } from "godot.annotations";
1212

1313
export default class MyJSNode extends Node {
14-
@signal()
15-
declare test!: Signal0;
14+
@ExportSignal()
15+
test!: Signal<(param1: string) => void>;
1616
}
1717
```
1818

@@ -24,9 +24,9 @@ If a GodotJS class is annotated with `tool()`, it'll be instantiated in the edit
2424

2525
```ts
2626
import { Node } from "godot";
27-
import { tool } from "godot.annotations";
27+
import { Tool } from "godot.annotations";
2828

29-
@tool()
29+
@Tool()
3030
export default class MyTool extends Node {
3131
_ready() {
3232
// This code will run in the editor
@@ -43,9 +43,9 @@ An icon can be used as node icon in the editor scene hierarchy with the annotati
4343

4444
```ts
4545
import { Sprite2D } from "godot";
46-
import { icon } from "godot.annotations";
46+
import { Icon } from "godot.annotations";
4747

48-
@icon("res://icon/affiliate.svg")
48+
@Icon("res://icon/affiliate.svg")
4949
export default class MySprite extends Sprite2D {}
5050
```
5151

@@ -57,15 +57,15 @@ In `GodotJS`, class member properties/variables can be exported.
5757
This means their value gets saved along with the resource
5858
(such as the scene) they're attached to.
5959
They will also be available for editing in the property editor.
60-
Exporting is done by using the `@export_` annotation.
60+
Exporting is done by using the `@Export` annotation.
6161

6262
```ts
63-
import { export_ } from "godot.annotations";
63+
import { Export } from "godot.annotations";
6464

6565
export default class Shooter extends Sprite2D {
66-
// type must be explicitly provided as the first parameter of @export_
66+
// type must be explicitly provided as the first parameter of @Export
6767
// cuz static type is actually a phantom in typescript
68-
@export_(Variant.Type.TYPE_FLOAT)
68+
@Export(Variant.Type.TYPE_FLOAT)
6969
speed: number = 0;
7070

7171
// ...
@@ -84,17 +84,17 @@ The retrieval of default value is implemented through `Class Default Object (CDO
8484
### Basic Use
8585

8686
```ts
87-
@export_(Variant.Type.TYPE_STRING)
87+
@Export(Variant.Type.TYPE_STRING)
8888
address: string = "somewhere"; // `:string` can be omitted here
8989

90-
@export_(Variant.Type.TYPE_INT)
90+
@Export(Variant.Type.TYPE_INT)
9191
age: number = 0; // `:number` can be omitted here
9292
```
9393

9494
If there's no default value, `default value` of the give type will be used (`0` in this case).
9595

9696
```ts
97-
@export_(Variant.Type.TYPE_INT)
97+
@Export(Variant.Type.TYPE_INT)
9898
age: number;
9999
```
100100

@@ -105,7 +105,7 @@ Enum value properties can be exported with the built-in support in the property
105105
> **NOTE:** So far, only `int` is supported as enum value.
106106
107107
```ts
108-
@export_enum(MyColor)
108+
@ExportEnum(MyColor)
109109
color: MyColor = MyColor.White;
110110
```
111111

Loading
Loading
Loading
Loading
Loading

docs/documentation/godot-js-scripts/intro.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,8 @@ export default class MyJSNode extends Node {
6666
Annotations are used to define properties, signals, and other metadata for Godot objects.
6767
They are similar to decorators in TypeScript and can be used to enhance the functionality of your scripts.
6868
Check out [decorators](decorators.md) for more information.
69+
70+
## Auto-Completion and Codegen
71+
72+
By default, GodotJS wil auto generate some TypeScript files based on you project.
73+
Check out [auto-completion](auto-completion.md) for more information.

docs/documentation/godot-js-scripts/npm-dependencies.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { dayjs } from "./npm.bundle";
2222

2323
export default class Example extends Node {
2424
_ready(): void {
25-
const label: Label = this.get_node("Label") as Label;
25+
const label: Label = this.get_node("Label");
2626

2727
label.text = dayjs().toString();
2828
}

docs/documentation/godot-js-scripts/signals.md

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,25 @@
33
You can define signals based on the amount of arguments you want to pass:
44

55
```ts
6-
import { Node, Signal0, Signal1, Signal2, Callable } from "godot";
7-
import { signal } from "godot.annotations";
6+
import { Node, Signal } from "godot";
7+
import { ExportSignal } from "godot.annotations";
88

9-
export default class MyJSNode extends Node {
10-
@signal()
11-
declare no_arg!: Signal0;
9+
export default class MyNode extends Node {
10+
@ExportSignal()
11+
declare no_arg!: Signal<() => void>;
1212

13-
@signal()
14-
declare one_arg!: Signal1<number>;
13+
@ExportSignal()
14+
declare one_arg!: Signal<(param1: string) => void>;
1515

16-
@signal()
17-
declare two_args!: Signal2<string, string>;
16+
@ExportSignal()
17+
declare two_args!: Signal<(param1: number, param2: string) => void>;
1818
}
1919
```
2020

21-
> **NOTE:** You must `declare` signal properties.
22-
> This creates an "ambient" declaration, which is a way of telling TypeScript
23-
> that the property exists but not to generate any code to define it.
24-
> Instead `@signal` automatically generates an accessor on your behalf.
25-
> If you omit `declare`, the TypeScript compiler creates an "own property"
26-
> on instances with an `undefined` value, which blocks access to the GodotJS'
27-
> generated accessor method (which exists on the instance's prototype).
28-
2921
## Passing Arguments via Signals
3022

31-
When emitting signals, only Godot-native objects (GArray, GDictionary, and primitives) can be passed as valid arguments. Raw TypeScript/JavaScript objects cannot be used directly.
23+
When emitting signals, only Godot-native objects (GArray, GDictionary, and primitives) can be passed as valid arguments.
24+
Raw TypeScript/JavaScript objects cannot be used directly.
3225

3326
Incorrect Example:
3427

@@ -46,9 +39,9 @@ data.set("key", "value");
4639
this.some_signal.emit(data); // ✅ Godot dictionary
4740
```
4841

49-
If raw JavaScript objects must be passed, consider converting them into ``GDictionary`` or ``GArray`` before emitting them as arguments.
42+
If raw JavaScript objects must be passed, consider converting them into `GDictionary` or `GArray` before emitting them as arguments.
5043
If you use [godot-ts](https://github.com/godotjs/godot-ts) you can use
51-
the functions ``toGDictionary`` and `fromGDictionary` from ``generated/utils.ts``.
44+
the functions `toGDictionary` and `fromGDictionary` from `generated/utils.ts`.
5245

5346
## Connect and disconnect to a signal programmatically
5447

docs/examples/reuse-custom-resources.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ This example shows how to create a custom resource and reuse it with different s
77
We create a new file `character-attributes.ts` and add this code to it:
88

99
```ts title="character-attributes.ts"
10-
import { export_ } from "godot.annotations";
10+
import { Export } from "godot.annotations";
1111
import { Resource, Variant } from "godot";
1212

1313
export default class CharacterAttributes extends Resource {
14-
@export_(Variant.Type.TYPE_INT)
14+
@Export(Variant.Type.TYPE_INT)
1515
health: number = 5;
1616
}
1717
```
@@ -33,14 +33,14 @@ Create a new file `index.ts` and add this code to it:
3333

3434
```ts title="index.ts"
3535
import { Node, Variant } from "godot";
36-
import { export_ } from "godot.annotations";
36+
import { Export } from "godot.annotations";
3737
import CharacterAttributes from "./character-attributes";
3838

3939
export default class ResourceExample extends Node {
40-
@export_(Variant.Type.TYPE_OBJECT)
40+
@Export(Variant.Type.TYPE_OBJECT)
4141
warriorAttributes: CharacterAttributes | undefined = undefined;
4242

43-
@export_(Variant.Type.TYPE_OBJECT)
43+
@Export(Variant.Type.TYPE_OBJECT)
4444
mageAttributes: CharacterAttributes | undefined = undefined;
4545

4646
_ready(): void {

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Supports JavaScript engines:
2222
2323
## Getting started
2424

25-
Read the [getting-started](documentation/getting-started).
25+
Read the [getting-started](documentation/getting-started.md).
2626

2727
## Features
2828

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ nav:
1818
- Cyclic Imports: documentation/godot-js-scripts/cyclic-imports.md
1919
- Bindings: documentation/godot-js-scripts/bindings.md
2020
- Running code in editor: documentation/godot-js-scripts/code-in-editor.md
21+
- Auto-Completion and Codegen: documentation/godot-js-scripts/auto-completion-and-codegen.md
2122
- Utilities:
2223
- REPL: documentation/utilities/repl.md
2324
- SourceMaps: documentation/utilities/source-map.md

0 commit comments

Comments
 (0)