Skip to content
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

implement macro overhaul #1345

Closed
kennykerr opened this issue Nov 19, 2021 · 1 comment · Fixed by #1450
Closed

implement macro overhaul #1345

kennykerr opened this issue Nov 19, 2021 · 1 comment · Fixed by #1450
Labels
enhancement New feature or request

Comments

@kennykerr
Copy link
Collaborator

kennykerr commented Nov 19, 2021

I'm starting to limit use of proc macros as much as possible. Part of that includes an overhaul of the implement macro that will not depend on metadata and instead rely on traits to determine what interface vtables to implement and what methods to expect from the developer. This should significantly reduce the compile time cost of using the implement macro and solve a variety of usability issues with the current macro.

This will require more code to be generated ahead of time to support upcalls from the ABI and traits for implementers to use. This code should be provided via a new implement feature to avoid taxing compile time for projects not using this feature. The code itself can be generated in distinct source file and included on demand based on cfg.

@kennykerr kennykerr added the enhancement New feature or request label Nov 19, 2021
@kennykerr
Copy link
Collaborator Author

kennykerr commented Jan 6, 2022

Making good progress on the overhaul. Here's an example:

use windows::core::*;
use windows::Foundation::*;

#[implement(IStringable, IClosable)]
struct Sample(pub i32);

impl IClosable_Impl for Sample {
    fn Close(&self) -> Result<()> {
        println!("Close {}", self.0);
        Ok(())
    }
}

impl IStringable_Impl for Sample {
    fn ToString(&self) -> Result<HSTRING> {
        println!("ToString {}", self.0);
        Ok("hello".into())
    }
}

fn main() -> Result<()> {
    let c: IClosable = Sample(123).into();
    c.Close()?;
    let o: IInspectable = c.into();
    assert!(o.GetRuntimeClassName()? == "Windows.Foundation.IClosable");

    let s: IStringable = Sample(456).into();
    assert!(s.ToString()? == "hello");
    let o: IInspectable = s.into();
    assert!(o.GetRuntimeClassName()? == "Windows.Foundation.IStringable");
    Ok(())
}

Notice how you no longer have to spell out the full type name in the implement macro and you now implement the desired interface members with traits (#1265). The traits need unique names, IStringable vs IStringableImpl, as the former still represents an instance.

The GetRuntimeClassName implementation will also automatically return the correct type name based on the relevant vtable (#1405). This is an improvement over cppwinrt, which only returns a single value for all vtables.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant