BayernMessenger/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultInitialSyncProgressS...

143 lines
4.6 KiB
Kotlin
Raw Normal View History

2019-07-09 13:36:12 +00:00
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
2019-07-04 08:53:46 +00:00
package im.vector.matrix.android.internal.session
import androidx.annotation.StringRes
2019-07-04 08:53:46 +00:00
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import im.vector.matrix.android.api.session.InitialSyncProgressService
import timber.log.Timber
import javax.inject.Inject
@SessionScope
class DefaultInitialSyncProgressService @Inject constructor() : InitialSyncProgressService {
private var status = MutableLiveData<InitialSyncProgressService.Status>()
2019-07-04 08:53:46 +00:00
private var rootTask: TaskInfo? = null
2019-07-04 08:53:46 +00:00
override fun getInitialSyncProgressStatus(): LiveData<InitialSyncProgressService.Status?> {
2019-07-04 08:53:46 +00:00
return status
}
fun startTask(@StringRes nameRes: Int, totalProgress: Int, parentWeight: Float = 1f) {
// Create a rootTask, or add a child to the leaf
2019-07-04 08:53:46 +00:00
if (rootTask == null) {
rootTask = TaskInfo(nameRes, totalProgress)
} else {
val currentLeaf = rootTask!!.leaf()
val newTask = TaskInfo(nameRes,
totalProgress,
currentLeaf,
parentWeight)
2019-07-04 08:53:46 +00:00
currentLeaf.child = newTask
}
reportProgress(0)
}
fun reportProgress(progress: Int) {
rootTask?.leaf()?.setProgress(progress)
2019-07-04 08:53:46 +00:00
}
fun endTask(nameRes: Int) {
val endedTask = rootTask?.leaf()
if (endedTask?.nameRes == nameRes) {
//close it
val parent = endedTask.parent
parent?.child = null
parent?.setProgress(endedTask.offset + (endedTask.totalProgress * endedTask.parentWeight).toInt())
2019-07-04 08:53:46 +00:00
}
if (endedTask?.parent == null) {
2019-07-09 14:36:46 +00:00
status.postValue(null)
2019-07-04 08:53:46 +00:00
}
}
fun endAll() {
2019-07-09 13:36:12 +00:00
rootTask = null
2019-07-09 14:36:46 +00:00
status.postValue(null)
2019-07-04 08:53:46 +00:00
}
private inner class TaskInfo(@StringRes var nameRes: Int,
var totalProgress: Int,
var parent: TaskInfo? = null,
var parentWeight: Float = 1f,
var offset: Int = parent?.currentProgress ?: 0) {
2019-07-04 08:53:46 +00:00
var child: TaskInfo? = null
var currentProgress: Int = 0
/**
* Get the further child
*/
2019-07-04 08:53:46 +00:00
fun leaf(): TaskInfo {
var last = this
while (last.child != null) {
last = last.child!!
}
return last
}
/**
* Set progress of the parent if any (which will post value), or post the value
*/
fun setProgress(progress: Int) {
2019-07-04 08:53:46 +00:00
currentProgress = progress
// val newProgress = Math.min(currentProgress + progress, totalProgress)
parent?.let {
val parentProgress = (currentProgress * parentWeight).toInt()
it.setProgress(offset + parentProgress)
} ?: run {
Timber.e("--- ${leaf().nameRes}: $currentProgress")
2019-07-09 14:36:46 +00:00
status.postValue(
2019-07-04 08:53:46 +00:00
InitialSyncProgressService.Status(leaf().nameRes, currentProgress)
)
}
}
}
}
2019-07-09 16:31:04 +00:00
inline fun <T> reportSubtask(reporter: DefaultInitialSyncProgressService?,
@StringRes nameRes: Int,
2019-07-09 16:31:04 +00:00
totalProgress: Int,
2019-07-09 16:20:00 +00:00
parentWeight: Float = 1f,
block: () -> T): T {
2019-07-04 08:53:46 +00:00
reporter?.startTask(nameRes, totalProgress, parentWeight)
return block().also {
reporter?.endTask(nameRes)
}
2019-07-08 14:31:21 +00:00
}
2019-07-09 16:20:00 +00:00
inline fun <K, V, R> Map<out K, V>.mapWithProgress(reporter: DefaultInitialSyncProgressService?,
taskId: Int,
weight: Float,
transform: (Map.Entry<K, V>) -> R): List<R> {
val total = count().toFloat()
2019-07-08 14:31:21 +00:00
var current = 0
reporter?.startTask(taskId, 100, weight)
return map {
reporter?.reportProgress((current / total * 100).toInt())
2019-07-08 14:31:21 +00:00
current++
transform.invoke(it)
}.also {
reporter?.endTask(taskId)
}
}