Skip to content

Commit

Permalink
Rust crate
Browse files Browse the repository at this point in the history
  • Loading branch information
MarijnS95 committed Apr 1, 2023
1 parent 7a7d110 commit 0a775b4
Show file tree
Hide file tree
Showing 18 changed files with 74,739 additions and 0 deletions.
21 changes: 21 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,24 @@ jobs:
with:
name: metadata
path: .windows/winmd

generate-rust:
name: Generate Rust crate
runs-on: ubuntu-latest
needs: generate-winmd
steps:
- uses: actions/checkout@v3
- name: Clean
run: rm -rf .windows/winmd/ .rust/crate/src/Windows/Win32/Graphics
- name: Download
uses: actions/download-artifact@v3
with:
name: metadata
path: .windows/winmd
- name: Generate
run: cargo r -p api_gen
- name: Upload
uses: actions/upload-artifact@v3
with:
name: crate
path: .rust/crate/src/
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,7 @@
/out
/CMakeUserPresets.json
/build*
/target
/Cargo.lock
/.metadata/obj
/.metadata/bin
9 changes: 9 additions & 0 deletions .rust/api_gen/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "api_gen"
version = "0.0.0"
edition = "2021"
publish = false

[dependencies]
windows-bindgen = "0.48"
windows-metadata = "0.48"
69 changes: 69 additions & 0 deletions .rust/api_gen/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use std::io::prelude::*;
use windows_metadata::reader::{File, Reader, Tree};

fn main() {
let start = std::time::Instant::now();
let mut output_path = std::path::PathBuf::new();

output_path.push(".rust/crate/src");
let _ = std::fs::remove_dir_all(output_path.join("Microsoft/DirectX"));

let winmd_files = [
File::new(".windows/winmd/Microsoft.DirectX.winmd").unwrap(),
File::new(".windows/winmd/Windows.Win32.winmd").unwrap(),
File::new(".windows/winmd/Windows.Win32.Interop.winmd").unwrap(),
];

let reader = Reader::new(&winmd_files);
let root = reader.tree("Microsoft.DirectX", &Default::default());

let trees = root.flatten();
trees
.iter()
.for_each(|tree| gen_tree(&reader, &output_path, tree));

println!("Took {:.1?}", start.elapsed());
}

fn gen_tree(reader: &Reader, output: &std::path::Path, tree: &Tree) {
let mut path = std::path::PathBuf::from(output);

println!("Generating {}", tree.namespace);

path.push(tree.namespace.replace('.', "/"));
std::fs::create_dir_all(&path).unwrap();

let mut gen = windows_bindgen::Gen::new(reader);
gen.namespace = tree.namespace;
gen.cfg = false;
gen.doc = false;

let mut tokens = windows_bindgen::namespace(&gen, tree);
tokens.push_str(r#"#[cfg(feature = "implement")] ::core::include!("impl.rs");"#);
fmt_tokens(tree.namespace, &mut tokens);
std::fs::write(path.join("mod.rs"), tokens).unwrap();

let mut tokens = windows_bindgen::namespace_impl(&gen, tree);
fmt_tokens(tree.namespace, &mut tokens);
std::fs::write(path.join("impl.rs"), tokens).unwrap();
}

fn fmt_tokens(namespace: &str, tokens: &mut String) {
let mut child = std::process::Command::new("rustfmt")
.stdin(std::process::Stdio::piped())
.stdout(std::process::Stdio::piped())
.stderr(std::process::Stdio::null())
.spawn()
.expect("Failed to spawn `rustfmt`");

let mut stdin = child.stdin.take().expect("Failed to open stdin");
stdin.write_all(tokens.as_bytes()).unwrap();
drop(stdin);
let output = child.wait_with_output().unwrap();

if output.status.success() {
*tokens = String::from_utf8(output.stdout).expect("Failed to parse UTF-8");
} else {
println!("** {} - rustfmt failed", namespace);
}
}
26 changes: 26 additions & 0 deletions .rust/crate/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[package]
name = "microsoft-directx"
version = "0.0.0-alpha.3"
authors = ["Marijn Suijten <[email protected]>"]
edition = "2021"
license = "MIT OR Apache-2.0"
description = "Rust bindings for the latest DirectX (Agility SDK) headers"
homepage = "https://github.com/Microsoft/DirectX-Headers"
repository = "https://github.com/MarijnS95/DirectX-Headers"

[package.metadata.docs.rs]
default-target = "x86_64-pc-windows-msvc"
targets = []

[dependencies.windows]
version = "0.48"
features = [
"Win32_Foundation",
"Win32_Graphics_Direct3D",
"Win32_Graphics_Direct3D11on12",
"Win32_Graphics_Dxgi_Common",
"Win32_Security",
]

[features]
implement = []
167 changes: 167 additions & 0 deletions .rust/crate/src/Microsoft/DirectX/Direct3D/impl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
pub trait ID3DBlob_Impl: Sized {
fn GetBufferPointer(&self) -> *mut ::core::ffi::c_void;
fn GetBufferSize(&self) -> usize;
}
impl ::windows::core::RuntimeName for ID3DBlob {}
impl ID3DBlob_Vtbl {
pub const fn new<
Identity: ::windows::core::IUnknownImpl<Impl = Impl>,
Impl: ID3DBlob_Impl,
const OFFSET: isize,
>() -> ID3DBlob_Vtbl {
unsafe extern "system" fn GetBufferPointer<
Identity: ::windows::core::IUnknownImpl<Impl = Impl>,
Impl: ID3DBlob_Impl,
const OFFSET: isize,
>(
this: *mut ::core::ffi::c_void,
) -> *mut ::core::ffi::c_void {
let this = (this as *const *const ()).offset(OFFSET) as *const Identity;
let this = (*this).get_impl();
this.GetBufferPointer()
}
unsafe extern "system" fn GetBufferSize<
Identity: ::windows::core::IUnknownImpl<Impl = Impl>,
Impl: ID3DBlob_Impl,
const OFFSET: isize,
>(
this: *mut ::core::ffi::c_void,
) -> usize {
let this = (this as *const *const ()).offset(OFFSET) as *const Identity;
let this = (*this).get_impl();
this.GetBufferSize()
}
Self {
base__: ::windows::core::IUnknown_Vtbl::new::<Identity, OFFSET>(),
GetBufferPointer: GetBufferPointer::<Identity, Impl, OFFSET>,
GetBufferSize: GetBufferSize::<Identity, Impl, OFFSET>,
}
}
pub fn matches(iid: &windows::core::GUID) -> bool {
iid == &<ID3DBlob as ::windows::core::ComInterface>::IID
}
}
pub trait ID3DDestructionNotifier_Impl: Sized {
fn RegisterDestructionCallback(
&self,
callbackfn: PFN_DESTRUCTION_CALLBACK,
pdata: *const ::core::ffi::c_void,
) -> ::windows::core::Result<u32>;
fn UnregisterDestructionCallback(&self, callbackid: u32) -> ::windows::core::Result<()>;
}
impl ::windows::core::RuntimeName for ID3DDestructionNotifier {}
impl ID3DDestructionNotifier_Vtbl {
pub const fn new<
Identity: ::windows::core::IUnknownImpl<Impl = Impl>,
Impl: ID3DDestructionNotifier_Impl,
const OFFSET: isize,
>() -> ID3DDestructionNotifier_Vtbl {
unsafe extern "system" fn RegisterDestructionCallback<
Identity: ::windows::core::IUnknownImpl<Impl = Impl>,
Impl: ID3DDestructionNotifier_Impl,
const OFFSET: isize,
>(
this: *mut ::core::ffi::c_void,
callbackfn: PFN_DESTRUCTION_CALLBACK,
pdata: *const ::core::ffi::c_void,
pcallbackid: *mut u32,
) -> ::windows::core::HRESULT {
let this = (this as *const *const ()).offset(OFFSET) as *const Identity;
let this = (*this).get_impl();
match this.RegisterDestructionCallback(
::core::mem::transmute_copy(&callbackfn),
::core::mem::transmute_copy(&pdata),
) {
::core::result::Result::Ok(ok__) => {
::core::ptr::write(pcallbackid, ::core::mem::transmute(ok__));
::windows::core::HRESULT(0)
}
::core::result::Result::Err(err) => err.into(),
}
}
unsafe extern "system" fn UnregisterDestructionCallback<
Identity: ::windows::core::IUnknownImpl<Impl = Impl>,
Impl: ID3DDestructionNotifier_Impl,
const OFFSET: isize,
>(
this: *mut ::core::ffi::c_void,
callbackid: u32,
) -> ::windows::core::HRESULT {
let this = (this as *const *const ()).offset(OFFSET) as *const Identity;
let this = (*this).get_impl();
this.UnregisterDestructionCallback(::core::mem::transmute_copy(&callbackid))
.into()
}
Self {
base__: ::windows::core::IUnknown_Vtbl::new::<Identity, OFFSET>(),
RegisterDestructionCallback: RegisterDestructionCallback::<Identity, Impl, OFFSET>,
UnregisterDestructionCallback: UnregisterDestructionCallback::<Identity, Impl, OFFSET>,
}
}
pub fn matches(iid: &windows::core::GUID) -> bool {
iid == &<ID3DDestructionNotifier as ::windows::core::ComInterface>::IID
}
}
pub trait ID3DInclude_Impl: Sized {
fn Open(
&self,
includetype: D3D_INCLUDE_TYPE,
pfilename: &::windows::core::PCSTR,
pparentdata: *const ::core::ffi::c_void,
ppdata: *mut *mut ::core::ffi::c_void,
pbytes: *mut u32,
) -> ::windows::core::Result<()>;
fn Close(&self, pdata: *const ::core::ffi::c_void) -> ::windows::core::Result<()>;
}
impl ID3DInclude_Vtbl {
pub const fn new<Impl: ID3DInclude_Impl>() -> ID3DInclude_Vtbl {
unsafe extern "system" fn Open<Impl: ID3DInclude_Impl>(
this: *mut ::core::ffi::c_void,
includetype: D3D_INCLUDE_TYPE,
pfilename: ::windows::core::PCSTR,
pparentdata: *const ::core::ffi::c_void,
ppdata: *mut *mut ::core::ffi::c_void,
pbytes: *mut u32,
) -> ::windows::core::HRESULT {
let this =
(this as *mut *mut ::core::ffi::c_void) as *const ::windows::core::ScopedHeap;
let this = &*((*this).this as *const Impl);
this.Open(
::core::mem::transmute_copy(&includetype),
::core::mem::transmute(&pfilename),
::core::mem::transmute_copy(&pparentdata),
::core::mem::transmute_copy(&ppdata),
::core::mem::transmute_copy(&pbytes),
)
.into()
}
unsafe extern "system" fn Close<Impl: ID3DInclude_Impl>(
this: *mut ::core::ffi::c_void,
pdata: *const ::core::ffi::c_void,
) -> ::windows::core::HRESULT {
let this =
(this as *mut *mut ::core::ffi::c_void) as *const ::windows::core::ScopedHeap;
let this = &*((*this).this as *const Impl);
this.Close(::core::mem::transmute_copy(&pdata)).into()
}
Self {
Open: Open::<Impl>,
Close: Close::<Impl>,
}
}
}
#[doc(hidden)]
struct ID3DInclude_ImplVtbl<T: ID3DInclude_Impl>(::std::marker::PhantomData<T>);
impl<T: ID3DInclude_Impl> ID3DInclude_ImplVtbl<T> {
const VTABLE: ID3DInclude_Vtbl = ID3DInclude_Vtbl::new::<T>();
}
impl ID3DInclude {
pub fn new<'a, T: ID3DInclude_Impl>(this: &'a T) -> ::windows::core::ScopedInterface<'a, Self> {
let this = ::windows::core::ScopedHeap {
vtable: &ID3DInclude_ImplVtbl::<T>::VTABLE as *const _ as *const _,
this: this as *const _ as *const _,
};
let this = ::std::mem::ManuallyDrop::new(::std::boxed::Box::new(this));
unsafe { ::windows::core::ScopedInterface::new(::std::mem::transmute(&this.vtable)) }
}
}
Loading

0 comments on commit 0a775b4

Please sign in to comment.