Skip to content

create a macro to create interfaces for externally defined types #200

Open
@karroffel

Description

@karroffel

Objects that have scripts written in other languages attached can be passed to methods in Rust, the functionality provided by those scripts can't be accessed easily.

This is a proposal to create a procedural macro to use a trait as the description for an interface of an object.

An implementation of such a trait would use godot_variant_call to perform the calls.
All functions in the trait have to return a result type to represent the varcall failing.

When an object is used as an implementation of this interface no immediate checks are performed. Doing type-checking is not possible in the general case, so checks should be performed lazily.

This could work like this:

# adder.gd
extends Reference

var _value = 0

func add(amount: int) -> void:
    _value += amount

func tell() -> int:
    return _value
// src/lib.rs

// ... [ snip ] ...

#[gdnative::external_interface]
trait Adder: ExtInterface<Base = Reference> {

    fn add(&mut self, amount: i64) -> ExtResult<()>;
    fn tell(&self) -> ExtResult<i64>;
}

#[derive(gdnative::ExtInterfaceImpl)]
#[gdnative::ext_interface(Adder)]
struct AdderImpl<'a>;

/*
// possible definition of impl-trait
trait ExtInterfaceImpl<'a> {
    type Interface: ExtInterface;
    fn from(base: &'a Self::Interface::Base) -> Self;
}
*/

// ... [ snip ] ...

#[export]
fn set_to_one_hundred(&self, _owner: Reference, adder: Reference) {
    use gdnative::ExtInterfaceImpl;

    let adder = AdderImpl::from(&adder);
    let current = if let Ok(val) = adder.tell() {
        val
    } else {
        return;
    }
    let difference = 100 - current;
    if difference <= 0 {
        return;
    }

    // TODO check result, maybe the type does not actually implement the interface
    let _ = adder.add(different);
    
    let new_value = adder.tell().unwrap_or(0):
    assert_eq!(new_value, 100);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    c: exportComponent: export (mod export, derive)featureAdds functionality to the library

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions