Closed Geequlim closed 1 year ago
This looks awesome!
I was just about to ask for this as it appears to be a huuuuge improvement over duktape and even chakra if you want something small to embed with high ECMA compliance.
Test case for QuickJS to make sure we can use Godot Object type correctly in javascript
(function() {
try {
console.log("---------------------------");
var btn = new godot.Button();
console.log(btn, btn instanceof godot.Object); // <--- Variant toString test should print `[Button:XXX]`
// prototype chian check
console.log(btn instanceof godot.Object, btn instanceof godot.Control, btn instanceof godot.Resource); // true, true, false
(function () { // C++ take references of JS objects
var theme = new godot.Theme();
theme.aaa = 'AAA'; // <-- script properties
// UTF8 character & properties
theme.set_name('资源名');
theme.resource_path = '资源路径';
btn.set_theme(theme); // <-- Add reference count of `theme` object in C++
console.log(theme, theme.resource_name, theme.get_path());
// `o` is Object type should not be auto freed by GC
var o = new godot.Node();
o.ooo = 'OOO'; // <-- script properties
btn.set_meta('obj', o);
console.log(o);
// `res` should be freed by GC as it was not used in C++
var res = new godot.Resource();
console.log(res);
})(); // <--- Avoid `theme` and `o` be freed by the GC
var theme = btn.get_theme();
console.log(theme, theme.aaa); // <--- Get script property to make sure the object is the one we created before
var o = btn.get_meta('obj');
console.log(o, o.ooo);
btn.set_meta('obj', null);
// Object have to be freed manually as GDScript
o.free();
btn.free();
// theme.free() // <--- Throw exception when try to free Reference
console.log("---------------------------");
// constants
console.log(godot.Control.CURSOR_HELP);
// enumerations
console.log(godot.Control.CursorShape.CURSOR_HELP);
console.log(JSON.stringify(godot.Control.CursorShape));
// signal
console.log(JSON.stringify(godot.Control.focus_exited));
console.log("---------------------------")
} catch (error) {
console.log("ERROR:", error);
}
})();
Fork of QuickJS with the necessary changes: https://github.com/koush/quickjs VSCode Extension: https://github.com/koush/vscode-quickjs-debug VSCode Marketplace Link: https://marketplace.visualstudio.com/items?itemName=koush.quickjs-debug
↑ It's time to start the work :)
Bunnymark compare to GDScript 2019-11-17:
2020-01-01
In addition to porting to quickjs, are there any plans to investigate bindings using pluginscript instead of a godot module. It would be nice to have this supported as something that can be downloaded through the asset library instead of having to compile it into godot. Quickjs is rather portable, so distributing the addon would be conceivably small and quick to plug in for projects thinking of exploring the option.
@nhydock No such plan in the near feature.
Hello, I've encountered this error when trying to compile: (on Ubuntu 18.04.3)
modules/libmodules.x11.tools.64.a(quickjs_builtin_binder.x11.tools.64.o): In function 'QuickJSBuiltinBinder::initialize(JSContext*, QuickJSBinder*)':
/home/cupi/Make/godotJS/godot/modules/ECMAScript/quickjs/quickjs_builtin_binder.cpp:160: undefined reference to 'QuickJSBuiltinBinder::bind_builtin_classes_gen()'
@cupiniki comment this line https://github.com/Geequlim/ECMAScript/blob/706d39af38e313170ffdbed6f94ee65ad9ec0cd2/generate_builtin_api.py#L6
@Geequlim Thank you
@nhydock Why not using GDNative/ PluginScript ?
Just an idea something that might be interesting to explore wrt getting as much performance out of this as possible...
A lot of the godot built-in methods are there because for the convenience of GDScript, which is developed entirely within the closed ecosystem of Godot. Javascript has a lot of similar math functions as part of its language, or you can get them as npm modules. Because of the overhead of c interop when calling any godot bindings from javascript and adapting data to javascript data structures, in some cases it can be more performant to use an equivalent function that are plain javascript. This can be especially true if the functions are going to be called frequently, such as using Rand functions for procgen.
It could be interesting to see the performance difference of rebuilding parts of the godot API in equivalent native javascript versus their c function counterparts.
@nhydock I have thought about reducing the allocation by implementing the builtin type in JS. But there is an important problem. Can the performance of the QuickJS vm achieve the expectations? quickjs does not support JIT, and there are many computationally intensive functions in the built-in APIs, which may not achieve the ultimate goal. Doing so may perform well in some simple use case like acquiring members of vector2 such as bunnymark, but not as expected in real projects. So I think the huge workload of maintaining built-in types with JS is not worth it.
a lot of the built-in types such as Vector2 and Basis I wouldn't touch, because those would need to always be converted back regardless since the engine heavily relies on those structs. I was more interested in a lot of the pure math related functions, namely everything that's just convenience methods in https://docs.godotengine.org/en/stable/classes/class_@gdscript.html
Since they're purely computational and for convenience, they may either be redundant to JS or suboptimal to use frequently with their interop overhead.
If someone did want to see if they could optimize their own project by rewriting the same functions directly in javascript there's nothing stopping them from making their own lib instead of calling to godot.
A new benchmark result after opimize performance (In both binding code and script code)
As the result shows in V1DrawTexture
we got more bunnies in JavaScript than GDScript.
Is this completed?
As far as I know, quickjs has been implemented. Please open new issues for bugs and improvements.
I will wait until quickjs is more stable at least the debugger is implemented.Export godot symbols to script
ECMAScriptGCHandler
to improve the binding processgodot.Object
godot.Reference
godot.sin
godot.randi
godot.Vector2
godot.Color
Rect2.end
,Color.r8
Register script classes to godot
godot.register_class
to register classes form JSexport default ClassFunction
syntaxExporting
Optional Plans
Object.connect
,Object.disconnect
andObject.is_connected
await
support for signalsWorker
APIAdd allocator for binding objectECMAScriptGCHandler
More work to improve the performance for container typesArray
Dictionary