Comments (4)
I'm just personally a big fan of strong typing in typescript, and it offers better intellisense/tooling, such as having a type error if you pass arguments that don't correspond to the connected signal. I can look into it and offer a PR and better proof of concept
i.e.
this.get_tree().connect("network_peer_connected", (id: string, otherArg: number) => {}, "other");
that will be a type error because the id argument should be a number, and a string was passed to the otherArg when a number is required.
from ecmascript.
another place that stronger inference would generate useful tooling: although I would need to research if it's even possible.
function rpc_id<T extends {} = {}, MethodKey extends key of T, Method = T[]>(id: number, method: MethodKey, ...args: Parameters<Method>): any;
from ecmascript.
In godot signal just a string constant.
That seems a lot of work to do but gains no difference in JavaScript.
from ecmascript.
This is an interesting and useful suggestion. I was able to implement such a thing for C# using godot4-like signal declaration. For now, I am on the way to implementing this for our project (and it goes much much simpler). There is a code snippet of how this can work in typescript:
// This part should be defined somewhere in the ECMAScript
// The implementation of `emit` and `connect` is omitted to keep things simple
// In real Life each signal instance should keep owenr_id and name (which is set by
// ECMAscript when object instantiating) and bypass connection to singleton proxy Object
// ProxyObject well receive all Godot signals and additional argument bypassed
// by Signal instance - `callback_id` and then calls exact function.
// Godot signal are generated as properties which create instances of Signal
// on demand.
type VarArgs = readonly unknown[];
type Action<T extends VarArgs> = (...args: T) => void;
class Signal<T extends VarArgs> implements PromiseLike<T> {
object_id: Number = 0
name: String = ""
// showcase
callbacks:Action<T>[] = []
public emit(...args: T) {
// something from real world:
// godot.instance_from_id(this.instance_id).emit(this.name, ...args)
// just for showcase
for (const cb of this.callbacks) {
cb(...args)
}
}
public connect(cb: Action<T>) {
// real world:
// let obj = godot.instance_from_id(this.instance_id)
// let callback_id = Proxy.get_instance().register_callback(cb)
// obj.connect(this.name, Proxy.get_instance(), "handle_signal", [callback_id])
// just for showcase
this.callbacks.push(cb);
}
// this is required for awaiting directly for signals
public then<TResult1 = T>(onfulfilled?: ((value: T) => (PromiseLike<TResult1> | TResult1)) | undefined | null): PromiseLike<TResult1> {
return new Promise<TResult1>( (resolve, reject) => {
this.connect((...args: T) => {
if (typeof onfulfilled === 'function') {
resolve(onfulfilled(args))
} else {
// exception?
reject("Don't know how to complete without onfulfilled");
}
})
})
}
}
// the rest part is the usage example
class Obj /* extends godot.Object */ {
// @godot.typedsignal - for registering signal nad providing name and owner_id (or maybe generating property)
pressed: Signal<[]> = new Signal();
input: Signal<[name: String]> = new Signal();
selected: Signal<[name: String, age: Number]> = new Signal();
public async ready() {
console.log("in ready")
this.input.connect(this.handle_input) // <= everything typed as excpected
this.pressed.connect(() => console.log("pressed"))
this.input.connect((name) => console.log("input", name))
this.selected.connect((name, age) => console.log("selected", name, age))
// faking signals for showcase
setTimeout(() => this.pressed.emit(), 100)
setTimeout(() => this.input.emit("jhj"), 200);
setTimeout(() => this.selected.emit("vasia", 21), 300);
console.log("before handle")
await this.handle()
console.log("after handle")
}
public handle_input(name: String) {
console.log("Handling input with handle_input method", name)
}
public async handle(a: String = "" ) {
console.log("in handle")
await this.pressed
console.log("after pressed")
let [key] = await this.input; // key is str
console.log("after input", key)
let [name, age] = await this.selected; // name is str, age is num
console.log("after selected", name, age)
}
}
let n = new Obj()
n.ready()
/* Output:
[LOG]: "in ready"
[LOG]: "before handle"
[LOG]: "in handle"
[LOG]: "pressed"
[LOG]: "after pressed"
[LOG]: "Handling input with handle_input method", "jhj"
[LOG]: "input", "jhj"
[LOG]: "after input", "jhj"
[LOG]: "selected", "vasia", 21
[LOG]: "after selected", "vasia", 21
[LOG]: "after handle"
*/
This approach has some memory overhead but adding a lot of impact and stability. It is also fully compatible
with Godot API, e.g. I am able to emit a signal from the engine using old good emit_signal
and so on.
There is Playground Link
from ecmascript.
Related Issues (20)
- CommonJS Module Support HOT 4
- Steps needs to run wasm HOT 1
- [Suggestion] Documentation and getting started tutorial HOT 8
- dev is ok , when i build get error below HOT 1
- Refactor repo branches to enable good publish process HOT 9
- Close issues that refer to Godot Engine 3 but don't exist in Godot Engine 4 HOT 1
- [4.1-v0.0.17] Signal arguments makes it crash HOT 4
- Get started page 404 HOT 2
- Configuring esbuild for bundling classes issue
- Missing template / examples for pre-release HOT 2
- Can I add this to an existing godot install? HOT 1
- .d.ts file has errors HOT 6
- Condition "!is_inside_tree()" is true. HOT 2
- Master build does not build with Godot HOT 2
- Unicode parsing error: Invalid unicode codepoint (fffd), cannot represent as ASCII/Latin-1 HOT 1
- Global pollution HOT 2
- Creating an object in js lost all built-in function links
- [BUMP] GodotJS addon: CSS integration
- 4.2+ support
- Is it dead? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ecmascript.