makepad_platform/os/windows/
implement_com.rs

1
2#[macro_export]
3macro_rules!implement_com{
4    {
5        for_struct: $ for_struct: ident,
6        identity: $ identity: ident,
7        wrapper_struct: $ wrapper_struct: ident,
8        interface_count: $ interface_count: tt,
9        interfaces: {
10            $ ( $ iface_index: tt: $ iface: ident), *
11        }
12    } => {
13        
14        #[repr(C)]
15        struct $ wrapper_struct {
16            identity: *const crate::windows::core::IInspectable_Vtbl,
17            vtables:
18            ( $ (*const < $ iface as crate::windows::core::Interface> ::Vtable), *, ()),
19            this: $ for_struct,
20            count: crate::windows::core::imp::WeakRefCount,
21        }
22        
23        impl $ wrapper_struct {
24            const VTABLES:
25            ( $ (< $ iface as crate::windows::core::Interface> ::Vtable), *, ()) =
26            ( $ (< $ iface as crate::windows::core::Interface> ::Vtable ::new ::<Self, $ for_struct, {-1 - $ iface_index}>()), *, ());
27            
28            const IDENTITY: crate::windows::core::IInspectable_Vtbl = crate::windows::core::IInspectable_Vtbl::new::<Self,$identity,0> ();
29            
30            fn new(this: $ for_struct) -> Self {
31                Self {
32                    identity: &Self::IDENTITY,
33                    vtables: ( $ (&Self::VTABLES. $ iface_index), *, ()),
34                    this,
35                    count: crate::windows::core::imp::WeakRefCount ::new(),
36                }
37            }
38        }
39        
40        impl crate::windows::core::IUnknownImpl for $ wrapper_struct {
41            type Impl = $ for_struct;
42            
43            fn get_impl(&self) -> &Self ::Impl {
44                &self.this
45            }
46            
47            #[allow(non_snake_case)]
48            unsafe fn QueryInterface(&self, iid: &crate::windows::core::GUID, interface: *mut *const ::core ::ffi ::c_void) -> crate::windows::core::HRESULT {
49                *interface =
50                if iid == &<crate::windows::core::IUnknown as crate::windows::core::ComInterface> ::IID ||
51                  iid == &<crate::windows::core::IInspectable as crate::windows::core::ComInterface> ::IID ||
52                  iid == &<crate::windows::core::imp::IAgileObject as crate::windows::core::ComInterface> ::IID{
53                    &self.identity as *const _ as *const _
54                }
55                $ (else if < $ iface as crate::windows::core::Interface> ::Vtable::matches(iid) {
56                    &self.vtables. $ iface_index as *const _ as *const _
57                }) *
58                else {
59                    std::ptr::null_mut()
60                };
61                
62                if!(*interface).is_null() {
63                    self.count.add_ref();
64                    return crate::windows::core::HRESULT(0);
65                }
66                
67                *interface = self.count.query(iid, &self.identity as *const _ as *mut _);
68                
69                if (*interface).is_null() {
70                    crate::windows::core::HRESULT(-2147467262i32)
71                }
72                else {
73                    crate::windows::core::HRESULT(0)
74                }
75            }
76            
77            #[allow(non_snake_case)]
78            fn AddRef(&self) -> u32 {self.count.add_ref()}
79            
80            #[allow(non_snake_case)]
81            unsafe fn Release(&self) -> u32 {
82                let remaining = self.count.release();
83                if remaining == 0 {
84                    let _ = Box ::from_raw(self as *const Self as *mut Self);
85                } remaining
86            }
87        }
88        /*
89        impl $ for_struct {
90            unsafe fn cast<I: crate::windows_crate::core::Interface> (&self) -> crate::windows_crate::core::Result<I> {
91                let boxed = (self as *const _ as *const *mut std::ffi::c_void).sub(1 + $interface_count) as *mut $ wrapper_struct;
92                let mut result = None;
93                < $ wrapper_struct as crate::windows_crate::core::IUnknownImpl>::QueryInterface(&*boxed, &I::IID, &mut result as *mut _ as _).and_some(result)
94            }
95        }*/
96        
97        impl std::convert::From< $ for_struct> for crate::windows::core::IUnknown {
98            fn from(this: $ for_struct) -> Self {
99                let this = $ wrapper_struct::new(this);
100                let boxed = std::mem::ManuallyDrop::new(Box::new(this));
101                unsafe {std::mem ::transmute(&boxed.identity)}
102            }
103        }
104        
105        $ (
106            impl std::convert::From< $ for_struct> for $ iface {
107                fn from(this: $ for_struct) -> Self {
108                    let this = $ wrapper_struct::new(this);
109                    let this = std::mem::ManuallyDrop::new(Box::new(this));
110                    let vtable_ptr = &this.vtables. $ iface_index;
111                    unsafe {std::mem ::transmute(vtable_ptr)}
112                }
113            }
114            
115            impl crate::windows::core::AsImpl< $ for_struct> for $ iface {
116                unsafe fn as_impl(&self) -> & $ for_struct {
117                    let this = crate::windows::core::Interface::as_raw(self);
118                    unsafe {
119                        let this = (this as *mut *mut ::core ::ffi ::c_void).sub(1 + $ iface_index) as *mut $ wrapper_struct ::< >;
120                        &(*this).this
121                    }
122                }
123            }
124        ) *
125        
126    }
127}
128