-
-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wiki: Add detail regarding passing objects via signals #57
Comments
Indeed, it's very easy to make such mistakes when writing this kind of code, and unfortunately, most of these errors can't be detected by the ts compiler. Thanks for the suggestions. I'll improve the docs about it. |
Should add that I'm very happy to edit the wiki myself, requires some repo perms to edit though I think. Here's some suggested content to copy paste in: Passing Arguments via SignalsWhen emitting signals, only Godot-native objects ( Incorrect Example: this.some_signal.emit({ key: "value" }); // ❌ Raw JS object Correct Example: import { GDictionary } from "godot";
const data = new GDictionary();
data.set("key", "value");
this.some_signal.emit(data); // ✅ Godot dictionary If raw JavaScript objects must be passed, consider converting them into |
To others reading this, here's a (hacky, llm generated) converter from/to TS objects to Godot objects (not strongly tested, just a quick workaround to get things going) import { GArray, GDictionary } from "godot";
/**
* Recursively converts JavaScript objects and arrays to Godot-compatible GDictionary and GArray types
* @param data Any JavaScript value to convert to a Godot-compatible type
* @returns The Godot-compatible representation of the input data
*/
export function toGD(data: any) {
// Handle null/undefined
if (data === null || data === undefined) {
return null;
}
// Handle primitive types (pass through)
if (typeof data !== 'object') {
return data;
}
// Handle arrays
if (Array.isArray(data)) {
const gArray = new GArray();
for (const item of data) {
gArray.push_back(toGD(item));
}
return gArray;
}
// Handle objects
if (data instanceof GArray || data instanceof GDictionary) {
// Already a Godot type, return as is
return data;
}
// Convert object to GDictionary
const gDict = new GDictionary();
for (const key in data) {
if (Object.prototype.hasOwnProperty.call(data, key)) {
gDict.set_keyed(key, toGD(data[key]));
}
}
return gDict;
}
/**
* Recursively converts Godot GDictionary and GArray types to JavaScript objects and arrays
* @param data Godot data structure to convert to a JavaScript equivalent
* @returns The JavaScript representation of the input Godot data
*/
export function fromGD<T = any>(data: any): T {
// Handle null/undefined
if (data === null || data === undefined) {
return null as T;
}
// Handle GArray
if (data instanceof GArray) {
const jsArray: any[] = [];
for (let i = 0; i < data.size(); i++) {
jsArray.push(fromGD(data.get_indexed(i)));
}
return jsArray as T;
}
// Handle GDictionary
if (data instanceof GDictionary) {
const jsObject: Record<string | number, any> = {};
const keys = data.keys();
for (let i = 0; i < keys.size(); i++) {
const key = keys.get_indexed(i);
jsObject[key] = fromGD(data.get_keyed(key));
}
return jsObject as T;
}
// Handle primitive types and anything else (pass through)
return data as T;
} |
Would be good to add a note explaining that raw ts/js objects cannot be passed via signals, only godot objects i.e.
GArray
,GDictionary
(and primitives) can be passed as valid arguments. Might seem intuitive but turned out to be a gotcha for me when porting a c#/godot_mono project across, hopefully might be able to help other peopleThe text was updated successfully, but these errors were encountered: