< Summary

Class:DCL.Huds.QuestsTracker.QuestsTrackerSection
Assembly:QuestsTrackerHUD
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/QuestsTrackerHUD/QuestsTrackerSection.cs
Covered lines:32
Uncovered lines:45
Coverable lines:77
Total lines:181
Line coverage:41.5% (32 of 77)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
QuestsTrackerSection()0%110100%
QuestsTrackerSection()0%110100%
Populate(...)0%9.049092%
CreateTask()0%110100%
DestroyTaskEntry(...)0%6200%
Sequence()0%2101400%
SetExpandCollapseState(...)0%330100%
ClearTaskRoutines()0%10.754025%
WaitForTaskRoutines()0%20400%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/QuestsTrackerHUD/QuestsTrackerSection.cs

#LineLine coverage
 1using System;
 2using System.Collections;
 3using System.Collections.Generic;
 4using System.Linq;
 5using TMPro;
 6using UnityEngine;
 7
 8namespace DCL.Huds.QuestsTracker
 9{
 10    public class QuestsTrackerSection : MonoBehaviour
 11    {
 112        private static readonly int ANIMATION_TRIGGER_OUT = Animator.StringToHash("Out");
 13
 14        public enum SequenceState
 15        {
 16            NotStarted,
 17            ProgressingOngoingTasks,
 18            ShowingNewTasks,
 19            Finished
 20        }
 21
 22        [SerializeField] internal GameObject titleContainer;
 23        [SerializeField] internal TextMeshProUGUI sectionTitle;
 24        [SerializeField] internal RectTransform taskContainer;
 25        [SerializeField] internal GameObject taskPrefab;
 26        [SerializeField] internal Animator animator;
 27        [SerializeField] internal AudioEvent newTaskAudioEvent;
 28
 29        public event Action OnLayoutRebuildRequested;
 30        public event Action<string> OnDestroyed;
 31
 032        public SequenceState sequenceState { get; private set; } = SequenceState.NotStarted;
 33
 34        private QuestSection section;
 2735        internal readonly Dictionary<string, QuestsTrackerTask> taskEntries = new Dictionary<string, QuestsTrackerTask>(
 2736        private readonly List<Coroutine> tasksRoutines = new List<Coroutine>();
 37
 38        public void Populate(QuestSection newSection)
 39        {
 2540            sequenceState = SequenceState.NotStarted;
 2541            ClearTaskRoutines();
 42
 2543            section = newSection;
 2544            QuestTask[] allTasks = section.tasks;
 2545            titleContainer.SetActive(!string.IsNullOrEmpty(section.name));
 2546            sectionTitle.text = section.name;
 47
 48            bool hasCompletedTasksToShow = false;
 2549            List<string> entriesToRemove = taskEntries.Keys.ToList();
 50
 9651            for (int index = 0; index < allTasks.Length; index++)
 52            {
 2353                QuestTask task = allTasks[index];
 54                //We only show completed quests that has been just completed to show the progress
 2355                if (!taskEntries.ContainsKey(task.id) && (task.status == QuestsLiterals.Status.BLOCKED || (task.progress
 56                    continue;
 57
 2258                entriesToRemove.Remove(task.id);
 2259                if (!taskEntries.TryGetValue(task.id, out QuestsTrackerTask taskEntry))
 60                {
 2261                    taskEntry = CreateTask();
 62                    //New tasks are invisible
 2263                    taskEntry.gameObject.SetActive(!task.justUnlocked);
 2264                    taskEntries.Add(task.id, taskEntry);
 65                }
 66
 2267                taskEntry.Populate(task);
 2268                taskEntry.transform.SetSiblingIndex(index);
 69            }
 70
 5071            for (int index = 0; index < entriesToRemove.Count; index++)
 72            {
 073                DestroyTaskEntry(entriesToRemove[index]);
 74            }
 2575            OnLayoutRebuildRequested?.Invoke();
 76
 1877        }
 78
 79        internal QuestsTrackerTask CreateTask()
 80        {
 2281            var taskEntry = Instantiate(taskPrefab, taskContainer).GetComponent<QuestsTrackerTask>();
 2282            taskEntry.OnDestroyed += (taskId) =>
 83            {
 084                taskEntries.Remove(taskId);
 085                OnLayoutRebuildRequested?.Invoke();
 086            };
 2287            return taskEntry;
 88        }
 89
 90        private void DestroyTaskEntry(string taskId)
 91        {
 092            if (!taskEntries.TryGetValue(taskId, out QuestsTrackerTask taskEntry))
 093                return;
 094            Destroy(taskEntry.gameObject);
 095            taskEntries.Remove(taskId);
 096        }
 97
 98        public IEnumerator Sequence()
 99        {
 0100            sequenceState = SequenceState.ProgressingOngoingTasks;
 101
 0102            ClearTaskRoutines();
 103
 0104            List<QuestsTrackerTask> visibleTasks = new List<QuestsTrackerTask>();
 0105            List<QuestsTrackerTask> newTasks = new List<QuestsTrackerTask>();
 0106            foreach (QuestsTrackerTask task in taskEntries.Values)
 107            {
 0108                if (task.gameObject.activeSelf)
 0109                    visibleTasks.Add(task);
 110                else
 0111                    newTasks.Add(task);
 112            }
 113
 114            //Progress of currently visible tasks
 0115            for (int i = 0; i < visibleTasks.Count; i++)
 116            {
 0117                tasksRoutines.Add(StartCoroutine(visibleTasks[i].ProgressAndCompleteSequence()));
 118            }
 0119            yield return WaitForTaskRoutines();
 0120            OnLayoutRebuildRequested?.Invoke();
 121
 0122            sequenceState = SequenceState.ShowingNewTasks;
 123
 124            //Play "new task" sound
 0125            if (newTasks.Count > 0)
 0126                newTaskAudioEvent.Play();
 127
 128            //Show and progress of new tasks
 0129            for (int i = 0; i < newTasks.Count; i++)
 130            {
 0131                newTasks[i].gameObject.SetActive(true);
 0132                newTasks[i].SetIsNew(true);
 0133                tasksRoutines.Add(StartCoroutine(newTasks[i].ProgressAndCompleteSequence()));
 134            }
 0135            OnLayoutRebuildRequested?.Invoke();
 136
 0137            yield return WaitForTaskRoutines();
 138
 0139            if (taskEntries.Count == 0)
 140            {
 0141                animator.SetTrigger(ANIMATION_TRIGGER_OUT);
 0142                yield return WaitForSecondsCache.Get(0.5f);
 0143                Destroy(gameObject);
 0144                OnDestroyed?.Invoke(section.id);
 145            }
 0146            sequenceState = SequenceState.Finished;
 0147        }
 148
 149        public void SetExpandCollapseState(bool newIsExpanded)
 150        {
 72151            foreach (QuestsTrackerTask taskEntry in taskEntries.Values)
 152            {
 18153                taskEntry.SetExpandedStatus(newIsExpanded);
 154            }
 155
 18156            OnLayoutRebuildRequested?.Invoke();
 18157        }
 158
 159        public void ClearTaskRoutines()
 160        {
 25161            if (tasksRoutines.Count > 0)
 162            {
 0163                for (int i = 0; i < tasksRoutines.Count; i++)
 164                {
 0165                    if (tasksRoutines[i] != null)
 0166                        StopCoroutine(tasksRoutines[i]);
 167                }
 0168                tasksRoutines.Clear();
 169            }
 25170        }
 171
 172        private IEnumerator WaitForTaskRoutines()
 173        {
 0174            for (int i = 0; i < tasksRoutines.Count; i++)
 175            {
 176                //yielding Coroutines (not IEnumerators) allows us to wait for them in parallel
 0177                yield return tasksRoutines[i];
 178            }
 0179        }
 180    }
 181}