Skip to content

Commit

Permalink
Add component helper function to simplify component development (#1840
Browse files Browse the repository at this point in the history
)
  • Loading branch information
kennykerr authored Jun 22, 2022
1 parent 6a3a748 commit 0fafaed
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 28 deletions.
11 changes: 11 additions & 0 deletions crates/libs/bindgen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,17 @@ pub fn namespace_impl(gen: &Gen, tree: &Tree) -> String {
tokens.into_string()
}

pub fn component(namespace: &str, files: &[File]) -> String {
let reader = &Reader::new(files);
let tree = reader.tree(namespace, &[]).expect("Namespace not found");
let mut gen = Gen::new(reader);
gen.namespace = tree.namespace;
gen.component = true;
let mut bindings = crate::namespace(&gen, &tree);
bindings.push_str(&namespace_impl(&gen, &tree));
bindings
}

fn combine<'a>(types: &mut BTreeMap<&'a str, TokenStream>, name: &'a str, tokens: TokenStream) {
types.entry(name).or_default().combine(&tokens);
}
Expand Down
15 changes: 1 addition & 14 deletions crates/tests/component/build.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::fs::*;
use std::io::prelude::*;
use std::process::*;

fn main() -> std::io::Result<()> {
Expand All @@ -9,20 +8,8 @@ fn main() -> std::io::Result<()> {

Command::new("midlrt.exe").arg("/winrt").arg("/nomidl").arg("/h").arg("nul").arg("/metadata_dir").arg(&metadata_dir).arg("/reference").arg(format!("{}\\Windows.Foundation.winmd", metadata_dir)).arg("/winmd").arg(".windows/winmd/component.winmd").arg("src/component.idl").status()?;

std::fs::remove_file("src/bindings.rs").ok();
let mut bindings = File::create("src/bindings.rs")?;

// TODO: this needs to be simpler
let files = vec![metadata::reader::File::new("../../libs/metadata/default/Windows.winmd").unwrap(), metadata::reader::File::new(".windows/winmd/component.winmd").unwrap()];
let reader = &metadata::reader::Reader::new(&files);
let tree = reader.tree("test_component", &[]).expect("`test_component` namespace not found");
let mut gen = bindgen::Gen::new(reader);
gen.namespace = tree.namespace;
gen.component = true;
bindings.write_all(bindgen::namespace(&gen, &tree).as_bytes())?;
bindings.write_all(bindgen::namespace_impl(&gen, &tree).as_bytes())?;

drop(bindings);
write("src/bindings.rs", bindgen::component("test_component", &files))?;
Command::new("rustfmt").arg("src/bindings.rs").status()?;

Ok(())
Expand Down
15 changes: 1 addition & 14 deletions crates/tests/component_client/build.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,12 @@
use std::fs::*;
use std::io::prelude::*;
use std::process::*;

fn main() -> std::io::Result<()> {
create_dir_all(".windows/winmd")?;
copy("../component/.windows/winmd/component.winmd", ".windows/winmd/component.winmd")?;

std::fs::remove_file("src/bindings.rs").ok();
let mut bindings = File::create("src/bindings.rs")?;

// TODO: this needs to be simpler
let files = vec![metadata::reader::File::new("../../libs/metadata/default/Windows.winmd").unwrap(), metadata::reader::File::new(".windows/winmd/component.winmd").unwrap()];
let reader = &metadata::reader::Reader::new(&files);
let tree = reader.tree("test_component", &[]).expect("`test_component` namespace not found");
let mut gen = bindgen::Gen::new(reader);
gen.namespace = tree.namespace;
gen.component = true;
bindings.write_all(bindgen::namespace(&gen, &tree).as_bytes())?;

drop(bindings);

write("src/bindings.rs", bindgen::component("test_component", &files))?;
Command::new("rustfmt").arg("src/bindings.rs").status()?;
Ok(())
}
36 changes: 36 additions & 0 deletions crates/tests/component_client/src/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,39 @@ pub struct IClass_Vtbl {
pub Property: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, result__: *mut i32) -> ::windows::core::HRESULT,
pub SetProperty: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value: i32) -> ::windows::core::HRESULT,
}
pub trait IClass_Impl: Sized {
fn Property(&self) -> ::windows::core::Result<i32>;
fn SetProperty(&self, value: i32) -> ::windows::core::Result<()>;
}
impl ::windows::core::RuntimeName for IClass {
const NAME: &'static str = "test_component.IClass";
}
impl IClass_Vtbl {
pub const fn new<Identity: ::windows::core::IUnknownImpl<Impl = Impl>, Impl: IClass_Impl, const OFFSET: isize>() -> IClass_Vtbl {
unsafe extern "system" fn Property<Identity: ::windows::core::IUnknownImpl<Impl = Impl>, Impl: IClass_Impl, const OFFSET: isize>(this: *mut ::core::ffi::c_void, result__: *mut i32) -> ::windows::core::HRESULT {
let this = (this as *const *const ()).offset(OFFSET) as *const Identity;
let this = (*this).get_impl();
match this.Property() {
::core::result::Result::Ok(ok__) => {
::core::ptr::write(result__, ::core::mem::transmute_copy(&ok__));
::core::mem::forget(ok__);
::windows::core::HRESULT(0)
}
::core::result::Result::Err(err) => err.into(),
}
}
unsafe extern "system" fn SetProperty<Identity: ::windows::core::IUnknownImpl<Impl = Impl>, Impl: IClass_Impl, const OFFSET: isize>(this: *mut ::core::ffi::c_void, value: i32) -> ::windows::core::HRESULT {
let this = (this as *const *const ()).offset(OFFSET) as *const Identity;
let this = (*this).get_impl();
this.SetProperty(value).into()
}
Self {
base__: ::windows::core::IInspectableVtbl::new::<Identity, IClass, OFFSET>(),
Property: Property::<Identity, Impl, OFFSET>,
SetProperty: SetProperty::<Identity, Impl, OFFSET>,
}
}
pub fn matches(iid: &windows::core::GUID) -> bool {
iid == &<IClass as ::windows::core::Interface>::IID
}
}

0 comments on commit 0fafaed

Please sign in to comment.