makepad_platform/os/windows/
implement_com.rs1
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 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