Skip to content

Commit

Permalink
Decouple TaskDataHandler and TaskSequenceHandler by binding the corou…
Browse files Browse the repository at this point in the history
…tine in DataCollectionViewModel
  • Loading branch information
shobhitagarwal1612 committed Jan 9, 2025
1 parent fc0d384 commit af94eb3
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flow
Expand Down Expand Up @@ -143,8 +144,8 @@ internal constructor(

lateinit var submissionId: String

private val taskSequenceHandler: TaskSequenceHandler = TaskSequenceHandler(tasks)
private val taskDataHandler = taskSequenceHandler.taskDataHandler
private val taskSequenceHandler = TaskSequenceHandler(tasks)
private val taskDataHandler = TaskDataHandler()

init {
if (currentTaskId.value == "") {
Expand All @@ -154,6 +155,11 @@ internal constructor(

check(currentTaskId.value.isNotBlank()) { "Task ID can't be blank" }
_uiState.update { UiState.TaskListAvailable(tasks, getTaskPosition(currentTaskId.value)) }

// Refresh the computed sequence whenever the collected task's data is updated.
viewModelScope.launch {
taskDataHandler.dataState.collectLatest { taskSequenceHandler.refreshSequence() }
}
}

fun setLoiName(name: String) {
Expand Down Expand Up @@ -326,11 +332,9 @@ internal constructor(
return taskSequenceHandler.isLastPosition(task.id)
}

val taskSelections = taskDataHandler.getTaskSelections(taskValueOverride = task.id to value)
val sequence =
taskSequenceHandler.generateTaskSequence(
"isLastPositionWithTaskData",
taskValueOverride = task.id to value,
)
taskSequenceHandler.generateTaskSequence("isLastPositionWithTaskData", taskSelections)
return task.id == sequence.last().id
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update

class TaskDataHandler(private val taskSequenceHandler: TaskSequenceHandler) {
class TaskDataHandler {

private val _dataState = MutableStateFlow(LinkedHashMap<Task, TaskData?>())

Expand All @@ -25,7 +25,6 @@ class TaskDataHandler(private val taskSequenceHandler: TaskSequenceHandler) {
fun setData(key: Task, newValue: TaskData?) {
if (getData(key) == newValue) return
_dataState.update { it.apply { set(key, newValue) } }
taskSequenceHandler.refreshSequence()
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
*/
package com.google.android.ground.ui.datacollection

import com.google.android.ground.model.submission.TaskData
import com.google.android.ground.model.task.Task
import com.google.android.ground.model.task.TaskSelections
import timber.log.Timber

/**
Expand All @@ -30,8 +30,6 @@ import timber.log.Timber
*/
class TaskSequenceHandler(private val tasks: List<Task>) {

val taskDataHandler = TaskDataHandler(this)

private var sequence: Sequence<Task> = emptySequence()
private var isInitialized = false

Expand All @@ -50,12 +48,9 @@ class TaskSequenceHandler(private val tasks: List<Task>) {
}

/** Generates the task sequence based on conditions and overrides. */
fun generateTaskSequence(
tag: String,
taskValueOverride: Pair<String, TaskData?>? = null,
): Sequence<Task> {
fun generateTaskSequence(tag: String, taskSelections: TaskSelections? = null): Sequence<Task> {
Timber.d("Task Sequence Generated: $tag")
return tasks.filter { shouldIncludeTaskInSequence(it, taskValueOverride) }.asSequence()
return tasks.filter { shouldIncludeTaskInSequence(it, taskSelections) }.asSequence()
}

/** Lazily retrieves the task sequence. */
Expand All @@ -68,12 +63,8 @@ class TaskSequenceHandler(private val tasks: List<Task>) {
}

/** Determines if a task should be included with the given overrides. */
private fun shouldIncludeTaskInSequence(
task: Task,
taskValueOverride: Pair<String, TaskData?>?,
): Boolean {
if (task.condition == null) return true
val taskSelections = taskDataHandler.getTaskSelections(taskValueOverride)
private fun shouldIncludeTaskInSequence(task: Task, taskSelections: TaskSelections?): Boolean {
if (task.condition == null || taskSelections == null) return true
return task.condition.fulfilledBy(taskSelections)
}

Expand Down

0 comments on commit af94eb3

Please sign in to comment.