Skip to content

Proposal: Add #[dyn_func] to #[godot_api] to give a more convenient API for DynGd #1267

@sylbeth

Description

@sylbeth

Needs #1265

The only current way to, as of this moment, get a DynGd smart pointer is to manually use either try_dinify or FromGodot's methods. As the usage talked about in #1256, probably the best use case for DynGd is only to make one conversion in a function, or at least one at first, or so I've understood. Right now, this is explicit, and introduces identation, when most use cases of this would probably all look the same:

#[func]
fn func_name(&self, param: ...) {
    if let Ok(param) = param.try_dinify::<dyn Trait>() {
        do_something
    } else {
        do_something else
    }
}

In do something else, people would probably either panic (shouldn't be calling the function with a type that doesn't implement the trait), or return a default.

So, my proposal is as follows:

#[dyn_func(..., default = expr (evaluates to impl Fn() -> ReturnType, or Fn(&self) or Fn(&mut self), or Fn(Gd<Self>)), dyn_1 = Default::default)] // would accept panic (not specified), default (uses Default::default), default = func (where func is an expression that evaluates to impl Fn() -> ReturnType)
pub? fn func_name(&self, dyn_1: DynGd<DynNode, dyn DynTrait>, ...) -> ReturnType {
...
}

The default config makes Default::default the default callable in the else branches, which can be overriden for specific parameters, unless specified otherwise (ident/expr).

This would be equivalent to:

pub? fn _func_name(&self, dyn_1: DynGd<DynNode, dyn DynTrait>, ...) -> ReturnType {
    ...
}

#[func(...)]
pub? fn func_name(&self, dyn_1: Gd<DynNode>, ...) -> ReturnType {
    let Ok(dyn_1) = dyn_1.try_dinify() else { return Default::default(); };
    ...
    _func_name(&self, dyn_1, ...)
}

The _func_name is made with the same visibility as the one specified, in case someone has already a DynGd object and doesn't want to go through func_name.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions