< Summary

Class:DCL.Controllers.WorldBlockersController
Assembly:WorldBlockersController
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/WorldRuntime/BlockerController/WorldBlockersController.cs
Covered lines:85
Uncovered lines:9
Coverable lines:94
Total lines:221
Line coverage:90.4% (85 of 94)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
WorldBlockersController(...)0%110100%
WorldBlockersController()0%110100%
OnRendererStateChange(...)0%3.143075%
SetupWorldBlockers()0%4.074083.33%
SetEnabled(...)0%3.043083.33%
OnWorldReposition(...)0%110100%
Dispose()0%3.013088.89%
Initialize()0%330100%
SetupWorldBlockers(...)0%99096.77%
LookForLimits(...)0%6.056088.89%
OnWorldsBlockerEnabledChange(...)0%2100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/WorldRuntime/BlockerController/WorldBlockersController.cs

#LineLine coverage
 1using System.Collections.Generic;
 2using DCL.Helpers;
 3using System;
 4using UnityEngine;
 5using Object = UnityEngine.Object;
 6
 7namespace DCL.Controllers
 8{
 9    /// <summary>
 10    /// This class is the domain-specific glue for BlockerInstanceHandler.
 11    /// <br/><br/>
 12    /// Responsibilities:<br/>
 13    /// - Spawning blockers depending on scene state<br/>
 14    /// - Moving blockers when the world is repositioned<br/>
 15    /// - Handling lifecycle of BlockerInstanceHandler<br/>
 16    /// </summary>
 17    public class WorldBlockersController : IWorldBlockersController
 18    {
 50419        public bool enabled = true;
 20
 21        Transform blockersParent;
 22
 23        ISceneHandler sceneHandler;
 24        IBlockerInstanceHandler blockerInstanceHandler;
 25
 50426        HashSet<Vector2Int> blockersToRemove = new HashSet<Vector2Int>();
 50427        HashSet<Vector2Int> blockersToAdd = new HashSet<Vector2Int>();
 28
 129        static Vector2Int[] aroundOffsets =
 30        {
 31            new Vector2Int(1, 0),
 32            new Vector2Int(-1, 0),
 33            new Vector2Int(0, 1),
 34            new Vector2Int(0, -1),
 35            new Vector2Int(1, 1),
 36            new Vector2Int(-1, -1),
 37            new Vector2Int(1, -1),
 38            new Vector2Int(-1, 1)
 39        };
 40
 1241        private BaseVariable<int> worldBlockersLimit => DataStore.i.worldBlockers.worldBlockerLimit;
 100942        private BaseVariable<bool> worldBlockersEnabled => DataStore.i.worldBlockers.worldBlockerEnabled;
 43
 44        void OnRendererStateChange(bool newValue, bool oldValue)
 45        {
 59346            blockerInstanceHandler.SetCollision(newValue);
 47
 59348            if (newValue && DataStore.i.debugConfig.isDebugMode.Get())
 049                SetEnabled(false);
 59350        }
 51
 50452        public WorldBlockersController(IBlockerInstanceHandler blockerInstanceHandler = null,
 53            ISceneHandler sceneHandler = null)
 54        {
 50455            this.sceneHandler = sceneHandler;
 50456            this.blockerInstanceHandler = blockerInstanceHandler;
 50457            worldBlockersEnabled.OnChange += OnWorldsBlockerEnabledChange;
 50458        }
 59
 60        public void SetupWorldBlockers()
 61        {
 62#if UNITY_STANDALONE || UNITY_EDITOR
 52563            if (DataStore.i.common.isApplicationQuitting.Get())
 064                return;
 65#endif
 66
 52567            if (!enabled || sceneHandler == null)
 168                return;
 69
 52470            SetupWorldBlockers(sceneHandler.GetAllLoadedScenesCoords());
 52471        }
 72
 73        public void SetEnabled(bool targetValue)
 74        {
 75#if UNITY_STANDALONE || UNITY_EDITOR
 276            if (DataStore.i.common.isApplicationQuitting.Get())
 077                return;
 78#endif
 79
 280            enabled = targetValue;
 81
 282            if (!enabled)
 183                blockerInstanceHandler.DestroyAllBlockers();
 284        }
 85
 86        void OnWorldReposition(Vector3 current, Vector3 previous)
 87        {
 288            var newPosition = PositionUtils.WorldToUnityPosition(Vector3.zero); // Blockers parent original position
 289            blockersParent.position = newPosition;
 290        }
 91
 92        public void Dispose()
 93        {
 94#if UNITY_STANDALONE || UNITY_EDITOR
 50595            if (DataStore.i.common.isApplicationQuitting.Get())
 096                return;
 97#endif
 98
 50599            CommonScriptableObjects.worldOffset.OnChange -= OnWorldReposition;
 505100            worldBlockersEnabled.OnChange -= OnWorldsBlockerEnabledChange;
 505101            blockerInstanceHandler.DestroyAllBlockers();
 102
 505103            if (blockersParent != null)
 500104                Object.Destroy(blockersParent.gameObject);
 105
 505106            enabled = false;
 505107        }
 108
 109        public void Initialize()
 110        {
 500111            enabled = true;
 500112            blockersParent = new GameObject("WorldBlockers").transform;
 500113            blockersParent.position = Vector3.zero;
 114
 500115            if (blockerInstanceHandler == null)
 116            {
 500117                var blockerAnimationHandler = new BlockerAnimationHandler();
 500118                blockerInstanceHandler = new BlockerInstanceHandler(blockerAnimationHandler);
 119            }
 120
 500121            if (this.sceneHandler == null)
 500122                this.sceneHandler = DCL.Environment.i.world.state;
 123
 500124            blockerInstanceHandler.SetParent(blockersParent);
 125
 500126            CommonScriptableObjects.worldOffset.OnChange -= OnWorldReposition;
 500127            CommonScriptableObjects.worldOffset.OnChange += OnWorldReposition;
 128
 500129            CommonScriptableObjects.rendererState.OnChange -= OnRendererStateChange;
 500130            CommonScriptableObjects.rendererState.OnChange += OnRendererStateChange;
 500131        }
 132
 133        internal void SetupWorldBlockers(HashSet<Vector2Int> allLoadedParcelCoords)
 134        {
 524135            if (allLoadedParcelCoords.Count == 0)
 512136                return;
 137
 12138            blockersToRemove.Clear();
 12139            blockersToAdd.Clear();
 140
 12141            var blockers = blockerInstanceHandler.GetBlockers();
 142
 143            // Detect blockers to be removed
 80144            foreach (var item in blockers)
 145            {
 28146                if (allLoadedParcelCoords.Contains(item.Key))
 147                {
 2148                    blockersToRemove.Add(item.Key);
 149                }
 150                else
 151                {
 26152                    bool foundAroundLoadedScenes = false;
 214153                    for (int i = 0; i < aroundOffsets.Length; i++)
 154                    {
 107155                        Vector2Int offset = aroundOffsets[i];
 107156                        Vector2Int checkedPosition = new Vector2Int(item.Key.x + offset.x, item.Key.y + offset.y);
 157
 107158                        if (allLoadedParcelCoords.Contains(checkedPosition))
 159                        {
 26160                            foundAroundLoadedScenes = true;
 26161                            break;
 162                        }
 163                    }
 164
 26165                    if (!foundAroundLoadedScenes)
 0166                        blockersToRemove.Add(item.Key);
 167                }
 168            }
 169
 12170            blockersToAdd = LookForLimits(allLoadedParcelCoords, blockers, 0);
 171
 172            // Remove extra blockers
 28173            foreach (var coords in blockersToRemove)
 2174                blockerInstanceHandler.HideBlocker(coords, false);
 175
 176            // Add missing blockers
 212177            foreach (var coords in blockersToAdd)
 94178                blockerInstanceHandler.ShowBlocker(coords, false, CommonScriptableObjects.rendererState.Get());
 12179        }
 180
 181        private HashSet<Vector2Int> LookForLimits(HashSet<Vector2Int> dontAddABlockerHere, Dictionary<Vector2Int, IPoola
 182        {
 12183            HashSet<Vector2Int> blockersCandidate = new HashSet<Vector2Int>();
 184
 185            // Detect missing blockers to be added
 12186            using (var it = dontAddABlockerHere.GetEnumerator())
 187            {
 37188                while (it.MoveNext())
 189                {
 25190                    Vector2Int pos = it.Current;
 191
 450192                    for (int i = 0; i < aroundOffsets.Length; i++)
 193                    {
 200194                        Vector2Int offset = aroundOffsets[i];
 200195                        int xCandidate = pos.x + offset.x;
 200196                        int yCandidate = pos.y + offset.y;
 200197                        Vector2Int checkedPosition = new Vector2Int(xCandidate, yCandidate);
 198
 200199                        if (!dontAddABlockerHere.Contains(checkedPosition) && !blockers.ContainsKey(checkedPosition))
 200                        {
 120201                            blockersCandidate.Add(checkedPosition);
 202                        }
 203                    }
 204                }
 12205            }
 206
 12207            if (currentLimitIterationEvaluation == worldBlockersLimit.Get())
 12208                return blockersCandidate;
 209            else
 210            {
 0211                blockersCandidate.UnionWith(dontAddABlockerHere);
 0212                return LookForLimits(blockersCandidate, blockers, currentLimitIterationEvaluation + 1);
 213            }
 214        }
 215
 216        private void OnWorldsBlockerEnabledChange(bool newState, bool _)
 217        {
 0218            SetEnabled(newState);
 0219        }
 220    }
 221}