-
-
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
Type-safe signals #1000
base: master
Are you sure you want to change the base?
Type-safe signals #1000
Conversation
Adds three APIs to classes that contain at least one #[signal] decl: - self.signals() - self.funcs() - Self::static_funcs() The idea is to use generated symbols for type-safe connecting (signal -> func) as well as emitting. This is still WIP.
API docs are being generated and will be shortly available at: https://godot-rust.github.io/docs/gdext/pr-1000 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just looking through this a bit and it's really cool from what i can tell! as it's a draft im not really gonna do a proper review but it'll be cool to see the more finished product.
(also happy 1000th issue/pr :p)
pub trait ParamTuple { | ||
fn to_variant_array(&self) -> Vec<Variant>; | ||
fn from_variant_array(array: &[&Variant]) -> Self; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i wonder if this is something we could reuse in Ptr/VarcallSignatureTuple
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I was wondering the same, the similarities are hard to overlook 🙂 It could even be a foundation for a potential builder API one day, if we allow users to register their own methods....
One thing that would be interesting, but very hard to measure, is how compile-time is impacted by different approaches (e.g. more code in declarative macros vs. procedural macros vs. traits/generics) 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing that would be interesting, but very hard to measure, is how compile-time is impacted by different approaches (e.g. more code in declarative macros vs. procedural macros vs. traits/generics) 🤔
I can imagine it would also vary a lot depending on exactly what lies where too
223a47c
to
686f08d
Compare
522dfbc
to
73f520f
Compare
73f520f
to
ba17d4a
Compare
|
||
/// Extracted syntax info for a declared signal. | ||
struct SignalDetails<'a> { | ||
/// `fn my_signal(i: i32, s: GString)` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would change these from docstrings ///
to normal comments //
- IDE highlights might be a bit too confusing in isolation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure how you mean this -- these types are only used during codegen of the macro and won't be visible to the user.
Using ///
has the advantage that hovering over the fields (elsewhere) shows some example formats, plus there's syntax highlighting for the `...`
backticked parts 🙂
Seeing this MR gave me a smile for the whole day. Thanks. :) |
Closes #8.
Closes #620.
Early draft for a type-safe signal system. Largely backwards compatible with the current syntax.
The following...
...expands to code that can then be used like this (inside
impl MyClass
):Note that this is explicitly not limited to functions declared via
#[func]
. I had an earlier draft with a generatedfuncs()
API which would route the calls via Godot reflection, but this seems more flexible, since you can keep signal recipients private in Rust. On the downside, it may be harder to disconnect such signals.Compatibility
#[signal]
now requires aBase<T>
field.As far as I can see, that's the only breakage. It might also be possible to opt in to the new type-safe signals via something like
#[godot_api(signals)]
or so.This feature is only available on Godot 4.2+, since it requires custom callables.
Work to do
There's a ton that can still be added, in either this or future PRs:
sig.connect_obj(obj, Class::method)
impl
)gd.signals().my_signal()
#[signal]
pub
etc).AsArg
inemit()
&self
methods