1
1
use futures:: future:: Future ;
2
2
use std:: pin:: Pin ;
3
+ use std:: ops:: Deref ;
3
4
use std:: task:: { Context , Poll } ;
4
5
use std:: sync:: { Arc , Mutex , Condvar } ;
5
6
@@ -78,8 +79,7 @@ macro_rules! impl_blocking_wait {
78
79
}
79
80
}
80
81
81
- impl RtAsyncAction for IAsyncAction
82
- {
82
+ impl RtAsyncAction for IAsyncAction {
83
83
impl_blocking_wait ! { AsyncActionCompletedHandler }
84
84
}
85
85
@@ -95,39 +95,6 @@ impl<T: RtType + 'static> RtAsyncAction for IAsyncOperation<T>
95
95
impl_blocking_wait ! { AsyncOperationCompletedHandler }
96
96
}
97
97
98
- impl < ' a , T : RtType + ' static > Future for crate :: ComPtr < IAsyncOperation < T > >
99
- where AsyncOperationCompletedHandler < T > : ComIid
100
- {
101
- type Output = Result < <T as RtType >:: Out > ;
102
-
103
- fn poll ( self : Pin < & mut Self > , cx : & mut Context ) -> Poll < Self :: Output > {
104
- use std:: ops:: Deref ;
105
-
106
- let info = crate :: comptr:: query_interface :: < _ , IAsyncInfo > ( self . deref ( ) . deref ( ) ) . expect ( "query_interface failed" ) ;
107
- let status = info. get_status ( ) . expect ( "get_status failed" ) ;
108
- match status {
109
- crate :: langcompat:: ASYNC_STATUS_COMPLETED => {
110
- Poll :: Ready ( self . get_results ( ) )
111
- } ,
112
- crate :: langcompat:: ASYNC_STATUS_STARTED => {
113
- if self . get_completed ( ) . expect ( "get_completed failed" ) . is_some ( ) {
114
- return Poll :: Pending ;
115
- }
116
- let waker = cx. waker ( ) . clone ( ) ;
117
-
118
- let handler = AsyncOperationCompletedHandler :: new ( move |_op, _status| {
119
- waker. wake_by_ref ( ) ;
120
- Ok ( ( ) )
121
- } ) ;
122
-
123
- self . set_completed ( & handler) . expect ( "set_completed failed" ) ;
124
- Poll :: Pending
125
- }
126
- _ => unimplemented ! ( )
127
- }
128
- }
129
- }
130
-
131
98
impl < T : RtType + ' static > RtAsyncOperation for IAsyncOperation < T >
132
99
where AsyncOperationCompletedHandler < T > : ComIid
133
100
{
@@ -156,20 +123,67 @@ impl<T: RtType + 'static, P: RtType + 'static> RtAsyncOperation for IAsyncOperat
156
123
}
157
124
}
158
125
159
- // Make await syntax work with `ComPtr` directly
160
- /*impl<'a, T: RtType + 'static> Future for &'a crate::ComPtr<T>
161
- where &'a T: Future,
162
- //&'a crate::rt::gen::windows::foundation::IAsyncOperation<T> : futures::Future,
163
- //&'a crate::ComPtr<T>: Unpin
164
- {
165
- type Output = <&'a T as Future>::Output;
166
- #[inline] fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
167
- use std::ops::DerefMut;
168
- //unsafe { self.map_unchecked(|ptr| ptr.deref().deref()) }.poll(self, cx)
169
- let s: Pin<&mut &_>/*: Pin<&mut &IAsyncOperation<_>>*/ = unsafe { self.map_unchecked_mut(|mut ptr| &mut&**ptr) };
170
- //let s: Pin<&mut &'a IAsyncOperation<T>> = Pin::new(&mut **self.get_mut().deref_mut().deref_mut());
171
- //let p: crate::ComPtr<T>
172
- s.poll(cx)
173
- //unimplemented!()
126
+
127
+ macro_rules! impl_poll {
128
+ ( $handler: ident => $retexpr: tt) => {
129
+ fn poll( self : Pin <& mut Self >, cx: & mut Context ) -> Poll <Self :: Output > {
130
+ let info = crate :: comptr:: query_interface:: <_, IAsyncInfo >( self . deref( ) . deref( ) ) . expect( "query_interface failed" ) ;
131
+ let status = info. get_status( ) . expect( "get_status failed" ) ;
132
+ match status {
133
+ crate :: windows:: foundation:: AsyncStatus :: Completed => {
134
+ Poll :: Ready ( $retexpr( self ) )
135
+ } ,
136
+ crate :: windows:: foundation:: AsyncStatus :: Started => {
137
+ // Calling poll multiple times must work correctly, so we have to check that we didn't already install the Completed handler
138
+ if self . get_completed( ) . expect( "get_completed failed" ) . is_some( ) {
139
+ // TODO: We might have to check that the installed handler is actually
140
+ // the one with the waker (because the user could have installed one independently).
141
+ // Or we document that the user is not allowed to do that.
142
+ return Poll :: Pending ;
143
+ }
144
+ let waker = cx. waker( ) . clone( ) ;
145
+
146
+ let handler = $handler:: new( move |_op, _status| {
147
+ waker. wake_by_ref( ) ;
148
+ Ok ( ( ) )
149
+ } ) ;
150
+
151
+ self . set_completed( & handler) . expect( "set_completed failed" ) ;
152
+ Poll :: Pending
153
+ }
154
+ _ => unimplemented!( ) // FIXME
155
+ }
156
+ }
174
157
}
175
- }*/
158
+ }
159
+
160
+
161
+ impl Future for crate :: ComPtr < IAsyncAction > {
162
+ type Output = ( ) ;
163
+
164
+ impl_poll ! { AsyncActionCompletedHandler => { |_: Pin <& mut Self >| ( ) } }
165
+ }
166
+
167
+ impl < P : RtType + ' static > Future for crate :: ComPtr < IAsyncActionWithProgress < P > >
168
+ where AsyncActionWithProgressCompletedHandler < P > : ComIid
169
+ {
170
+ type Output = ( ) ;
171
+
172
+ impl_poll ! { AsyncActionWithProgressCompletedHandler => { |_: Pin <& mut Self >| ( ) } }
173
+ }
174
+
175
+ impl < T : RtType + ' static > Future for crate :: ComPtr < IAsyncOperation < T > >
176
+ where AsyncOperationCompletedHandler < T > : ComIid
177
+ {
178
+ type Output = Result < <T as RtType >:: Out > ;
179
+
180
+ impl_poll ! { AsyncOperationCompletedHandler => { |s: Pin <& mut Self >| s. get_results( ) } }
181
+ }
182
+
183
+ impl < T : RtType + ' static , P : RtType + ' static > Future for crate :: ComPtr < IAsyncOperationWithProgress < T , P > >
184
+ where AsyncOperationWithProgressCompletedHandler < T , P > : ComIid
185
+ {
186
+ type Output = Result < <T as RtType >:: Out > ;
187
+
188
+ impl_poll ! { AsyncOperationWithProgressCompletedHandler => { |s: Pin <& mut Self >| s. get_results( ) } }
189
+ }
0 commit comments