@@ -22,13 +22,26 @@ use bevy::prelude::{
22
22
use std:: future:: Future ;
23
23
24
24
use crate :: {
25
- Promise , Provider , StreamPack , Detach , TakenResponse , AddOperation ,
26
- IntoBlockingMap , IntoAsyncMap , ImpulseProperties , UnusedTarget , StoreResponse ,
27
- PushResponse ,
25
+ Promise , Provider , StreamPack , IntoBlockingMap , IntoAsyncMap , UnusedTarget ,
28
26
} ;
29
27
30
- pub mod traits;
31
- pub use traits:: * ;
28
+ mod detach;
29
+ pub ( crate ) use detach:: * ;
30
+
31
+ mod insert;
32
+ pub ( crate ) use insert:: * ;
33
+
34
+ mod internal;
35
+ pub ( crate ) use internal:: * ;
36
+
37
+ mod push;
38
+ pub ( crate ) use push:: * ;
39
+
40
+ mod store;
41
+ pub ( crate ) use store:: * ;
42
+
43
+ mod taken;
44
+ pub ( crate ) use taken:: * ;
32
45
33
46
/// Impulses can be chained as a simple sequence of [providers](Provider).
34
47
pub struct Impulse < ' w , ' s , ' a , Response , Streams > {
@@ -50,15 +63,16 @@ where
50
63
self
51
64
}
52
65
53
- /// Take the data that comes out of the request.
66
+ /// Take the data that comes out of the request, including both the response
67
+ /// and the streams.
54
68
#[ must_use]
55
69
pub fn take ( self ) -> Recipient < Response , Streams > {
56
70
let ( response_sender, response_promise) = Promise :: < Response > :: new ( ) ;
57
- self . commands . add ( AddOperation :: new (
71
+ self . commands . add ( AddImpulse :: new (
58
72
self . session ,
59
73
TakenResponse :: < Response > :: new ( response_sender) ,
60
74
) ) ;
61
- let ( bundle, stream_receivers) = Streams :: make_receiver ( self . session , self . commands ) ;
75
+ let ( bundle, stream_receivers) = Streams :: take_streams ( self . session , self . commands ) ;
62
76
self . commands . entity ( self . source ) . insert ( bundle) ;
63
77
64
78
Recipient {
67
81
}
68
82
}
69
83
84
+ /// Take only the response data that comes out of the request.
85
+ #[ must_use]
86
+ pub fn take_response ( self ) -> Promise < Response > {
87
+ let ( response_sender, response_promise) = Promise :: < Response > :: new ( ) ;
88
+ self . commands . add ( AddImpulse :: new (
89
+ self . session ,
90
+ TakenResponse :: < Response > :: new ( response_sender) ,
91
+ ) ) ;
92
+ response_promise
93
+ }
94
+
70
95
/// Pass the outcome of the request to another provider.
71
96
#[ must_use]
72
97
pub fn then < P : Provider < Request = Response > > (
75
100
) -> Impulse < ' w , ' s , ' a , P :: Response , P :: Streams > {
76
101
let source = self . session ;
77
102
let session = self . commands . spawn ( (
78
- ImpulseProperties :: new ( ) ,
103
+ Detached :: default ( ) ,
79
104
UnusedTarget ,
80
105
) ) . id ( ) ;
81
106
@@ -127,36 +152,75 @@ where
127
152
128
153
/// Store the response in a [`Storage`] component in the specified entity.
129
154
///
155
+ /// Each stream will be collected into [`Collection`] components in the
156
+ /// specified entity, one for each stream type. To store the streams in a
157
+ /// different entity, call [`Self::collect_streams`] before this.
158
+ ///
130
159
/// If the entity despawns then the request gets cancelled unless you used
131
160
/// [`Self::detach`] before calling this.
132
161
pub fn store ( self , target : Entity ) {
133
- self . commands . add ( AddOperation :: new (
162
+ self . commands . add ( AddImpulse :: new (
134
163
self . session ,
135
164
StoreResponse :: < Response > :: new ( target) ,
136
165
) ) ;
166
+
167
+ let stream_targets = Streams :: collect_streams (
168
+ self . source , target, self . commands ,
169
+ ) ;
170
+ self . commands . entity ( self . source ) . insert ( stream_targets) ;
137
171
}
138
172
139
- /// Push the response to the back of a [`Storage<Vec<T>>`] component in an
173
+ /// Collect the stream data into [`Collection<T>`] components in the
174
+ /// specified target, one collection for each stream data type. You must
175
+ /// still decide what to do with the final response data.
176
+ #[ must_use]
177
+ pub fn collect_streams ( self , target : Entity ) -> Impulse < ' w , ' s , ' a , Response , ( ) > {
178
+ let stream_targets = Streams :: collect_streams (
179
+ self . source , target, self . commands ,
180
+ ) ;
181
+ self . commands . entity ( self . source ) . insert ( stream_targets) ;
182
+
183
+ Impulse {
184
+ source : self . source ,
185
+ session : self . session ,
186
+ commands : self . commands ,
187
+ _ignore : Default :: default ( ) ,
188
+ }
189
+ }
190
+
191
+ /// Push the response to the back of a [`Collection<T>`] component in an
192
+ /// entity.
193
+ ///
194
+ /// Similar to [`Self::store`] this will also collect streams into this
140
195
/// entity.
141
196
///
142
197
/// If the entity despawns then the request gets cancelled unless you used
143
198
/// [`Self::detach`] before calling this.
144
199
pub fn push ( self , target : Entity ) {
145
- self . commands . add ( AddOperation :: new (
200
+ self . commands . add ( AddImpulse :: new (
146
201
self . session ,
147
- PushResponse :: < Response > :: new ( target) ,
202
+ PushResponse :: < Response > :: new ( target, false ) ,
148
203
) ) ;
204
+
205
+ let stream_targets = Streams :: collect_streams (
206
+ self . source , target, self . commands ,
207
+ ) ;
208
+ self . commands . entity ( self . source ) . insert ( stream_targets) ;
149
209
}
150
210
151
- // TODO(@mxgrey): Offer an on_cancel method that lets users provide a
152
- // callback to be triggered when a cancellation happens.
211
+ // TODO(@mxgrey): Consider offering ways for users to respond to cancellations.
212
+ // For example, offer an on_cancel method that lets users provide a callback
213
+ // to be triggered when a cancellation happens. Or focus on terminal impulses,
214
+ // like offer store_or_else(~), push_or_else(~) etc which accept a callback
215
+ // that will be triggered after a cancellation.
153
216
}
154
217
155
218
impl < ' w , ' s , ' a , Response , Streams > Impulse < ' w , ' s , ' a , Response , Streams >
156
219
where
157
220
Response : Bundle ,
158
221
{
159
- /// Insert the response as a bundle in the specified entity.
222
+ /// Insert the response as a bundle in the specified entity. Stream data
223
+ /// will be dropped unless you use [`Self::collect_streams`] before this.
160
224
///
161
225
/// If the entity despawns then the request gets cancelled unless you used
162
226
/// [`Self::detach`] before calling this.
@@ -173,9 +237,11 @@ impl<'w, 's, 'a, Response, Streams> Impulse<'w, 's, 'a, Response, Streams>
173
237
where
174
238
Response : Event ,
175
239
{
176
- /// Send the response out as an event once it is ready. Using this will also
177
- /// effectively [detach](Self::detach) the impulse.
178
- pub fn send ( self ) {
240
+ /// Send the response out as an event once it is ready. Stream data will be
241
+ /// dropped unless you use [`Self::collect_streams`] before this.
242
+ ///
243
+ /// Using this will also effectively [detach](Self::detach) the impulse.
244
+ pub fn send_event ( self ) {
179
245
180
246
}
181
247
}
@@ -192,7 +258,10 @@ pub struct Storage<T> {
192
258
pub session : Entity ,
193
259
}
194
260
195
- /// Used to collect responses from multiple impulse chains into a container.
261
+ /// Used to collect responses from multiple impulse chains into a container
262
+ /// attached to an entity.
263
+ //
264
+ // TODO(@mxgrey): Consider allowing the user to choose the container type.
196
265
#[ derive( Component ) ]
197
266
pub struct Collection < T > {
198
267
/// The items that have been collected.
0 commit comments