1 /*
2  * Copyright 2021 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 androidx.paging
18 
19 import androidx.paging.LoadType.APPEND
20 import androidx.paging.LoadType.PREPEND
21 import androidx.paging.LoadType.REFRESH
22 import androidx.paging.PageEvent.LoadStateUpdate
23 
localInsertnull24 private fun <T : Any> localInsert(
25     loadType: LoadType,
26     pages: List<TransformablePage<T>>,
27     placeholdersBefore: Int,
28     placeholdersAfter: Int,
29     source: LoadStates
30 ) =
31     when (loadType) {
32         REFRESH ->
33             PageEvent.Insert.Refresh(
34                 pages = pages,
35                 placeholdersBefore = placeholdersBefore,
36                 placeholdersAfter = placeholdersAfter,
37                 sourceLoadStates = source,
38                 mediatorLoadStates = null
39             )
40         PREPEND ->
41             PageEvent.Insert.Prepend(
42                 pages = pages,
43                 placeholdersBefore = placeholdersBefore,
44                 sourceLoadStates = source,
45                 mediatorLoadStates = null,
46             )
47         APPEND ->
48             PageEvent.Insert.Append(
49                 pages = pages,
50                 placeholdersAfter = placeholdersAfter,
51                 sourceLoadStates = source,
52                 mediatorLoadStates = null
53             )
54     }
55 
localRefreshnull56 internal fun <T : Any> localRefresh(
57     pages: List<TransformablePage<T>> = listOf(emptyPage()),
58     placeholdersBefore: Int = 0,
59     placeholdersAfter: Int = 0,
60     source: LoadStates = loadStates()
61 ) =
62     localInsert(
63         loadType = REFRESH,
64         pages = pages,
65         placeholdersBefore = placeholdersBefore,
66         placeholdersAfter = placeholdersAfter,
67         source = source
68     )
69 
70 internal fun <T : Any> localPrepend(
71     pages: List<TransformablePage<T>> = listOf(emptyPage()),
72     placeholdersBefore: Int = 0,
73     source: LoadStates = loadStates()
74 ) =
75     localInsert(
76         loadType = PREPEND,
77         pages = pages,
78         placeholdersBefore = placeholdersBefore,
79         placeholdersAfter = -1,
80         source = source
81     )
82 
83 internal fun <T : Any> localAppend(
84     pages: List<TransformablePage<T>> = listOf(emptyPage()),
85     placeholdersAfter: Int = 0,
86     source: LoadStates = loadStates()
87 ) =
88     localInsert(
89         loadType = APPEND,
90         pages = pages,
91         placeholdersBefore = -1,
92         placeholdersAfter = placeholdersAfter,
93         source = source
94     )
95 
96 private fun <T : Any> remoteInsert(
97     loadType: LoadType,
98     pages: List<TransformablePage<T>>,
99     placeholdersBefore: Int,
100     placeholdersAfter: Int,
101     source: LoadStates,
102     mediator: LoadStates,
103 ) =
104     when (loadType) {
105         REFRESH ->
106             PageEvent.Insert.Refresh(
107                 pages = pages,
108                 placeholdersBefore = placeholdersBefore,
109                 placeholdersAfter = placeholdersAfter,
110                 sourceLoadStates = source,
111                 mediatorLoadStates = mediator,
112             )
113         PREPEND ->
114             PageEvent.Insert.Prepend(
115                 pages = pages,
116                 placeholdersBefore = placeholdersBefore,
117                 sourceLoadStates = source,
118                 mediatorLoadStates = mediator,
119             )
120         APPEND ->
121             PageEvent.Insert.Append(
122                 pages = pages,
123                 placeholdersAfter = placeholdersAfter,
124                 sourceLoadStates = source,
125                 mediatorLoadStates = mediator
126             )
127     }
128 
remoteRefreshnull129 internal fun <T : Any> remoteRefresh(
130     pages: List<TransformablePage<T>> = listOf(emptyPage()),
131     placeholdersBefore: Int = 0,
132     placeholdersAfter: Int = 0,
133     source: LoadStates = loadStates(),
134     mediator: LoadStates = loadStates(),
135 ) =
136     remoteInsert(
137         loadType = REFRESH,
138         pages = pages,
139         placeholdersBefore = placeholdersBefore,
140         placeholdersAfter = placeholdersAfter,
141         source = source,
142         mediator = mediator,
143     )
144 
145 internal fun <T : Any> remotePrepend(
146     pages: List<TransformablePage<T>> = listOf(emptyPage()),
147     placeholdersBefore: Int = 0,
148     source: LoadStates = loadStates(),
149     mediator: LoadStates = loadStates(),
150 ) =
151     remoteInsert(
152         loadType = PREPEND,
153         pages = pages,
154         placeholdersBefore = placeholdersBefore,
155         placeholdersAfter = -1,
156         source = source,
157         mediator = mediator,
158     )
159 
160 internal fun <T : Any> remoteAppend(
161     pages: List<TransformablePage<T>> = listOf(emptyPage()),
162     placeholdersAfter: Int = 0,
163     source: LoadStates = loadStates(),
164     mediator: LoadStates = loadStates(),
165 ) =
166     remoteInsert(
167         loadType = APPEND,
168         pages = pages,
169         placeholdersBefore = -1,
170         placeholdersAfter = placeholdersAfter,
171         source = source,
172         mediator = mediator,
173     )
174 
175 internal fun <T : Any> localLoadStateUpdate(
176     refreshLocal: LoadState = LoadState.NotLoading.Incomplete,
177     prependLocal: LoadState = LoadState.NotLoading.Incomplete,
178     appendLocal: LoadState = LoadState.NotLoading.Incomplete,
179 ) =
180     LoadStateUpdate<T>(
181         source = loadStates(refreshLocal, prependLocal, appendLocal),
182         mediator = null
183     )
184 
185 internal fun <T : Any> localLoadStateUpdate(source: LoadStates = LoadStates.IDLE) =
186     LoadStateUpdate<T>(source, null)
187 
188 internal fun <T : Any> remoteLoadStateUpdate(
189     source: LoadStates = LoadStates.IDLE,
190     mediator: LoadStates = LoadStates.IDLE,
191 ) = LoadStateUpdate<T>(source, mediator)
192 
193 internal fun <T : Any> remoteLoadStateUpdate(
194     refreshLocal: LoadState = LoadState.NotLoading.Incomplete,
195     prependLocal: LoadState = LoadState.NotLoading.Incomplete,
196     appendLocal: LoadState = LoadState.NotLoading.Incomplete,
197     refreshRemote: LoadState = LoadState.NotLoading.Incomplete,
198     prependRemote: LoadState = LoadState.NotLoading.Incomplete,
199     appendRemote: LoadState = LoadState.NotLoading.Incomplete,
200 ) =
201     LoadStateUpdate<T>(
202         source = loadStates(refreshLocal, prependLocal, appendLocal),
203         mediator = loadStates(refreshRemote, prependRemote, appendRemote),
204     )
205 
206 private fun <T : Any> emptyPage() = TransformablePage<T>(0, emptyList())
207 
208 public fun <E> MutableList<E>.getAllAndClear(): List<E> {
209     val data = toList()
210     repeat(data.size) { removeFirst() }
211     return data
212 }
213