-
-
Notifications
You must be signed in to change notification settings - Fork 212
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
Builder API to register classes, functions, properties, signals #4
Comments
68: PR #4/5 Astolfo feature/builtin-quaternion r=Bromeon a=RealAstolfo Co-Authored-By: Thomas ten Cate <[email protected]> Implemented Quaternion to the best of my current ability to resemble godot's, meant to be merged after #67 Co-authored-by: RealAstolfo <[email protected]> Co-authored-by: Jan Haller <[email protected]>
# This is the 1st commit message: Parse gdextension_interface.h declarations using regex # This is the commit message #2: AsUninit trait to convert FFI pointers to their uninitialized versions # This is the commit message godot-rust#3: GodotFfi::from_sys_init() now uses uninitialized pointer types # This is the commit message godot-rust#4: Introduce GDExtensionUninitialized*Ptr, without changing semantics # This is the commit message godot-rust#5: Adjust init code to new get_proc_address mechanism # This is the commit message godot-rust#6: Make `trace` feature available in godot-ffi, fix interface access before initialization # This is the commit message godot-rust#7: Compatibility layer between Godot 4.0 and 4.1 (different GDExtension APIs) # This is the commit message godot-rust#8: Add GdextBuild to access build/runtime metadata # This is the commit message godot-rust#9: Detect 4.0 <-> 4.1 mismatches in both directions + missing `compatibility_minimum = 4.1` # This is the commit message godot-rust#10: Detect legacy/modern version of C header (also without `custom-godot` feature) # This is the commit message godot-rust#11: CI: add jobs that use patched 4.0.x versions # This is the commit message godot-rust#12: Remove several memory leaks by constructing into uninitialized pointers # This is the commit message godot-rust#13: CI: memcheck jobs for both 4.0.3 and nightly # This is the commit message godot-rust#14: Remove ToVariant, FromVariant, and VariantMetadata impls for pointers This commit splits SignatureTuple into two separate traits: PtrcallSignatureTuple and VarcallSignatureTuple. The latter is a child of the former. PtrcallSignatureTuple is used for ptrcall and only demands GodotFuncMarshall of its arguments. VarcallSignatureTuple is used for varcall and additionally demands ToVariant, FromVariant, and VariantMetadata of its arguments, so pointers cannot benefit from the optimizations provided by varcall over ptrcall. # This is the commit message godot-rust#15: Adds FromVariant and ToVariant proc macros # This is the commit message godot-rust#16: godot-core: builtin: reimplement Plane functions/methods # This is the commit message godot-rust#17: impl GodotFfi for Option<T> when T is pointer sized and nullable godot-rust#240 Additionally FromVariant and ToVariant are also implemented for Option<Gd<T>> to satisfy all the requirements for ffi and godot_api. # This is the commit message godot-rust#18: Fix UB in virtual method calls that take objects Fix incorrect incrementing of refcount when calling in to godot Fix refcount not being incremented when we receive a refcounted object in virtual methods # This is the commit message godot-rust#19: fix UB caused by preload weirdness # This is the commit message godot-rust#20: Implements swizzle and converts from/to tuples
While this feature is still far away (definitely not this year), here are already some ideas of how proc-macro APIs could map to the builder API. The philosophy is to keep the mapping somewhat intuitive, reusing names where possible and avoid too much magic. For example, given: #[derive(GodotClass)]
#[class(base=Node2D)]
struct MyClass {
#[base]
base: Base<Node2D>,
#[onready]
late_init: OnReady<PackedInt32Array>,
#[export]
integer: i32,
}
#[godot_api]
impl MyClass {
#[func]
fn regular() -> Gd<Other> {...}
#[func(gd_self)]
fn do_sth(this: Gd<Self>, arg: i32) {...}
}
#[godot_api]
impl INode2D for MyClass {
fn init(base: Base<Node2D>) -> Self {...}
fn ready(&mut self); {...}
fn to_string() -> GString {...}
} With builders and zero proc-macros, it could look something like: struct MyClass {
base: Base<Node2D>,
late_init: OnReady<PackedInt32Array>,
integer: i32,
}
impl MyClass {
fn regular() -> Gd<Other> {...}
fn do_sth(this: Gd<Self>, arg: i32) {...}
}
// NEW: explicit GodotClass
impl GodotClass for MyClass {
// base, memory etc
}
impl INode2D for MyClass {
// NEW:
fn register(b: &mut ClassBuilder<MyClass>) {
// Fields
b.export_var("integer").get(Self::get_integer).set(Self::set_integer);
b.base(Self::get_base); // returns &mut Base
b.onready(Self::get_late_init); // returns &mut OnReady
// Different kinds of methods, e.g. static/instance/Gd<Self>
b.func("regular").method(Self::regular);
b.func("do_sth").method_gd_self(Self::do_sth);
// Special methods (we need to tell which ones are overridden, compiler can't detect it)
b.interface() // requires INode2D bound
.overrides(IMethod::Init | IMethod::Ready | IMethod::ToString);
}
fn init(base: Base<Node2D>) -> Self {...}
fn ready(&mut self); {...}
fn to_string() -> GString {...}
}
// in a global registration hook:
fn register_classes(b: &mut LibraryBuilder) {
b.add_class::<MyClass>();
...
} |
This would be great! Additional problems like the inability to register methods coming from different trait impl wouldn't be a problem then - they could be just manually added in |
Just for completeness, I'd also like to mention fully dynamic builder APIs. Meaning, class methods are registered based on I don't think we should support this, at least not at the moment. But maybe we should also establish use cases for a typed builder API more clearly, to differentiate it better from features that the proc-macro API already provides. |
I'm copying this message from Discord to provide some feedback on usage of builder API. I'm currently using Godot 3/ The Both typed and untyped registration systems would perfectly work for the case above, as interface definition needs to be provided once and each class which would register this interface will have consistent signatures, properties etc. |
added delta_time parameter to KeepWaiting
Functionality that is currently available through proc-macros should ideally be exposed in a programmatic builder API, too.
Some challenges:
GodotExt
.Method
trait, which is very flexible and general, but required full implementation for every single type. This might serve as a basis, with more higher-level concretizations.The text was updated successfully, but these errors were encountered: