-
Notifications
You must be signed in to change notification settings - Fork 211
[WIP] Derive property groups #855
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
[WIP] Derive property groups #855
Conversation
c53620a to
234a37d
Compare
234a37d to
1828e4d
Compare
1828e4d to
6832f39
Compare
|
For Rust, we should probably follow a slightly different approach than in GDScript. I agree that the behavior is suprising and has room for improvement. Some ideas what we could do better in Rust:
I'm not yet sure about grouping via struct or via label (attribute), it depends a bit how this would be used. Struct would be the "more correct" way, but keep in mind that this means that the export layout determines how Rust code needs to access the fields. Which can be a good thing (when improving code structure), or super annoying (when forcing introduction of 5 new types for seemingly no benefit). I'd still say we should choose one way here. In case we go for the structural approach, your 2nd proposed API already looks quite nice. In a label-based world, I would probably change some things: // Group is named "Offset", no prefix for fields
#[derive(PropertyGroup)]
struct Offset;
// Group is named "Size", fields prefixed "size_"
#[derive(PropertyGroup)]
#[group(title = "Size", prefix = "size_")]
struct SizeGroup;
#[derive(NativeClass)]
#[inherit(Node)]
pub struct MyStruct {
// This property is _not_ grouped.
// Exported as "magnitude"
#[property(default = 8.0, set = "Self::set_magnitude")]
magnitude: f32,
// Exported as "offset_x"
#[property(group = Offset)]
offset_x: f32,
// Exported as "offset_y"
#[property(group = Offset)]
offset_y: f32,
// Exported as "size_width"
#[property(group = SizeGroup)]
width: u32,
// Exported as "size_height"
#[property(group = SizeGroup)]
height: u32,
// Not member of a group simply because there's no `group` attribute
// No need to inspect any field declarations before
#[property]
duration: f32,
}Not fully happy with the prefix magic though. We might as well use an explicit |
|
@parasyte Any feedback on my ideas above? 💡 |
|
It seems like this PR has fallen into inactivity for a while, and has now drifted too far from Note that property grouping via renaming has been available since at least 0.9.2: |
|
Closing this is the right thing to do. I can’t comment on how it compares to the Thanks for the reminder on this. |
https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_exports.html#adding-script-categories
https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_exports.html#grouping-properties
This was thrown together to start a discussion. There are no tests, and I am not happy with the implementation. Consider this PR an experiment with no intention to merge. But it could help define the feature and identify shortcomings.
Usage currently looks something like this:
How it looks in the editor:
Ideally, I believe that property groups should be declared structurally. The example above has a flat hierarchy that illustrates many issues:
group = "..."arg is easy to typo, which will ruin the grouping of items. Likewise, property names are only conventionally grouped by a prefix.Nilwhich provides a name for the group. In the example,sizeandoffsetare both group names, created automatically by the property attribute using the field name as the property's name. TheGroupMarkertype is just a way to feed theNilvalue to Godot.GROUPusage flag enabled will become a member of that group. (See the linked GDScript documentation.)hint_stringis provided on the property with theGROUPflag: In this case, only properties whose name matches the given hint prefix will become group members. Any other properties will "move" to the top of the list outside of any group. This behavior is surprising, and any number of bugs can cause this to happen by mistake.With structural declaration, the example could possibly look like this:
This looks more reasonable, but it also has some problems:
size.widthbeing renamed tosize_widthand a hint on the group set to"size_"to handle the prefixing. Creating a group without prefix handling would have to be an extra option for the property attribute.OffsetandSizeas separate types, and they both have to refer back toMyStructfor getter/setter functions. At least it makes sense to include hint functions on these separate types.#[property(group)]for this? Is ``#[derive(PropertyGroup)]` enough? Can we do something better?