Refactor small parts of class_generator.rs by Bromeon · Pull Request #315 · godot-rust/gdext (original) (raw)

322: Default parameters in Engine API + meta param/return types r=Bromeon a=Bromeon

Default parameters in Engine API

Example RenderingServer::environment_set_ambient_light with signature:

void environment_set_ambient_light(
    RID env,
    Color color,
    EnvironmentAmbientSource ambient=0,
    float energy=1.0,
    float sky_contibution=0.0, 
    EnvironmentReflectionSource reflection_source=0
)

Previous gdext syntax:

server.environment_set_ambient_light(rid, color, 0, 1.0, 0.0, 0)

Now:

server.environment_set_ambient_light(rid, color)

With default arguments:

// select what you like, skip out-of-order:
server.environment_set_ambient_light_ex(rid, color).energy(2.0).done()

// provide all:
server.environment_set_ambient_light_ex(rid, color)
    .ambient(0)
    .energy(1.0)
    .sky_contribution(0.0)
    .reflection_source(0)
    .done()

See also this commit for the real-world impact this change has, within gdext alone.


Mechanics

Methods accepting default parameters come in two flavors: method and method_ex.

The _ex overload returns an "extender", a builder object providing a fluent API to accept values overriding the defaults. The arguments can be provided in any order, and arbitrary ones can be skipped. This is different from C++ and GDScript, where you have to provide all default arguments in their positional order.

This effectively implements an API similar to the one discussed in godot-rust/gdnative#814 (comment), however in a non-generic way and without enforcing ordering. Theoretically it's possible to specify the same argument twice, but that's a risk I'm gladly taking if I can avoid type-state with its compile-time and complexity implications.


Other changes

This pull request comes with a few collateral features:

Co-authored-by: Jan Haller bromeon@gmail.com