1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.internal.util.function.pooled;
18 
19 import static com.android.internal.util.function.pooled.PooledLambdaImpl.acquire;
20 import static com.android.internal.util.function.pooled.PooledLambdaImpl.acquireConstSupplier;
21 
22 import android.os.Message;
23 
24 import com.android.internal.util.function.DecConsumer;
25 import com.android.internal.util.function.DodecConsumer;
26 import com.android.internal.util.function.HeptConsumer;
27 import com.android.internal.util.function.HexConsumer;
28 import com.android.internal.util.function.NonaConsumer;
29 import com.android.internal.util.function.OctConsumer;
30 import com.android.internal.util.function.QuadConsumer;
31 import com.android.internal.util.function.QuadPredicate;
32 import com.android.internal.util.function.QuintConsumer;
33 import com.android.internal.util.function.QuintPredicate;
34 import com.android.internal.util.function.TriConsumer;
35 import com.android.internal.util.function.TriPredicate;
36 import com.android.internal.util.function.UndecConsumer;
37 import com.android.internal.util.function.pooled.PooledLambdaImpl.LambdaType.ReturnType;
38 
39 import java.util.function.BiConsumer;
40 import java.util.function.BiPredicate;
41 import java.util.function.Consumer;
42 import java.util.function.Function;
43 import java.util.function.Supplier;
44 
45 /**
46  * A recyclable anonymous function.
47  * Allows obtaining {@link Function}s/{@link Runnable}s/{@link Supplier}s/etc. without allocating a
48  * new instance each time
49  *
50  * This exploits the mechanic that stateless lambdas (such as plain/non-bound method references)
51  * get translated into a singleton instance, making it possible to create a recyclable container
52  * ({@link PooledLambdaImpl}) holding a reference to such a singleton function, as well as
53  * (possibly partial) arguments required for its invocation.
54  *
55  * To obtain an instance, use one of the factory methods in this class.
56  *
57  * You can call {@link #recycleOnUse} to make the instance automatically recycled upon invocation,
58  * making if effectively <b>one-time use</b>.
59  * This is often the behavior you want, as it allows to not worry about manual recycling.
60  * Some notable examples: {@link android.os.Handler#post(Runnable)},
61  * {@link android.app.Activity#runOnUiThread(Runnable)}, {@link android.view.View#post(Runnable)}
62  *
63  * For factories of functions that take further arguments, the corresponding 'missing' argument's
64  * position is marked by an argument of type {@link ArgumentPlaceholder} with the type parameter
65  * corresponding to missing argument's type.
66  * You can fill the 'missing argument' spot with {@link #__()}
67  * (which is the factory function for {@link ArgumentPlaceholder})
68  *
69  * NOTE: It is highly recommended to <b>only</b> use {@code ClassName::methodName}
70  * (aka unbounded method references) as the 1st argument for any of the
71  * factories ({@code obtain*(...)}) to avoid unwanted allocations.
72  * This means <b>not</b> using:
73  * <ul>
74  *     <li>{@code someVar::methodName} or {@code this::methodName} as it captures the reference
75  *     on the left of {@code ::}, resulting in an allocation on each evaluation of such
76  *     bounded method references</li>
77  *
78  *     <li>A lambda expression, e.g. {@code () -> toString()} due to how easy it is to accidentally
79  *     capture state from outside. In the above lambda expression for example, no variable from
80  *     outer scope is explicitly mentioned, yet one is still captured due to {@code toString()}
81  *     being an equivalent of {@code this.toString()}</li>
82  * </ul>
83  *
84  * @hide
85  */
86 @SuppressWarnings({"unchecked", "unused", "WeakerAccess"})
87 public interface PooledLambda {
88 
89     /**
90      * Recycles this instance. No-op if already recycled.
91      */
recycle()92     void recycle();
93 
94     /**
95      * Makes this instance automatically {@link #recycle} itself after the first call.
96      *
97      * @return this instance for convenience
98      */
recycleOnUse()99     PooledLambda recycleOnUse();
100 
101 
102     // Factories
103 
104     /**
105      * @return {@link ArgumentPlaceholder} with the inferred type parameter value
106      */
__()107     static <R> ArgumentPlaceholder<R> __() {
108         return (ArgumentPlaceholder<R>) ArgumentPlaceholder.INSTANCE;
109     }
110 
111     /**
112      * @param typeHint the explicitly specified type of the missing argument
113      * @return {@link ArgumentPlaceholder} with the specified type parameter value
114      */
__(Class<R> typeHint)115     static <R> ArgumentPlaceholder<R> __(Class<R> typeHint) {
116         return __();
117     }
118 
119     /**
120      * Wraps the given value into a {@link PooledSupplier}
121      *
122      * @param value a value to wrap
123      * @return a pooled supplier of {@code value}
124      */
obtainSupplier(R value)125     static <R> PooledSupplier<R> obtainSupplier(R value) {
126         PooledLambdaImpl r = acquireConstSupplier(ReturnType.OBJECT);
127         r.mFunc = value;
128         return r;
129     }
130 
131     /**
132      * Wraps the given value into a {@link PooledSupplier}
133      *
134      * @param value a value to wrap
135      * @return a pooled supplier of {@code value}
136      */
obtainSupplier(int value)137     static PooledSupplier.OfInt obtainSupplier(int value) {
138         PooledLambdaImpl r = acquireConstSupplier(ReturnType.INT);
139         r.mConstValue = value;
140         return r;
141     }
142 
143     /**
144      * Wraps the given value into a {@link PooledSupplier}
145      *
146      * @param value a value to wrap
147      * @return a pooled supplier of {@code value}
148      */
obtainSupplier(long value)149     static PooledSupplier.OfLong obtainSupplier(long value) {
150         PooledLambdaImpl r = acquireConstSupplier(ReturnType.LONG);
151         r.mConstValue = value;
152         return r;
153     }
154 
155     /**
156      * Wraps the given value into a {@link PooledSupplier}
157      *
158      * @param value a value to wrap
159      * @return a pooled supplier of {@code value}
160      */
obtainSupplier(double value)161     static PooledSupplier.OfDouble obtainSupplier(double value) {
162         PooledLambdaImpl r = acquireConstSupplier(ReturnType.DOUBLE);
163         r.mConstValue = Double.doubleToRawLongBits(value);
164         return r;
165     }
166 
167     /**
168      * {@link PooledRunnable} factory
169      *
170      * @param function non-capturing lambda(typically an unbounded method reference)
171      *                 to be invoked on call
172      * @param arg1 parameter supplied to {@code function} on call
173      * @return a {@link PooledRunnable}, equivalent to lambda:
174      *         {@code () -> function(arg1) }
175      */
obtainRunnable( Consumer<? super A> function, A arg1)176     static <A> PooledRunnable obtainRunnable(
177             Consumer<? super A> function,
178             A arg1) {
179         return acquire(PooledLambdaImpl.sPool,
180                 function, 1, 0, ReturnType.VOID, arg1, null, null, null, null, null, null, null,
181                 null, null, null, null);
182     }
183 
184     /**
185      * Factory of {@link Message}s that contain an
186      * ({@link PooledLambda#recycleOnUse auto-recycling}) {@link PooledRunnable} as its
187      * {@link Message#getCallback internal callback}.
188      *
189      * The callback is equivalent to one obtainable via
190      * {@link #obtainRunnable(Consumer, Object)}
191      *
192      * Note that using this method with {@link android.os.Handler#handleMessage}
193      * is more efficient than the alternative of {@link android.os.Handler#post}
194      * with a {@link PooledRunnable} due to the lack of 2 separate synchronization points
195      * when obtaining {@link Message} and {@link PooledRunnable} from pools separately
196      *
197      * You may optionally set a {@link Message#what} for the message if you want to be
198      * able to cancel it via {@link android.os.Handler#removeMessages}, but otherwise
199      * there's no need to do so
200      *
201      * @param function non-capturing lambda(typically an unbounded method reference)
202      *                 to be invoked on call
203      * @param arg1 parameter supplied to {@code function} on call
204      * @return a {@link Message} invoking {@code function(arg1) } when handled
205      */
obtainMessage( Consumer<? super A> function, A arg1)206     static <A> Message obtainMessage(
207             Consumer<? super A> function,
208             A arg1) {
209         synchronized (Message.sPoolSync) {
210             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
211                     function, 1, 0, ReturnType.VOID, arg1, null, null, null, null, null, null, null,
212                     null, null, null, null);
213             return Message.obtain().setCallback(callback.recycleOnUse());
214         }
215     }
216 
217     /**
218      * {@link PooledRunnable} factory
219      *
220      * @param function non-capturing lambda(typically an unbounded method reference)
221      *                 to be invoked on call
222      * @param arg1 parameter supplied to {@code function} on call
223      * @param arg2 parameter supplied to {@code function} on call
224      * @return a {@link PooledRunnable}, equivalent to lambda:
225      *         {@code () -> function(arg1, arg2) }
226      */
obtainRunnable( BiConsumer<? super A, ? super B> function, A arg1, B arg2)227     static <A, B> PooledRunnable obtainRunnable(
228             BiConsumer<? super A, ? super B> function,
229             A arg1, B arg2) {
230         return acquire(PooledLambdaImpl.sPool,
231                 function, 2, 0, ReturnType.VOID, arg1, arg2, null, null, null, null, null, null,
232                 null, null, null, null);
233     }
234 
235     /**
236      * {@link PooledPredicate} factory
237      *
238      * @param function non-capturing lambda(typically an unbounded method reference)
239      *                 to be invoked on call
240      * @param arg1 placeholder for a missing argument. Use {@link #__} to get one
241      * @param arg2 parameter supplied to {@code function} on call
242      * @return a {@link PooledPredicate}, equivalent to lambda:
243      *         {@code (arg1) -> function(arg1, arg2) }
244      */
obtainPredicate( BiPredicate<? super A, ? super B> function, ArgumentPlaceholder<A> arg1, B arg2)245     static <A, B> PooledPredicate<A> obtainPredicate(
246             BiPredicate<? super A, ? super B> function,
247             ArgumentPlaceholder<A> arg1, B arg2) {
248         return acquire(PooledLambdaImpl.sPool,
249                 function, 2, 1, ReturnType.BOOLEAN, arg1, arg2, null, null, null, null, null, null,
250                 null, null, null, null);
251     }
252 
253     /**
254      * {@link PooledPredicate} factory
255      *
256      * @param function non-capturing lambda(typically an unbounded method reference)
257      *                 to be invoked on call
258      * @param arg1 placeholder for a missing argument. Use {@link #__} to get one
259      * @param arg2 parameter supplied to {@code function} on call
260      * @param arg3 parameter supplied to {@code function} on call
261      * @return a {@link PooledPredicate}, equivalent to lambda:
262      *         {@code (arg1) -> function(arg1, arg2, arg3) }
263      */
obtainPredicate( TriPredicate<? super A, ? super B, ? super C> function, ArgumentPlaceholder<A> arg1, B arg2, C arg3)264     static <A, B, C> PooledPredicate<A> obtainPredicate(
265             TriPredicate<? super A, ? super B, ? super C> function,
266             ArgumentPlaceholder<A> arg1, B arg2, C arg3) {
267         return acquire(PooledLambdaImpl.sPool,
268                 function, 3, 1, ReturnType.BOOLEAN, arg1, arg2, arg3, null, null, null, null, null,
269                 null, null, null, null);
270     }
271 
272     /**
273      * {@link PooledPredicate} factory
274      *
275      * @param function non-capturing lambda(typically an unbounded method reference)
276      *                 to be invoked on call
277      * @param arg1 placeholder for a missing argument. Use {@link #__} to get one
278      * @param arg2 parameter supplied to {@code function} on call
279      * @param arg3 parameter supplied to {@code function} on call
280      * @param arg4 parameter supplied to {@code function} on call
281      * @return a {@link PooledPredicate}, equivalent to lambda:
282      *         {@code (arg1) -> function(arg1, arg2, arg3, arg4) }
283      */
obtainPredicate( QuadPredicate<? super A, ? super B, ? super C, ? super D> function, ArgumentPlaceholder<A> arg1, B arg2, C arg3, D arg4)284     static <A, B, C, D> PooledPredicate<A> obtainPredicate(
285             QuadPredicate<? super A, ? super B, ? super C, ? super D> function,
286             ArgumentPlaceholder<A> arg1, B arg2, C arg3, D arg4) {
287         return acquire(PooledLambdaImpl.sPool,
288                 function, 4, 1, ReturnType.BOOLEAN, arg1, arg2, arg3, arg4, null, null, null, null,
289                 null, null, null, null);
290     }
291 
292     /**
293      * {@link PooledPredicate} factory
294      *
295      * @param function non-capturing lambda(typically an unbounded method reference)
296      *                 to be invoked on call
297      * @param arg1 placeholder for a missing argument. Use {@link #__} to get one
298      * @param arg2 parameter supplied to {@code function} on call
299      * @param arg3 parameter supplied to {@code function} on call
300      * @param arg4 parameter supplied to {@code function} on call
301      * @param arg5 parameter supplied to {@code function} on call
302      * @return a {@link PooledPredicate}, equivalent to lambda:
303      *         {@code (arg1) -> function(arg1, arg2, arg3, arg4, arg5) }
304      */
obtainPredicate( QuintPredicate<? super A, ? super B, ? super C, ? super D, ? super E> function, ArgumentPlaceholder<A> arg1, B arg2, C arg3, D arg4, E arg5)305     static <A, B, C, D, E> PooledPredicate<A> obtainPredicate(
306             QuintPredicate<? super A, ? super B, ? super C, ? super D, ? super E> function,
307             ArgumentPlaceholder<A> arg1, B arg2, C arg3, D arg4, E arg5) {
308         return acquire(PooledLambdaImpl.sPool,
309                 function, 5, 1, ReturnType.BOOLEAN, arg1, arg2, arg3, arg4, arg5, null, null, null,
310                 null, null, null, null);
311     }
312 
313     /**
314      * {@link PooledPredicate} factory
315      *
316      * @param function non-capturing lambda(typically an unbounded method reference)
317      *                 to be invoked on call
318      * @param arg1 parameter supplied to {@code function} on call
319      * @param arg2 placeholder for a missing argument. Use {@link #__} to get one
320      * @return a {@link PooledPredicate}, equivalent to lambda:
321      *         {@code (arg2) -> function(arg1, arg2) }
322      */
obtainPredicate( BiPredicate<? super A, ? super B> function, A arg1, ArgumentPlaceholder<B> arg2)323     static <A, B> PooledPredicate<B> obtainPredicate(
324             BiPredicate<? super A, ? super B> function,
325             A arg1, ArgumentPlaceholder<B> arg2) {
326         return acquire(PooledLambdaImpl.sPool,
327                 function, 2, 1, ReturnType.BOOLEAN, arg1, arg2, null, null, null, null, null, null,
328                 null, null, null, null);
329     }
330 
331     /**
332      * Factory of {@link Message}s that contain an
333      * ({@link PooledLambda#recycleOnUse auto-recycling}) {@link PooledRunnable} as its
334      * {@link Message#getCallback internal callback}.
335      *
336      * The callback is equivalent to one obtainable via
337      * {@link #obtainRunnable(BiConsumer, Object, Object)}
338      *
339      * Note that using this method with {@link android.os.Handler#handleMessage}
340      * is more efficient than the alternative of {@link android.os.Handler#post}
341      * with a {@link PooledRunnable} due to the lack of 2 separate synchronization points
342      * when obtaining {@link Message} and {@link PooledRunnable} from pools separately
343      *
344      * You may optionally set a {@link Message#what} for the message if you want to be
345      * able to cancel it via {@link android.os.Handler#removeMessages}, but otherwise
346      * there's no need to do so
347      *
348      * @param function non-capturing lambda(typically an unbounded method reference)
349      *                 to be invoked on call
350      * @param arg1 parameter supplied to {@code function} on call
351      * @param arg2 parameter supplied to {@code function} on call
352      * @return a {@link Message} invoking {@code function(arg1, arg2) } when handled
353      */
obtainMessage( BiConsumer<? super A, ? super B> function, A arg1, B arg2)354     static <A, B> Message obtainMessage(
355             BiConsumer<? super A, ? super B> function,
356             A arg1, B arg2) {
357         synchronized (Message.sPoolSync) {
358             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
359                     function, 2, 0, ReturnType.VOID, arg1, arg2, null, null, null, null, null, null,
360                     null, null, null, null);
361             return Message.obtain().setCallback(callback.recycleOnUse());
362         }
363     }
364 
365     /**
366      * {@link PooledRunnable} factory
367      *
368      * @param function non-capturing lambda(typically an unbounded method reference)
369      *                 to be invoked on call
370      * @param arg1 parameter supplied to {@code function} on call
371      * @param arg2 parameter supplied to {@code function} on call
372      * @param arg3 parameter supplied to {@code function} on call
373      * @return a {@link PooledRunnable}, equivalent to lambda:
374      *         {@code () -> function(arg1, arg2, arg3) }
375      */
obtainRunnable( TriConsumer<? super A, ? super B, ? super C> function, A arg1, B arg2, C arg3)376     static <A, B, C> PooledRunnable obtainRunnable(
377             TriConsumer<? super A, ? super B, ? super C> function,
378             A arg1, B arg2, C arg3) {
379         return acquire(PooledLambdaImpl.sPool,
380                 function, 3, 0, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null, null,
381                 null, null, null, null);
382     }
383 
384     /**
385      * Factory of {@link Message}s that contain an
386      * ({@link PooledLambda#recycleOnUse auto-recycling}) {@link PooledRunnable} as its
387      * {@link Message#getCallback internal callback}.
388      *
389      * The callback is equivalent to one obtainable via
390      * {@link #obtainRunnable(TriConsumer, Object, Object, Object)}
391      *
392      * Note that using this method with {@link android.os.Handler#handleMessage}
393      * is more efficient than the alternative of {@link android.os.Handler#post}
394      * with a {@link PooledRunnable} due to the lack of 2 separate synchronization points
395      * when obtaining {@link Message} and {@link PooledRunnable} from pools separately
396      *
397      * You may optionally set a {@link Message#what} for the message if you want to be
398      * able to cancel it via {@link android.os.Handler#removeMessages}, but otherwise
399      * there's no need to do so
400      *
401      * @param function non-capturing lambda(typically an unbounded method reference)
402      *                 to be invoked on call
403      * @param arg1 parameter supplied to {@code function} on call
404      * @param arg2 parameter supplied to {@code function} on call
405      * @param arg3 parameter supplied to {@code function} on call
406      * @return a {@link Message} invoking {@code function(arg1, arg2, arg3) } when handled
407      */
obtainMessage( TriConsumer<? super A, ? super B, ? super C> function, A arg1, B arg2, C arg3)408     static <A, B, C> Message obtainMessage(
409             TriConsumer<? super A, ? super B, ? super C> function,
410             A arg1, B arg2, C arg3) {
411         synchronized (Message.sPoolSync) {
412             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
413                     function, 3, 0, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null, null,
414                     null, null, null, null);
415             return Message.obtain().setCallback(callback.recycleOnUse());
416         }
417     }
418 
419     /**
420      * {@link PooledRunnable} factory
421      *
422      * @param function non-capturing lambda(typically an unbounded method reference)
423      *                 to be invoked on call
424      * @param arg1 parameter supplied to {@code function} on call
425      * @param arg2 parameter supplied to {@code function} on call
426      * @param arg3 parameter supplied to {@code function} on call
427      * @param arg4 parameter supplied to {@code function} on call
428      * @return a {@link PooledRunnable}, equivalent to lambda:
429      *         {@code () -> function(arg1, arg2, arg3, arg4) }
430      */
obtainRunnable( QuadConsumer<? super A, ? super B, ? super C, ? super D> function, A arg1, B arg2, C arg3, D arg4)431     static <A, B, C, D> PooledRunnable obtainRunnable(
432             QuadConsumer<? super A, ? super B, ? super C, ? super D> function,
433             A arg1, B arg2, C arg3, D arg4) {
434         return acquire(PooledLambdaImpl.sPool,
435                 function, 4, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null,
436                 null, null, null, null);
437     }
438 
439     /**
440      * Factory of {@link Message}s that contain an
441      * ({@link PooledLambda#recycleOnUse auto-recycling}) {@link PooledRunnable} as its
442      * {@link Message#getCallback internal callback}.
443      *
444      * The callback is equivalent to one obtainable via
445      * {@link #obtainRunnable(QuadConsumer, Object, Object, Object, Object)}
446      *
447      * Note that using this method with {@link android.os.Handler#handleMessage}
448      * is more efficient than the alternative of {@link android.os.Handler#post}
449      * with a {@link PooledRunnable} due to the lack of 2 separate synchronization points
450      * when obtaining {@link Message} and {@link PooledRunnable} from pools separately
451      *
452      * You may optionally set a {@link Message#what} for the message if you want to be
453      * able to cancel it via {@link android.os.Handler#removeMessages}, but otherwise
454      * there's no need to do so
455      *
456      * @param function non-capturing lambda(typically an unbounded method reference)
457      *                 to be invoked on call
458      * @param arg1 parameter supplied to {@code function} on call
459      * @param arg2 parameter supplied to {@code function} on call
460      * @param arg3 parameter supplied to {@code function} on call
461      * @param arg4 parameter supplied to {@code function} on call
462      * @return a {@link Message} invoking {@code function(arg1, arg2, arg3, arg4) } when handled
463      */
obtainMessage( QuadConsumer<? super A, ? super B, ? super C, ? super D> function, A arg1, B arg2, C arg3, D arg4)464     static <A, B, C, D> Message obtainMessage(
465             QuadConsumer<? super A, ? super B, ? super C, ? super D> function,
466             A arg1, B arg2, C arg3, D arg4) {
467         synchronized (Message.sPoolSync) {
468             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
469                     function, 4, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null,
470                     null, null, null, null);
471             return Message.obtain().setCallback(callback.recycleOnUse());
472         }
473     }
474 
475     /**
476      * {@link PooledRunnable} factory
477      *
478      * @param function non-capturing lambda(typically an unbounded method reference)
479      *                 to be invoked on call
480      * @param arg1 parameter supplied to {@code function} on call
481      * @param arg2 parameter supplied to {@code function} on call
482      * @param arg3 parameter supplied to {@code function} on call
483      * @param arg4 parameter supplied to {@code function} on call
484      * @param arg5 parameter supplied to {@code function} on call
485      * @return a {@link PooledRunnable}, equivalent to lambda:
486      *         {@code () -> function(arg1, arg2, arg3, arg4, arg5) }
487      */
obtainRunnable( QuintConsumer<? super A, ? super B, ? super C, ? super D, ? super E> function, A arg1, B arg2, C arg3, D arg4, E arg5)488     static <A, B, C, D, E> PooledRunnable obtainRunnable(
489             QuintConsumer<? super A, ? super B, ? super C, ? super D, ? super E> function,
490             A arg1, B arg2, C arg3, D arg4, E arg5) {
491         return acquire(PooledLambdaImpl.sPool,
492                 function, 5, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, null, null, null,
493                 null, null, null, null);
494     }
495 
496     /**
497      * Factory of {@link Message}s that contain an
498      * ({@link PooledLambda#recycleOnUse auto-recycling}) {@link PooledRunnable} as its
499      * {@link Message#getCallback internal callback}.
500      *
501      * The callback is equivalent to one obtainable via
502      * {@link #obtainRunnable(QuintConsumer, Object, Object, Object, Object, Object)}
503      *
504      * Note that using this method with {@link android.os.Handler#handleMessage}
505      * is more efficient than the alternative of {@link android.os.Handler#post}
506      * with a {@link PooledRunnable} due to the lack of 2 separate synchronization points
507      * when obtaining {@link Message} and {@link PooledRunnable} from pools separately
508      *
509      * You may optionally set a {@link Message#what} for the message if you want to be
510      * able to cancel it via {@link android.os.Handler#removeMessages}, but otherwise
511      * there's no need to do so
512      *
513      * @param function non-capturing lambda(typically an unbounded method reference)
514      *                 to be invoked on call
515      * @param arg1 parameter supplied to {@code function} on call
516      * @param arg2 parameter supplied to {@code function} on call
517      * @param arg3 parameter supplied to {@code function} on call
518      * @param arg4 parameter supplied to {@code function} on call
519      * @param arg5 parameter supplied to {@code function} on call
520      * @return a {@link Message} invoking {@code function(arg1, arg2, arg3, arg4, arg5) } when
521      *         handled
522      */
obtainMessage( QuintConsumer<? super A, ? super B, ? super C, ? super D, ? super E> function, A arg1, B arg2, C arg3, D arg4, E arg5)523     static <A, B, C, D, E> Message obtainMessage(
524             QuintConsumer<? super A, ? super B, ? super C, ? super D, ? super E> function,
525             A arg1, B arg2, C arg3, D arg4, E arg5) {
526         synchronized (Message.sPoolSync) {
527             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
528                     function, 5, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, null, null, null,
529                     null, null, null, null);
530             return Message.obtain().setCallback(callback.recycleOnUse());
531         }
532     }
533 
534     /**
535      * {@link PooledRunnable} factory
536      *
537      * @param function non-capturing lambda(typically an unbounded method reference)
538      *                 to be invoked on call
539      * @param arg1 parameter supplied to {@code function} on call
540      * @param arg2 parameter supplied to {@code function} on call
541      * @param arg3 parameter supplied to {@code function} on call
542      * @param arg4 parameter supplied to {@code function} on call
543      * @param arg5 parameter supplied to {@code function} on call
544      * @param arg6 parameter supplied to {@code function} on call
545      * @return a {@link PooledRunnable}, equivalent to lambda:
546      *         {@code () -> function(arg1, arg2, arg3, arg4, arg5, arg6) }
547      */
obtainRunnable( HexConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6)548     static <A, B, C, D, E, F> PooledRunnable obtainRunnable(
549             HexConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F> function,
550             A arg1, B arg2, C arg3, D arg4, E arg5, F arg6) {
551         return acquire(PooledLambdaImpl.sPool,
552                 function, 6, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, null, null,
553                 null, null, null, null);
554     }
555 
556     /**
557      * Factory of {@link Message}s that contain an
558      * ({@link PooledLambda#recycleOnUse auto-recycling}) {@link PooledRunnable} as its
559      * {@link Message#getCallback internal callback}.
560      *
561      * The callback is equivalent to one obtainable via
562      * {@link #obtainRunnable(QuintConsumer, Object, Object, Object, Object, Object)}
563      *
564      * Note that using this method with {@link android.os.Handler#handleMessage}
565      * is more efficient than the alternative of {@link android.os.Handler#post}
566      * with a {@link PooledRunnable} due to the lack of 2 separate synchronization points
567      * when obtaining {@link Message} and {@link PooledRunnable} from pools separately
568      *
569      * You may optionally set a {@link Message#what} for the message if you want to be
570      * able to cancel it via {@link android.os.Handler#removeMessages}, but otherwise
571      * there's no need to do so
572      *
573      * @param function non-capturing lambda(typically an unbounded method reference)
574      *                 to be invoked on call
575      * @param arg1 parameter supplied to {@code function} on call
576      * @param arg2 parameter supplied to {@code function} on call
577      * @param arg3 parameter supplied to {@code function} on call
578      * @param arg4 parameter supplied to {@code function} on call
579      * @param arg5 parameter supplied to {@code function} on call
580      * @param arg6 parameter supplied to {@code function} on call
581      * @return a {@link Message} invoking {@code function(arg1, arg2, arg3, arg4, arg5, arg6) }
582      *         when handled
583      */
obtainMessage( HexConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6)584     static <A, B, C, D, E, F> Message obtainMessage(
585             HexConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F> function,
586             A arg1, B arg2, C arg3, D arg4, E arg5, F arg6) {
587         synchronized (Message.sPoolSync) {
588             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
589                     function, 6, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, null, null,
590                     null, null, null, null);
591             return Message.obtain().setCallback(callback.recycleOnUse());
592         }
593     }
594 
595     /**
596      * {@link PooledRunnable} factory
597      *
598      * @param function non-capturing lambda(typically an unbounded method reference)
599      *                 to be invoked on call
600      * @param arg1 parameter supplied to {@code function} on call
601      * @param arg2 parameter supplied to {@code function} on call
602      * @param arg3 parameter supplied to {@code function} on call
603      * @param arg4 parameter supplied to {@code function} on call
604      * @param arg5 parameter supplied to {@code function} on call
605      * @param arg6 parameter supplied to {@code function} on call
606      * @param arg7 parameter supplied to {@code function} on call
607      * @return a {@link PooledRunnable}, equivalent to lambda:
608      *         {@code () -> function(arg1, arg2, arg3, arg4, arg5, arg6, arg7) }
609      */
obtainRunnable( HeptConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F, ? super G> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7)610     static <A, B, C, D, E, F, G> PooledRunnable obtainRunnable(
611             HeptConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
612                     ? super G> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7) {
613         return acquire(PooledLambdaImpl.sPool,
614                 function, 7, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, null,
615                 null, null, null, null);
616     }
617 
618     /**
619      * Factory of {@link Message}s that contain an
620      * ({@link PooledLambda#recycleOnUse auto-recycling}) {@link PooledRunnable} as its
621      * {@link Message#getCallback internal callback}.
622      *
623      * The callback is equivalent to one obtainable via
624      * {@link #obtainRunnable(QuintConsumer, Object, Object, Object, Object, Object)}
625      *
626      * Note that using this method with {@link android.os.Handler#handleMessage}
627      * is more efficient than the alternative of {@link android.os.Handler#post}
628      * with a {@link PooledRunnable} due to the lack of 2 separate synchronization points
629      * when obtaining {@link Message} and {@link PooledRunnable} from pools separately
630      *
631      * You may optionally set a {@link Message#what} for the message if you want to be
632      * able to cancel it via {@link android.os.Handler#removeMessages}, but otherwise
633      * there's no need to do so
634      *
635      * @param function non-capturing lambda(typically an unbounded method reference)
636      *                 to be invoked on call
637      * @param arg1 parameter supplied to {@code function} on call
638      * @param arg2 parameter supplied to {@code function} on call
639      * @param arg3 parameter supplied to {@code function} on call
640      * @param arg4 parameter supplied to {@code function} on call
641      * @param arg5 parameter supplied to {@code function} on call
642      * @param arg6 parameter supplied to {@code function} on call
643      * @param arg7 parameter supplied to {@code function} on call
644      * @return a {@link Message} invoking {@code function(arg1, arg2, arg3, arg4, arg5, arg6,
645      * arg7) } when handled
646      */
obtainMessage( HeptConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F, ? super G> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7)647     static <A, B, C, D, E, F, G> Message obtainMessage(
648             HeptConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
649                     ? super G> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7) {
650         synchronized (Message.sPoolSync) {
651             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
652                     function, 7, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, null,
653                     null, null, null, null);
654             return Message.obtain().setCallback(callback.recycleOnUse());
655         }
656     }
657 
658     /**
659      * {@link PooledRunnable} factory
660      *
661      * @param function non-capturing lambda(typically an unbounded method reference)
662      *                 to be invoked on call
663      * @param arg1 parameter supplied to {@code function} on call
664      * @param arg2 parameter supplied to {@code function} on call
665      * @param arg3 parameter supplied to {@code function} on call
666      * @param arg4 parameter supplied to {@code function} on call
667      * @param arg5 parameter supplied to {@code function} on call
668      * @param arg6 parameter supplied to {@code function} on call
669      * @param arg7 parameter supplied to {@code function} on call
670      * @param arg8 parameter supplied to {@code function} on call
671      * @return a {@link PooledRunnable}, equivalent to lambda:
672      *         {@code () -> function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) }
673      */
obtainRunnable( OctConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F, ? super G, ? super H> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8)674     static <A, B, C, D, E, F, G, H> PooledRunnable obtainRunnable(
675             OctConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F, ? super G,
676                     ? super H> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7,
677             H arg8) {
678         return acquire(PooledLambdaImpl.sPool,
679                 function, 8, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
680                 null, null, null, null);
681     }
682 
683     /**
684      * Factory of {@link Message}s that contain an
685      * ({@link PooledLambda#recycleOnUse auto-recycling}) {@link PooledRunnable} as its
686      * {@link Message#getCallback internal callback}.
687      *
688      * The callback is equivalent to one obtainable via
689      * {@link #obtainRunnable(QuintConsumer, Object, Object, Object, Object, Object)}
690      *
691      * Note that using this method with {@link android.os.Handler#handleMessage}
692      * is more efficient than the alternative of {@link android.os.Handler#post}
693      * with a {@link PooledRunnable} due to the lack of 2 separate synchronization points
694      * when obtaining {@link Message} and {@link PooledRunnable} from pools separately
695      *
696      * You may optionally set a {@link Message#what} for the message if you want to be
697      * able to cancel it via {@link android.os.Handler#removeMessages}, but otherwise
698      * there's no need to do so
699      *
700      * @param function non-capturing lambda(typically an unbounded method reference)
701      *                 to be invoked on call
702      * @param arg1 parameter supplied to {@code function} on call
703      * @param arg2 parameter supplied to {@code function} on call
704      * @param arg3 parameter supplied to {@code function} on call
705      * @param arg4 parameter supplied to {@code function} on call
706      * @param arg5 parameter supplied to {@code function} on call
707      * @param arg6 parameter supplied to {@code function} on call
708      * @param arg7 parameter supplied to {@code function} on call
709      * @param arg8 parameter supplied to {@code function} on call
710      * @return a {@link Message} invoking {@code function(arg1, arg2, arg3, arg4, arg5, arg6,
711      * arg7, arg8) } when handled
712      */
obtainMessage( OctConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F, ? super G, ? super H> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8)713     static <A, B, C, D, E, F, G, H> Message obtainMessage(
714             OctConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F, ? super G,
715                     ? super H> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7,
716             H arg8) {
717         synchronized (Message.sPoolSync) {
718             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
719                     function, 8, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
720                     null, null, null, null);
721             return Message.obtain().setCallback(callback.recycleOnUse());
722         }
723     }
724 
725     /**
726      * {@link PooledRunnable} factory
727      *
728      * @param function non-capturing lambda(typically an unbounded method reference)
729      *                 to be invoked on call
730      * @param arg1 parameter supplied to {@code function} on call
731      * @param arg2 parameter supplied to {@code function} on call
732      * @param arg3 parameter supplied to {@code function} on call
733      * @param arg4 parameter supplied to {@code function} on call
734      * @param arg5 parameter supplied to {@code function} on call
735      * @param arg6 parameter supplied to {@code function} on call
736      * @param arg7 parameter supplied to {@code function} on call
737      * @param arg8 parameter supplied to {@code function} on call
738      * @param arg9 parameter supplied to {@code function} on call
739      * @return a {@link PooledRunnable}, equivalent to lambda:
740      *         {@code () -> function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) }
741      */
obtainRunnable( NonaConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F, ? super G, ? super H, ? super I> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9)742     static <A, B, C, D, E, F, G, H, I> PooledRunnable obtainRunnable(
743             NonaConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
744                     ? super G, ? super H, ? super I> function, A arg1, B arg2, C arg3, D arg4,
745             E arg5, F arg6, G arg7, H arg8, I arg9) {
746         return acquire(PooledLambdaImpl.sPool,
747                 function, 9, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
748                 arg9, null, null, null);
749     }
750 
751     /**
752      * Factory of {@link Message}s that contain an
753      * ({@link PooledLambda#recycleOnUse auto-recycling}) {@link PooledRunnable} as its
754      * {@link Message#getCallback internal callback}.
755      *
756      * The callback is equivalent to one obtainable via
757      * {@link #obtainRunnable(QuintConsumer, Object, Object, Object, Object, Object)}
758      *
759      * Note that using this method with {@link android.os.Handler#handleMessage}
760      * is more efficient than the alternative of {@link android.os.Handler#post}
761      * with a {@link PooledRunnable} due to the lack of 2 separate synchronization points
762      * when obtaining {@link Message} and {@link PooledRunnable} from pools separately
763      *
764      * You may optionally set a {@link Message#what} for the message if you want to be
765      * able to cancel it via {@link android.os.Handler#removeMessages}, but otherwise
766      * there's no need to do so
767      *
768      * @param function non-capturing lambda(typically an unbounded method reference)
769      *                 to be invoked on call
770      * @param arg1 parameter supplied to {@code function} on call
771      * @param arg2 parameter supplied to {@code function} on call
772      * @param arg3 parameter supplied to {@code function} on call
773      * @param arg4 parameter supplied to {@code function} on call
774      * @param arg5 parameter supplied to {@code function} on call
775      * @param arg6 parameter supplied to {@code function} on call
776      * @param arg7 parameter supplied to {@code function} on call
777      * @param arg8 parameter supplied to {@code function} on call
778      * @param arg9 parameter supplied to {@code function} on call
779      * @return a {@link Message} invoking {@code function(arg1, arg2, arg3, arg4, arg5, arg6,
780      * arg7, arg8, arg9) } when handled
781      */
obtainMessage( NonaConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F, ? super G, ? super H, ? super I> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9)782     static <A, B, C, D, E, F, G, H, I> Message obtainMessage(
783             NonaConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
784                     ? super G, ? super H, ? super I> function, A arg1, B arg2, C arg3, D arg4,
785             E arg5, F arg6, G arg7, H arg8, I arg9) {
786         synchronized (Message.sPoolSync) {
787             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
788                     function, 9, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
789                     arg9, null, null, null);
790             return Message.obtain().setCallback(callback.recycleOnUse());
791         }
792     }
793 
794     /**
795      * {@link PooledRunnable} factory
796      *
797      * @param function non-capturing lambda(typically an unbounded method reference)
798      *                 to be invoked on call
799      * @param arg1 parameter supplied to {@code function} on call
800      * @param arg2 parameter supplied to {@code function} on call
801      * @param arg3 parameter supplied to {@code function} on call
802      * @param arg4 parameter supplied to {@code function} on call
803      * @param arg5 parameter supplied to {@code function} on call
804      * @param arg6 parameter supplied to {@code function} on call
805      * @param arg7 parameter supplied to {@code function} on call
806      * @param arg8 parameter supplied to {@code function} on call
807      * @param arg9 parameter supplied to {@code function} on call
808      * @param arg10 parameter supplied to {@code function} on call
809      * @return a {@link PooledRunnable}, equivalent to lambda:
810      *         {@code () -> function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) }
811      */
obtainRunnable( DecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F, ? super G, ? super H, ? super I, ? super J> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10)812     static <A, B, C, D, E, F, G, H, I, J> PooledRunnable obtainRunnable(
813             DecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
814                     ? super G, ? super H, ? super I, ? super J> function, A arg1, B arg2, C arg3,
815             D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10) {
816         return acquire(PooledLambdaImpl.sPool,
817                 function, 10, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
818                 arg9, arg10, null, null);
819     }
820 
821     /**
822      * Factory of {@link Message}s that contain an
823      * ({@link PooledLambda#recycleOnUse auto-recycling}) {@link PooledRunnable} as its
824      * {@link Message#getCallback internal callback}.
825      *
826      * The callback is equivalent to one obtainable via
827      * {@link #obtainRunnable(QuintConsumer, Object, Object, Object, Object, Object)}
828      *
829      * Note that using this method with {@link android.os.Handler#handleMessage}
830      * is more efficient than the alternative of {@link android.os.Handler#post}
831      * with a {@link PooledRunnable} due to the lack of 2 separate synchronization points
832      * when obtaining {@link Message} and {@link PooledRunnable} from pools separately
833      *
834      * You may optionally set a {@link Message#what} for the message if you want to be
835      * able to cancel it via {@link android.os.Handler#removeMessages}, but otherwise
836      * there's no need to do so
837      *
838      * @param function non-capturing lambda(typically an unbounded method reference)
839      *                 to be invoked on call
840      * @param arg1 parameter supplied to {@code function} on call
841      * @param arg2 parameter supplied to {@code function} on call
842      * @param arg3 parameter supplied to {@code function} on call
843      * @param arg4 parameter supplied to {@code function} on call
844      * @param arg5 parameter supplied to {@code function} on call
845      * @param arg6 parameter supplied to {@code function} on call
846      * @param arg7 parameter supplied to {@code function} on call
847      * @param arg8 parameter supplied to {@code function} on call
848      * @param arg9 parameter supplied to {@code function} on call
849      * @param arg10 parameter supplied to {@code function} on call
850      * @return a {@link Message} invoking {@code function(arg1, arg2, arg3, arg4, arg5, arg6,
851      * arg7, arg8, arg9, arg10) } when handled
852      */
obtainMessage( DecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F, ? super G, ? super H, ? super I, ? super J> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10)853     static <A, B, C, D, E, F, G, H, I, J> Message obtainMessage(
854             DecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
855                     ? super G, ? super H, ? super I, ? super J> function, A arg1, B arg2, C arg3,
856             D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10) {
857         synchronized (Message.sPoolSync) {
858             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
859                     function, 10, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
860                     arg8, arg9, arg10, null, null);
861             return Message.obtain().setCallback(callback.recycleOnUse());
862         }
863     }
864 
865     /**
866      * {@link PooledRunnable} factory
867      *
868      * @param function non-capturing lambda(typically an unbounded method reference)
869      *                 to be invoked on call
870      * @param arg1 parameter supplied to {@code function} on call
871      * @param arg2 parameter supplied to {@code function} on call
872      * @param arg3 parameter supplied to {@code function} on call
873      * @param arg4 parameter supplied to {@code function} on call
874      * @param arg5 parameter supplied to {@code function} on call
875      * @param arg6 parameter supplied to {@code function} on call
876      * @param arg7 parameter supplied to {@code function} on call
877      * @param arg8 parameter supplied to {@code function} on call
878      * @param arg9 parameter supplied to {@code function} on call
879      * @param arg10 parameter supplied to {@code function} on call
880      * @param arg11 parameter supplied to {@code function} on call
881      * @return a {@link PooledRunnable}, equivalent to lambda:
882      *         {@code () -> function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,
883      *         arg11) }
884      */
obtainRunnable( UndecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F, ? super G, ? super H, ? super I, ? super J, ? super K> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10, K arg11)885     static <A, B, C, D, E, F, G, H, I, J, K> PooledRunnable obtainRunnable(
886             UndecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
887                     ? super G, ? super H, ? super I, ? super J, ? super K> function, A arg1, B arg2,
888             C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10, K arg11) {
889         return acquire(PooledLambdaImpl.sPool,
890                 function, 11, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
891                 arg9, arg10, arg11, null);
892     }
893 
894     /**
895      * Factory of {@link Message}s that contain an
896      * ({@link PooledLambda#recycleOnUse auto-recycling}) {@link PooledRunnable} as its
897      * {@link Message#getCallback internal callback}.
898      *
899      * The callback is equivalent to one obtainable via
900      * {@link #obtainRunnable(QuintConsumer, Object, Object, Object, Object, Object)}
901      *
902      * Note that using this method with {@link android.os.Handler#handleMessage}
903      * is more efficient than the alternative of {@link android.os.Handler#post}
904      * with a {@link PooledRunnable} due to the lack of 2 separate synchronization points
905      * when obtaining {@link Message} and {@link PooledRunnable} from pools separately
906      *
907      * You may optionally set a {@link Message#what} for the message if you want to be
908      * able to cancel it via {@link android.os.Handler#removeMessages}, but otherwise
909      * there's no need to do so
910      *
911      * @param function non-capturing lambda(typically an unbounded method reference)
912      *                 to be invoked on call
913      * @param arg1 parameter supplied to {@code function} on call
914      * @param arg2 parameter supplied to {@code function} on call
915      * @param arg3 parameter supplied to {@code function} on call
916      * @param arg4 parameter supplied to {@code function} on call
917      * @param arg5 parameter supplied to {@code function} on call
918      * @param arg6 parameter supplied to {@code function} on call
919      * @param arg7 parameter supplied to {@code function} on call
920      * @param arg8 parameter supplied to {@code function} on call
921      * @param arg9 parameter supplied to {@code function} on call
922      * @param arg10 parameter supplied to {@code function} on call
923      * @param arg11 parameter supplied to {@code function} on call
924      * @return a {@link Message} invoking {@code function(arg1, arg2, arg3, arg4, arg5, arg6,
925      * arg7, arg8, arg9, arg10, arg11) } when handled
926      */
obtainMessage( UndecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F, ? super G, ? super H, ? super I, ? super J, ? super K> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10, K arg11)927     static <A, B, C, D, E, F, G, H, I, J, K> Message obtainMessage(
928             UndecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
929                     ? super G, ? super H, ? super I, ? super J, ? super K> function, A arg1, B arg2,
930             C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10, K arg11) {
931         synchronized (Message.sPoolSync) {
932             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
933                     function, 11, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
934                     arg8, arg9, arg10, arg11, null);
935             return Message.obtain().setCallback(callback.recycleOnUse());
936         }
937     }
938 
939     /**
940      * {@link PooledRunnable} factory
941      *
942      * @param function non-capturing lambda(typically an unbounded method reference)
943      *                 to be invoked on call
944      * @param arg1 parameter supplied to {@code function} on call
945      * @param arg2 parameter supplied to {@code function} on call
946      * @param arg3 parameter supplied to {@code function} on call
947      * @param arg4 parameter supplied to {@code function} on call
948      * @param arg5 parameter supplied to {@code function} on call
949      * @param arg6 parameter supplied to {@code function} on call
950      * @param arg7 parameter supplied to {@code function} on call
951      * @param arg8 parameter supplied to {@code function} on call
952      * @param arg9 parameter supplied to {@code function} on call
953      * @param arg10 parameter supplied to {@code function} on call
954      * @param arg11 parameter supplied to {@code function} on call
955      * @param arg12 parameter supplied to {@code function} on call
956      * @return a {@link PooledRunnable}, equivalent to lambda:
957      *         {@code () -> function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,
958      *         arg11, arg12) }
959      */
obtainRunnable( DodecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F, ? super G, ? super H, ? super I, ? super J, ? super K, ? super L> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10, K arg11, L arg12)960     static <A, B, C, D, E, F, G, H, I, J, K, L> PooledRunnable obtainRunnable(
961             DodecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
962                                 ? super G, ? super H, ? super I, ? super J, ? super K,
963                                 ? super L> function,
964             A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10,
965             K arg11, L arg12) {
966         return acquire(PooledLambdaImpl.sPool,
967                 function, 12, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
968                 arg9, arg10, arg11, arg12);
969     }
970 
971     /**
972      * Factory of {@link Message}s that contain an
973      * ({@link PooledLambda#recycleOnUse auto-recycling}) {@link PooledRunnable} as its
974      * {@link Message#getCallback internal callback}.
975      *
976      * The callback is equivalent to one obtainable via
977      * {@link #obtainRunnable(QuintConsumer, Object, Object, Object, Object, Object)}
978      *
979      * Note that using this method with {@link android.os.Handler#handleMessage}
980      * is more efficient than the alternative of {@link android.os.Handler#post}
981      * with a {@link PooledRunnable} due to the lack of 2 separate synchronization points
982      * when obtaining {@link Message} and {@link PooledRunnable} from pools separately
983      *
984      * You may optionally set a {@link Message#what} for the message if you want to be
985      * able to cancel it via {@link android.os.Handler#removeMessages}, but otherwise
986      * there's no need to do so
987      *
988      * @param function non-capturing lambda(typically an unbounded method reference)
989      *                 to be invoked on call
990      * @param arg1 parameter supplied to {@code function} on call
991      * @param arg2 parameter supplied to {@code function} on call
992      * @param arg3 parameter supplied to {@code function} on call
993      * @param arg4 parameter supplied to {@code function} on call
994      * @param arg5 parameter supplied to {@code function} on call
995      * @param arg6 parameter supplied to {@code function} on call
996      * @param arg7 parameter supplied to {@code function} on call
997      * @param arg8 parameter supplied to {@code function} on call
998      * @param arg9 parameter supplied to {@code function} on call
999      * @param arg10 parameter supplied to {@code function} on call
1000      * @param arg11 parameter supplied to {@code function} on call
1001      * @param arg12 parameter supplied to {@code function} on call
1002      * @return a {@link Message} invoking {@code function(arg1, arg2, arg3, arg4, arg5, arg6,
1003      * arg7, arg8, arg9, arg10, arg11) } when handled
1004      */
obtainMessage( DodecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F, ? super G, ? super H, ? super I, ? super J, ? super K, ? super L> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10, K arg11, L arg12)1005     static <A, B, C, D, E, F, G, H, I, J, K, L> Message obtainMessage(
1006             DodecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
1007                     ? super G, ? super H, ? super I, ? super J, ? super K, ? super L> function,
1008             A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10,
1009             K arg11, L arg12) {
1010         synchronized (Message.sPoolSync) {
1011             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
1012                     function, 11, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
1013                     arg8, arg9, arg10, arg11, arg12);
1014             return Message.obtain().setCallback(callback.recycleOnUse());
1015         }
1016     }
1017 }
1018