1
1
package com.alamkanak.weekview
2
2
3
- import androidx.annotation.VisibleForTesting
3
+ import androidx.collection.ArrayMap
4
4
import java.util.Calendar
5
5
6
- // /**
7
- // * Wraps all available [EventsCache]s to allow for dynamic switching between them.
8
- // */
9
- // internal class EventsCacheWrapper<T> {
10
- //
11
- // private val simpleEventsCache: EventsCache<T> = SimpleEventsCache()
12
- // private val pagedEventsCache: EventsCache<T> = PagedEventsCache()
13
- //
14
- // private var currentEventsCache = simpleEventsCache
15
- //
16
- // /**
17
- // * Returns the [EventsCache] that is currently in use.
18
- // */
19
- // fun get() = currentEventsCache
20
- //
21
- // /**
22
- // * Switches the currently used [EventsCache] to a [PagedEventsCache] (if [listener] is not null)
23
- // * or [SimpleEventsCache] (otherwise).
24
- // */
25
- // fun onListenerChanged(listener: OnMonthChangeListener<T>?) {
26
- // currentEventsCache = if (listener != null) pagedEventsCache else simpleEventsCache
27
- // }
28
- //
29
- // /**
30
- // * Switches the currently used [EventsCache] to a [PagedEventsCache] (if [listener] is not null)
31
- // * or [SimpleEventsCache] (otherwise).
32
- // */
33
- // fun onListenerChanged(listener: OnLoadMoreListener?) {
34
- // currentEventsCache = if (listener != null) pagedEventsCache else simpleEventsCache
35
- // }
36
- // }
37
-
38
6
/* *
39
7
* An abstract class that provides functionality to cache [WeekViewEvent]s.
40
8
*/
41
9
internal abstract class EventsCache <T > {
42
10
43
11
abstract val allEvents: List <ResolvedWeekViewEvent <T >>
12
+ abstract fun update (events : List <ResolvedWeekViewEvent <T >>)
44
13
abstract fun clear ()
45
14
46
- operator fun get (id : Long ): ResolvedWeekViewEvent <T >? {
47
- return allEvents.firstOrNull { it.id == id }
48
- }
15
+ operator fun get (id : Long ): ResolvedWeekViewEvent <T >? = allEvents.firstOrNull { it.id == id }
49
16
50
17
operator fun get (
51
18
dateRange : List <Calendar >
@@ -62,8 +29,6 @@ internal abstract class EventsCache<T> {
62
29
val endTime = fetchRange.next.endDate
63
30
return allEvents.filter { it.endTime >= startTime && it.startTime <= endTime }
64
31
}
65
-
66
- open operator fun get (period : Period ): List <ResolvedWeekViewEvent <T >>? = null
67
32
}
68
33
69
34
/* *
@@ -77,7 +42,7 @@ internal class SimpleEventsCache<T> : EventsCache<T>() {
77
42
override val allEvents: List <ResolvedWeekViewEvent <T >>
78
43
get() = _allEvents .orEmpty()
79
44
80
- fun update (events : List <ResolvedWeekViewEvent <T >>) {
45
+ override fun update (events : List <ResolvedWeekViewEvent <T >>) {
81
46
_allEvents = events
82
47
}
83
48
@@ -87,103 +52,34 @@ internal class SimpleEventsCache<T> : EventsCache<T>() {
87
52
}
88
53
89
54
/* *
90
- * Represents an [EventsCache] that caches [WeekViewEvent]s for a particular [FetchRange].
55
+ * Represents an [EventsCache] that caches [ResolvedWeekViewEvent]s for their respective [Period]
56
+ * and allows retrieval based on that [Period].
91
57
*/
92
58
internal class PagedEventsCache <T > : EventsCache <T >() {
93
59
94
60
override val allEvents: List <ResolvedWeekViewEvent <T >>
95
- get() = previousPeriodEvents.orEmpty() +
96
- currentPeriodEvents.orEmpty() +
97
- nextPeriodEvents.orEmpty()
98
-
99
- private var previousPeriodEvents: List <ResolvedWeekViewEvent <T >>? = null
100
- private var currentPeriodEvents: List <ResolvedWeekViewEvent <T >>? = null
101
- private var nextPeriodEvents: List <ResolvedWeekViewEvent <T >>? = null
102
-
103
- @VisibleForTesting
104
- internal var fetchedRange: FetchRange ? = null
61
+ get() = eventsByPeriod.values.flatten()
105
62
106
- operator fun contains ( period : Period ) = fetchedRange?.periods?.contains(period) ? : false
63
+ private val eventsByPeriod : ArrayMap < Period , List < ResolvedWeekViewEvent < T >>> = ArrayMap ()
107
64
108
- operator fun contains (fetchRange : FetchRange ) = fetchedRange?.isEqual(fetchRange) ? : false
109
-
110
- override fun get (period : Period ): List <ResolvedWeekViewEvent <T >>? {
111
- val range = checkNotNull(fetchedRange)
112
- return when (period) {
113
- range.previous -> previousPeriodEvents
114
- range.current -> currentPeriodEvents
115
- range.next -> nextPeriodEvents
116
- else -> throw IllegalStateException (" Requesting events for invalid period $period " )
65
+ override fun update (events : List <ResolvedWeekViewEvent <T >>) {
66
+ val groupedEvents = events.groupBy { Period .fromDate(it.startTime) }
67
+ for ((period, periodEvents) in groupedEvents) {
68
+ eventsByPeriod[period] = periodEvents
117
69
}
118
70
}
119
71
120
- /* *
121
- * Adjusts the [WeekViewEvent]s of the fetched [Period]s to the new [FetchRange]. This means
122
- * that if the user scrolled to the next month, the following would happen:
123
- * 1. The events of the current month would be moved to [previousPeriodEvents].
124
- * 2. The events of the next month would be moved to [currentPeriodEvents].
125
- * 3. The events of the following month aren't loaded yet; [nextPeriodEvents] will be null.
126
- * 4. The [fetchedRange] will be set to the provided [FetchRange].
127
- *
128
- * When scrolling to the previous month, the behavior would be like so:
129
- * 1. The events of the current month would be moved to [nextPeriodEvents].
130
- * 2. The events of the previous month would be moved to [currentPeriodEvents].
131
- * 2. The events of the preceding month aren't loaded yet; [previousPeriodEvents] will be null.
132
- * 4. The [fetchedRange] will be set to the provided [FetchRange].
133
- */
134
- fun adjustToFetchRange (fetchRange : FetchRange ) {
135
- val oldFetchRange = fetchedRange ? : fetchRange
136
- val newCurrentPeriod = fetchRange.current
137
-
138
- val previousEvents = when (newCurrentPeriod) {
139
- oldFetchRange.previous -> null
140
- oldFetchRange.next -> currentPeriodEvents
141
- else -> previousPeriodEvents
142
- }
72
+ internal fun determinePeriodsToFetch (range : FetchRange ) = range.periods.filter { it !in this }
143
73
144
- val currentEvents = when (newCurrentPeriod) {
145
- oldFetchRange.previous -> previousPeriodEvents
146
- oldFetchRange.next -> nextPeriodEvents
147
- else -> currentPeriodEvents
148
- }
74
+ operator fun contains (period : Period ) = eventsByPeriod.contains(period)
149
75
150
- val nextEvents = when (newCurrentPeriod) {
151
- oldFetchRange.previous -> currentPeriodEvents
152
- oldFetchRange.next -> null
153
- else -> nextPeriodEvents
154
- }
155
-
156
- previousPeriodEvents = previousEvents
157
- currentPeriodEvents = currentEvents
158
- nextPeriodEvents = nextEvents
159
- fetchedRange = fetchRange
160
- }
161
-
162
- fun update (eventsByPeriod : Map <Period , List <ResolvedWeekViewEvent <T >>>) {
163
- for ((period, events) in eventsByPeriod) {
164
- update(period, events)
165
- }
166
- }
167
-
168
- private fun update (period : Period , events : List <ResolvedWeekViewEvent <T >>) {
169
- val range = checkNotNull(fetchedRange)
170
- when (period) {
171
- range.previous -> previousPeriodEvents = events
172
- range.current -> currentPeriodEvents = events
173
- range.next -> nextPeriodEvents = events
174
- }
175
- }
76
+ operator fun contains (range : FetchRange ) = eventsByPeriod.containsAll(range.periods)
176
77
177
- operator fun set (
178
- period : Period ,
179
- events : List <ResolvedWeekViewEvent <T >>
180
- ) {
181
- update(period, events)
78
+ fun reserve (period : Period ) {
79
+ eventsByPeriod[period] = listOf ()
182
80
}
183
81
184
82
override fun clear () {
185
- previousPeriodEvents = null
186
- currentPeriodEvents = null
187
- nextPeriodEvents = null
83
+ eventsByPeriod.clear()
188
84
}
189
85
}
0 commit comments