Skip to content

Commit e341989

Browse files
docs: GDictionary.create() / GArray.create() (#10)
1 parent b8c0959 commit e341989

File tree

2 files changed

+109
-8
lines changed

2 files changed

+109
-8
lines changed

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

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,113 @@ And, avoid coding property assignments like this: `node.position.x = 0;`, althou
6969

7070
**It's not an error in javascript (which is more DANGEROUS)**, the actually modifed value is just a copy of `node.position`.
7171

72+
## Godot Data Structures
73+
74+
Godot has its own types that represent arrays and dictionaries. Godot engine methods are passed and return these types rather than JavaScript arrays/objects.
75+
76+
GodotJS provides convenience APIs to make working with these data structures easier.
77+
78+
### Creating Godot Arrays
79+
80+
You can convert JavaScript arrays to Godot arrays using `GArray.create`.
81+
82+
```ts
83+
const js_arr = [1, 2, 3];
84+
const godot_arr = GArray.create(js_arr);
85+
```
86+
87+
Importantly, type information is retained i.e. the following will compile:
88+
89+
```ts
90+
const godot_arr = GArray.create([1, 2, 3]);
91+
const a_number: number = godot_arr.get(0);
92+
```
93+
94+
but this will not:
95+
96+
```ts
97+
const godot_arr = GArray.create([1, 2, 3]);
98+
const a_string: string = godot_arr.get(0);
99+
```
100+
101+
`GArray.create` works recursively:
102+
103+
```ts
104+
const godot_arr = GArray.create([["a", "b", "c"], ["x", "y", "z"]]);
105+
const a_string: string = godot_arr.get(0).get(0);
106+
```
107+
108+
### Creating Godot Dictionaries
109+
110+
Similar to arrays, you can create Godot dictionaries from JS objects:
111+
112+
113+
```ts
114+
const godot_dict = GDictionary.create({ foo: "bar" });
115+
```
116+
117+
As with arrays, type information is retained when creating GDictionary.
118+
119+
```ts
120+
const godot_dict = GDictionary.create({ foo: "bar" });
121+
const foo: string = godot_dict.get("foo");
122+
```
123+
124+
### Accessing Godot Data Structures
125+
126+
GodotJS provides a convenience API that allows you to treat `GArray`/`GDictionary` similar to their JavaScript equivalents.
127+
128+
```ts
129+
const godot_arr = GArray.create([1, 2, 3]);
130+
const godot_arr_proxy = godot_arr.proxy();
131+
const a_number: number = godot_arr_proxy[0];
132+
```
133+
134+
Note the use of the indexer rather than needing to call `.get(0)`.
135+
136+
This works equally well for assignment:
137+
138+
```ts
139+
godot_arr_proxy[0] = 42;
140+
```
141+
142+
You can also access arbitrarily nested data too:
143+
144+
```ts
145+
const godot_dict = GDictionary.create({
146+
nested: [
147+
[{ foo: 'bar' }],
148+
[{ foo: 'bar' }],
149+
],
150+
});
151+
const godot_dict_proxy = godot_dict.proxy();
152+
const a_string: string = godot_dict_proxy.nested[0]![0]!.foo;
153+
```
154+
155+
Accessing data this way is particularly useful if you want to pluck out a few values from a large data structure. However, when you access nested data this way JavaScript `Proxy` objects are created on the fly; which can cause overhead with frequent nested access.
156+
157+
If you're performing frequent access, it'll likely be more efficient to convert the data structure to JavaScript objects just the once.
158+
159+
You can use the spread operator to create a JavaScript object from a proxy:
160+
161+
```ts
162+
const godot_arr = GArray.create([
163+
["a", "b", "c"],
164+
["x", "y", "z"],
165+
]);
166+
const js_shallow_arr = [...godot_arr.proxy()];
167+
168+
const godot_dict = GDictionary.create({
169+
nested: [
170+
[{ foo: 'bar' }],
171+
[{ foo: 'bar' }],
172+
],
173+
});
174+
const js_shallow_dict = { ...godot_dict.proxy() };
175+
```
176+
177+
Keep in mind that these are _shallow_ copies i.e. only the top level collection has been converted to a JavaScript object/array. Nested Godot collections will remain (as proxies).
178+
72179
### StringName
73180

74181
`StringName` optimization is completely transparent in javascript. When passing `StringName` parameters, a mapping between `StringName` and `v8::String` will be automatically cached to avoid repeatedly allocation of new `v8::String` objects and Godot `Variant` objects.

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

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,20 +29,14 @@ Incorrect Example:
2929
this.some_signal.emit({ key: "value" }); // ❌ Raw JS object
3030
```
3131

32-
Correct Example:
32+
You can use `GDictionary.create`/`GArray.create` to convert JS objects to their Godot equivalent data structure.
3333

3434
```ts
3535
import { GDictionary } from "godot";
3636

37-
const data = new GDictionary();
38-
data.set("key", "value");
39-
this.some_signal.emit(data); // ✅ Godot dictionary
37+
this.some_signal.emit(GDictionary.create({ key: "value" })); // ✅ Godot dictionary
4038
```
4139

42-
If raw JavaScript objects must be passed, consider converting them into `GDictionary` or `GArray` before emitting them as arguments.
43-
If you use [godot-ts](https://github.com/godotjs/godot-ts) you can use
44-
the functions `toGDictionary` and `fromGDictionary` from `generated/utils.ts`.
45-
4640
## Connect and disconnect to a signal programmatically
4741

4842
```ts

0 commit comments

Comments
 (0)