@@ -37,6 +37,7 @@ namespace FIREBASE_NAMESPACE {
37
37
// / @cond FIREBASE_APP_INTERNAL
38
38
namespace detail {
39
39
class FutureApiInterface ;
40
+ class CompletionCallbackHandle ;
40
41
} // namespace detail
41
42
// / @endcond
42
43
@@ -84,6 +85,12 @@ class FutureBase {
84
85
typedef void (*CompletionCallback)(const FutureBase& result_data,
85
86
void * user_data);
86
87
88
+ #if defined(INTERNAL_EXPERIMENTAL)
89
+ // / Handle, representing a completion callback, that can be passed to
90
+ // / RemoveOnCompletion.
91
+ using CompletionCallbackHandle = detail::CompletionCallbackHandle;
92
+ #endif
93
+
87
94
// / Construct an untyped future.
88
95
FutureBase ();
89
96
@@ -139,34 +146,113 @@ class FutureBase {
139
146
// / pending. Cast is required since GetFutureResult() returns void*.
140
147
const void * result_void () const ;
141
148
142
- // / Register a callback that will be called at most once, when the future is
143
- // / completed.
149
+ // / Register a single callback that will be called at most once, when the
150
+ // / future is completed.
151
+ // /
152
+ // / If you call any OnCompletion() method more than once on the same future,
153
+ // / only the most recent callback you registered with OnCompletion() will be
154
+ // / called.
155
+ #if defined(INTERNAL_EXPERIMENTAL)
156
+ // / However completions registered with AddCompletion() will still be
157
+ // / called even if there is a subsequent call to OnCompletion().
144
158
// /
145
- // / If you call any OnCompletion() method more than once, only the most recent
146
- // / callback you registered will be called.
159
+ // / When the future completes, first the most recent callback registered with
160
+ // / OnCompletion(), if any, will be called; then all callbacks registered with
161
+ // / AddCompletion() will be called, in the order that they were registered.
162
+ #endif
147
163
// /
148
164
// / When your callback is called, the user_data that you supplied here will be
149
165
// / passed back as the second parameter.
150
166
// /
151
167
// / @param[in] callback Function pointer to your callback.
152
168
// / @param[in] user_data Optional user data. We will pass this back to your
153
169
// / callback.
154
- void OnCompletion (CompletionCallback callback, void * user_data) const ;
170
+ #if defined(INTERNAL_EXPERIMENTAL)
171
+ // / @return A handle that can be passed to RemoveOnCompletion.
172
+ CompletionCallbackHandle
173
+ #else
174
+ void
175
+ #endif
176
+ OnCompletion (CompletionCallback callback, void * user_data) const ;
177
+
178
+ #if defined(FIREBASE_USE_STD_FUNCTION) || defined(DOXYGEN)
179
+ // / Register a single callback that will be called at most once, when the
180
+ // / future is completed.
181
+ // /
182
+ // / If you call any OnCompletion() method more than once on the same future,
183
+ // / only the most recent callback you registered with OnCompletion() will be
184
+ // / called.
185
+ #if defined(INTERNAL_EXPERIMENTAL)
186
+ // / However completions registered with AddCompletion() will still be
187
+ // / called even if there is a subsequent call to OnCompletion().
188
+ // /
189
+ // / When the future completes, first the most recent callback registered with
190
+ // / OnCompletion(), if any, will be called; then all callbacks registered with
191
+ // / AddCompletion() will be called, in the order that they were registered.
192
+ #endif
193
+ // /
194
+ // / @param[in] callback Function or lambda to call.
195
+ // /
196
+ // / @note This method is not available when using STLPort on Android, as
197
+ // / `std::function` is not supported on STLPort.
198
+ #if defined(INTERNAL_EXPERIMENTAL)
199
+ // / @return A handle that can be passed to RemoveOnCompletion.
200
+ CompletionCallbackHandle
201
+ #else
202
+ void
203
+ #endif
204
+ OnCompletion (std::function<void (const FutureBase&)> callback) const ;
205
+ #endif // defined(FIREBASE_USE_STD_FUNCTION) || defined(DOXYGEN)
206
+
207
+ #if defined(INTERNAL_EXPERIMENTAL)
208
+ // / Like OnCompletion, but allows adding multiple callbacks.
209
+ // /
210
+ // / If you call AddCompletion() more than once, all of the completions that
211
+ // / you register will be called, when the future is completed. However, any
212
+ // / callbacks which were subsequently removed by calling RemoveOnCompletion
213
+ // / will not be called.
214
+ // /
215
+ // / When the future completes, first the most recent callback registered with
216
+ // / OnCompletion(), if any, will be called; then all callbacks registered with
217
+ // / AddCompletion() will be called, in the order that they were registered.
218
+ // /
219
+ // / @param[in] callback Function pointer to your callback.
220
+ // / @param[in] user_data Optional user data. We will pass this back to your
221
+ // / callback.
222
+ // / @return A handle that can be passed to RemoveOnCompletion.
223
+ CompletionCallbackHandle
224
+ AddOnCompletion (CompletionCallback callback, void * user_data) const ;
155
225
156
226
#if defined(FIREBASE_USE_STD_FUNCTION) || defined(DOXYGEN)
157
- // / Register a callback that will be called at most once, when the future is
158
- // / completed.
227
+ // / Like OnCompletion, but allows adding multiple callbacks.
159
228
// /
160
- // / If you call any OnCompletion() method more than once, only the most recent
161
- // / callback you registered will be called.
229
+ // / If you call AddCompletion() more than once, all of the completions that
230
+ // / you register will be called, when the future is completed. However, any
231
+ // / callbacks which were subsequently removed by calling RemoveOnCompletion
232
+ // / will not be called.
233
+ // /
234
+ // / When the future completes, first the most recent callback registered with
235
+ // / OnCompletion(), if any, will be called; then all callbacks registered with
236
+ // / AddCompletion() will be called, in the order that they were registered.
162
237
// /
163
238
// / @param[in] callback Function or lambda to call.
239
+ // / @return A handle that can be passed to RemoveOnCompletion.
164
240
// /
165
241
// / @note This method is not available when using STLPort on Android, as
166
242
// / `std::function` is not supported on STLPort.
167
- void OnCompletion (std::function<void (const FutureBase&)> callback) const ;
243
+ CompletionCallbackHandle AddOnCompletion (
244
+ std::function<void (const FutureBase&)> callback) const ;
245
+
168
246
#endif // defined(FIREBASE_USE_STD_FUNCTION) || defined(DOXYGEN)
169
247
248
+ // / Unregisters a callback that was previously registered with
249
+ // / AddOnCompletion or OnCompletion.
250
+ // /
251
+ // / @param[in] completion_handle The return value of a previous call to
252
+ // / AddOnCompletion or OnCompletion.
253
+ void RemoveOnCompletion (CompletionCallbackHandle completion_handle) const ;
254
+ #endif // defined(INTERNAL_EXPERIMENTAL)
255
+
170
256
// / Returns true if the two Futures reference the same result.
171
257
bool operator ==(const FutureBase& rhs) const {
172
258
return api_ == rhs.api_ && handle_ == rhs.handle_ ;
@@ -282,11 +368,11 @@ class Future : public FutureBase {
282
368
return static_cast <const ResultType*>(result_void ());
283
369
}
284
370
285
- // / Register a callback that will be called at most once, when the future is
286
- // / completed.
371
+ // / Register a single callback that will be called at most once, when the
372
+ // / future is completed.
287
373
// /
288
- // / If you call any OnCompletion() method more than once, only the most recent
289
- // / callback you registered will be called.
374
+ // / If you call any OnCompletion() method more than once on the same future,
375
+ // / only the most recent callback you registered will be called.
290
376
// /
291
377
// / When your callback is called, the user_data that you supplied here will be
292
378
// / passed back as the second parameter.
@@ -298,17 +384,20 @@ class Future : public FutureBase {
298
384
// / @note This is the same callback as FutureBase::OnCompletion(), so you
299
385
// / can't expect to set both and have both run; again, only the most recently
300
386
// / registered one will run.
301
- void OnCompletion (TypedCompletionCallback callback, void * user_data) const {
302
- FutureBase::OnCompletion (reinterpret_cast <CompletionCallback>(callback),
303
- user_data);
304
- }
387
+ #if defined(INTERNAL_EXPERIMENTAL)
388
+ // / @return A handle that can be passed to RemoveOnCompletion.
389
+ inline CompletionCallbackHandle
390
+ #else
391
+ inline void
392
+ #endif
393
+ OnCompletion (TypedCompletionCallback callback, void * user_data) const ;
305
394
306
395
#if defined(FIREBASE_USE_STD_FUNCTION) || defined(DOXYGEN)
307
- // / Register a callback that will be called at most once, when the future is
308
- // / completed.
396
+ // / Register a single callback that will be called at most once, when the
397
+ // / future is completed.
309
398
// /
310
- // / If you call any OnCompletion() method more than once, only the most recent
311
- // / callback you registered will be called.
399
+ // / If you call any OnCompletion() method more than once on the same future,
400
+ // / only the most recent callback you registered will be called.
312
401
// /
313
402
// / @param[in] callback Function or lambda to call.
314
403
// /
@@ -318,12 +407,56 @@ class Future : public FutureBase {
318
407
// / @note This is the same callback as FutureBase::OnCompletion(), so you
319
408
// / can't expect to set both and have both run; again, only the most recently
320
409
// / registered one will run.
321
- void OnCompletion (
322
- std::function<void (const Future<ResultType>&)> callback) const {
323
- FutureBase::OnCompletion (
324
- *reinterpret_cast <std::function<void (const FutureBase&)>*>(&callback));
325
- }
410
+ #if defined(INTERNAL_EXPERIMENTAL)
411
+ // / @return A handle that can be passed to RemoveOnCompletion.
412
+ inline CompletionCallbackHandle
413
+ #else
414
+ inline void
415
+ #endif
416
+ OnCompletion (std::function<void (const Future<ResultType>&)> callback) const ;
417
+ #endif // defined(FIREBASE_USE_STD_FUNCTION) || defined(DOXYGEN)
418
+
419
+ #if defined(INTERNAL_EXPERIMENTAL)
420
+ // / Like OnCompletion, but allows adding multiple callbacks.
421
+ // /
422
+ // / If you call AddCompletion() more than once, all of the completions that
423
+ // / you register will be called, when the future is completed. However, any
424
+ // / callbacks which were subsequently removed by calling RemoveOnCompletion
425
+ // / will not be called.
426
+ // /
427
+ // / When the future completes, first the most recent callback registered with
428
+ // / OnCompletion(), if any, will be called; then all callbacks registered with
429
+ // / AddCompletion() will be called, in the order that they were registered.
430
+ // /
431
+ // / @param[in] callback Function pointer to your callback.
432
+ // / @param[in] user_data Optional user data. We will pass this back to your
433
+ // / callback.
434
+ // / @return A handle that can be passed to RemoveOnCompletion.
435
+ inline CompletionCallbackHandle
436
+ AddOnCompletion (TypedCompletionCallback callback, void * user_data) const ;
437
+
438
+ #if defined(FIREBASE_USE_STD_FUNCTION) || defined(DOXYGEN)
439
+ // / Like OnCompletion, but allows adding multiple callbacks.
440
+ // /
441
+ // / If you call AddCompletion() more than once, all of the completions that
442
+ // / you register will be called, when the future is completed. However, any
443
+ // / callbacks which were subsequently removed by calling RemoveOnCompletion
444
+ // / will not be called.
445
+ // /
446
+ // / When the future completes, first the most recent callback registered with
447
+ // / OnCompletion(), if any, will be called; then all callbacks registered with
448
+ // / AddCompletion() will be called, in the order that they were registered.
449
+ // /
450
+ // / @param[in] callback Function or lambda to call.
451
+ // / @return A handle that can be passed to RemoveOnCompletion.
452
+ // /
453
+ // / @note This method is not available when using STLPort on Android, as
454
+ // / `std::function` is not supported on STLPort.
455
+ inline CompletionCallbackHandle
456
+ AddOnCompletion (std::function<void (const Future<ResultType>&)> callback)
457
+ const ;
326
458
#endif // defined(FIREBASE_USE_STD_FUNCTION) || defined(DOXYGEN)
459
+ #endif // defined(INTERNAL_EXPERIMENTAL)
327
460
};
328
461
329
462
// NOLINTNEXTLINE - allow namespace overridden
0 commit comments