3 pub fn writer(writer
: &Writer
, def
: TypeDef
) -> TokenStream
{
4 if def
.flags().contains(TypeAttributes
::WindowsRuntime
) {
5 gen_delegate(writer
, def
)
7 gen_callback(writer
, def
)
11 fn gen_callback(writer
: &Writer
, def
: TypeDef
) -> TokenStream
{
12 let name
= to_ident(def
.name());
13 let method
= type_def_invoke_method(def
);
15 let signature
= method_def_signature(def
.namespace(), method
, &[]);
17 let return_type
= writer
.return_sig(&signature
);
18 let cfg
= type_def_cfg(def
, &[]);
19 let doc
= writer
.cfg_doc(&cfg
);
20 let features
= writer
.cfg_features(&cfg
);
22 let params
= signature
.params
.iter().map(|p
| {
23 let name
= writer
.param_name(p
.def
);
24 let tokens
= writer
.type_default_name(&p
.ty
);
25 quote
! { #name: #tokens }
31 pub type #name = ::core::option::Option<unsafe extern "system" fn(#(#params),*) #return_type>;
35 fn gen_delegate(writer
: &Writer
, def
: TypeDef
) -> TokenStream
{
37 let name
= to_ident(def
.name());
39 pub type #name = *mut ::core::ffi::c_void;
42 gen_win_delegate(writer
, def
)
46 fn gen_win_delegate(writer
: &Writer
, def
: TypeDef
) -> TokenStream
{
47 let name
= to_ident(def
.name());
48 let vtbl
= name
.join("_Vtbl");
49 let boxed
= name
.join("Box");
51 let generics
= &type_def_generics(def
);
52 let phantoms
= writer
.generic_phantoms(generics
);
53 let named_phantoms
= writer
.generic_named_phantoms(generics
);
54 let constraints
= writer
.generic_constraints(generics
);
55 let generic_names
= writer
.generic_names(generics
);
57 let ident
= writer
.type_def_name(def
, generics
);
58 let method
= type_def_invoke_method(def
);
60 let signature
= method_def_signature(def
.namespace(), method
, generics
);
62 let fn_constraint
= gen_fn_constraint(writer
, def
, &signature
);
63 let cfg
= type_def_cfg(def
, generics
);
64 let doc
= writer
.cfg_doc(&cfg
);
65 let features
= writer
.cfg_features(&cfg
);
67 let vtbl_signature
= writer
.vtbl_signature(def
, generics
, &signature
);
68 let invoke
= winrt_methods
::writer(writer
, def
, generics
, InterfaceKind
::Default
, method
, &mut MethodNames
::new(), &mut MethodNames
::new());
69 let invoke_upcall
= winrt_methods
::gen_upcall(writer
, &signature
, quote
! { ((*this).invoke) }
);
71 let mut tokens
= quote
! {
75 #[derive(::core::cmp::PartialEq, ::core::cmp::Eq, ::core::fmt::Debug, ::core::clone::Clone)]
76 pub struct #ident(pub ::windows_core::IUnknown, #phantoms) where #constraints;
78 impl<#constraints> #ident {
79 pub fn new
<#fn_constraint>(invoke: F) -> Self {
80 let com
= #boxed::<#generic_names F> {
81 vtable
: &#boxed::<#generic_names F>::VTABLE,
82 count
: ::windows_core
::imp
::RefCount
::new(1),
86 ::core
::mem
::transmute(::std
::boxed
::Box
::new(com
))
93 struct #boxed<#generic_names #fn_constraint> where #constraints {
94 vtable
: *const #vtbl<#generic_names>,
96 count
: ::windows_core
::imp
::RefCount
,
99 impl<#constraints #fn_constraint> #boxed<#generic_names F> {
100 const VTABLE
: #vtbl<#generic_names> = #vtbl::<#generic_names>{
101 base__
: ::windows_core
::IUnknown_Vtbl{QueryInterface: Self::QueryInterface, AddRef: Self::AddRef, Release: Self::Release}
,
102 Invoke
: Self::Invoke
,
105 unsafe extern "system" fn QueryInterface(this
: *mut ::core
::ffi
::c_void
, iid
: *const ::windows_core
::GUID
, interface
: *mut *mut ::core
::ffi
::c_void
) -> ::windows_core
::HRESULT
{
106 let this
= this
as *mut *mut ::core
::ffi
::c_void
as *mut Self;
108 if iid
.is_null() || interface
.is_null() {
109 return ::windows_core
::HRESULT(-2147467261); // E_POINTER
112 *interface
= if *iid
== <#ident as ::windows_core::ComInterface>::IID ||
113 *iid
== <::windows_core
::IUnknown
as ::windows_core
::ComInterface
>::IID
||
114 *iid
== <::windows_core
::imp
::IAgileObject
as ::windows_core
::ComInterface
>::IID
{
115 &mut (*this
).vtable
as *mut _
as _
117 ::core
::ptr
::null_mut()
120 // TODO: implement IMarshal
122 if (*interface
).is_null() {
123 ::windows_core
::HRESULT(-2147467262) // E_NOINTERFACE
125 (*this
).count
.add_ref();
126 ::windows_core
::HRESULT(0)
129 unsafe extern "system" fn AddRef(this
: *mut ::core
::ffi
::c_void
) -> u32 {
130 let this
= this
as *mut *mut ::core
::ffi
::c_void
as *mut Self;
131 (*this
).count
.add_ref()
133 unsafe extern "system" fn Release(this
: *mut ::core
::ffi
::c_void
) -> u32 {
134 let this
= this
as *mut *mut ::core
::ffi
::c_void
as *mut Self;
135 let remaining
= (*this
).count
.release();
138 let _
= ::std
::boxed
::Box
::from_raw(this
);
143 unsafe extern "system" fn Invoke
#vtbl_signature {
144 let this
= this
as *mut *mut ::core
::ffi
::c_void
as *mut Self;
150 tokens
.combine(&writer
.interface_trait(def
, generics
, &ident
, &constraints
, &features
, true));
151 tokens
.combine(&writer
.interface_winrt_trait(def
, generics
, &ident
, &constraints
, &phantoms
, &features
));
152 tokens
.combine(&writer
.interface_vtbl(def
, generics
, &ident
, &constraints
, &features
));
156 fn gen_fn_constraint(writer
: &Writer
, def
: TypeDef
, signature
: &Signature
) -> TokenStream
{
157 let signature
= writer
.impl_signature(def
, signature
);
159 quote
! { F: FnMut #signature + ::core::marker::Send + 'static }