< 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:87
Uncovered lines:9
Coverable lines:96
Total lines:230
Line coverage:90.6% (87 of 96)
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%8.078089.47%
OnWorldsBlockerEnabledChange(...)0%2100%
IsSceneKnown(...)0%110100%

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    {
 49719        public bool enabled = true;
 20
 21        Transform blockersParent;
 22
 23        ISceneHandler sceneHandler;
 24        IBlockerInstanceHandler blockerInstanceHandler;
 25
 49726        HashSet<Vector2Int> blockersToRemove = new HashSet<Vector2Int>();
 49727        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
 1441        private BaseVariable<int> worldBlockersLimit => DataStore.i.worldBlockers.worldBlockerLimit;
 99542        private BaseVariable<bool> worldBlockersEnabled => DataStore.i.worldBlockers.worldBlockerEnabled;
 43
 44        void OnRendererStateChange(bool newValue, bool oldValue)
 45        {
 57546            blockerInstanceHandler.SetCollision(newValue);
 47
 57548            if (newValue && DataStore.i.debugConfig.isDebugMode.Get())
 049                SetEnabled(false);
 57550        }
 51
 49752        public WorldBlockersController(IBlockerInstanceHandler blockerInstanceHandler = null,
 53            ISceneHandler sceneHandler = null)
 54        {
 49755            this.sceneHandler = sceneHandler;
 49756            this.blockerInstanceHandler = blockerInstanceHandler;
 49757            worldBlockersEnabled.OnChange += OnWorldsBlockerEnabledChange;
 49758        }
 59
 60        public void SetupWorldBlockers()
 61        {
 62#if UNITY_STANDALONE || UNITY_EDITOR
 53263            if (DataStore.i.common.isApplicationQuitting.Get())
 064                return;
 65#endif
 66
 53267            if (!enabled || sceneHandler == null)
 168                return;
 69
 53170            SetupWorldBlockers(sceneHandler.GetAllLoadedScenesCoords());
 53171        }
 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
 49895            if (DataStore.i.common.isApplicationQuitting.Get())
 096                return;
 97#endif
 98
 49899            CommonScriptableObjects.worldOffset.OnChange -= OnWorldReposition;
 498100            worldBlockersEnabled.OnChange -= OnWorldsBlockerEnabledChange;
 498101            blockerInstanceHandler.DestroyAllBlockers();
 102
 498103            if (blockersParent != null)
 493104                Object.Destroy(blockersParent.gameObject);
 105
 498106            enabled = false;
 498107        }
 108
 109        public void Initialize()
 110        {
 493111            enabled = true;
 493112            blockersParent = new GameObject("WorldBlockers").transform;
 493113            blockersParent.position = Vector3.zero;
 114
 493115            if (blockerInstanceHandler == null)
 116            {
 493117                var blockerAnimationHandler = new BlockerAnimationHandler();
 493118                blockerInstanceHandler = new BlockerInstanceHandler(blockerAnimationHandler);
 119            }
 120
 493121            if (this.sceneHandler == null)
 493122                this.sceneHandler = DCL.Environment.i.world.state;
 123
 493124            blockerInstanceHandler.SetParent(blockersParent);
 125
 493126            CommonScriptableObjects.worldOffset.OnChange -= OnWorldReposition;
 493127            CommonScriptableObjects.worldOffset.OnChange += OnWorldReposition;
 128
 493129            CommonScriptableObjects.rendererState.OnChange -= OnRendererStateChange;
 493130            CommonScriptableObjects.rendererState.OnChange += OnRendererStateChange;
 493131        }
 132
 133        internal void SetupWorldBlockers(HashSet<Vector2Int> allLoadedParcelCoords)
 134        {
 531135            if (allLoadedParcelCoords.Count == 0)
 517136                return;
 137
 14138            blockersToRemove.Clear();
 14139            blockersToAdd.Clear();
 140
 14141            var blockers = blockerInstanceHandler.GetBlockers();
 142
 143            // Detect blockers to be removed
 52144            foreach (var item in blockers)
 145            {
 12146                if (allLoadedParcelCoords.Contains(item.Key))
 147                {
 2148                    blockersToRemove.Add(item.Key);
 149                }
 150                else
 151                {
 10152                    bool foundAroundLoadedScenes = false;
 70153                    for (int i = 0; i < aroundOffsets.Length; i++)
 154                    {
 35155                        Vector2Int offset = aroundOffsets[i];
 35156                        Vector2Int checkedPosition = new Vector2Int(item.Key.x + offset.x, item.Key.y + offset.y);
 157
 35158                        if (allLoadedParcelCoords.Contains(checkedPosition))
 159                        {
 10160                            foundAroundLoadedScenes = true;
 10161                            break;
 162                        }
 163                    }
 164
 10165                    if (!foundAroundLoadedScenes)
 0166                        blockersToRemove.Add(item.Key);
 167                }
 168            }
 169
 14170            blockersToAdd = LookForLimits(dontAddABlockerHere: allLoadedParcelCoords, blockers, 0);
 171
 172            // Remove extra blockers
 32173            foreach (var coords in blockersToRemove)
 2174                blockerInstanceHandler.HideBlocker(coords, false);
 175
 176            // Add missing blockers
 136177            foreach (var coords in blockersToAdd)
 54178                blockerInstanceHandler.ShowBlocker(coords, false, CommonScriptableObjects.rendererState.Get());
 14179        }
 180
 181        private HashSet<Vector2Int> LookForLimits(HashSet<Vector2Int> dontAddABlockerHere, Dictionary<Vector2Int, IPoola
 182        {
 14183            HashSet<Vector2Int> blockersCandidate = new HashSet<Vector2Int>();
 184
 185            // Detect missing blockers to be added
 14186            using (var it = dontAddABlockerHere.GetEnumerator())
 187            {
 41188                while (it.MoveNext())
 189                {
 27190                    Vector2Int pos = it.Current;
 191
 486192                    for (int i = 0; i < aroundOffsets.Length; i++)
 193                    {
 216194                        Vector2Int offset = aroundOffsets[i];
 216195                        int xCandidate = pos.x + offset.x;
 216196                        int yCandidate = pos.y + offset.y;
 216197                        Vector2Int checkedPosition = new Vector2Int(xCandidate, yCandidate);
 198
 216199                        if (!dontAddABlockerHere.Contains(checkedPosition) && !blockers.ContainsKey(checkedPosition))
 200                        {
 201                            // We add a blocker here because it is either part of a World, or because it contains a scen
 152202                            if (DataStore.i.common.isWorld.Get() || IsSceneKnown (checkedPosition))
 80203                                blockersCandidate.Add(checkedPosition);
 204                        }
 205                    }
 206                }
 14207            }
 208
 14209            if (currentLimitIterationEvaluation == worldBlockersLimit.Get())
 14210                return blockersCandidate;
 211            else
 212            {
 0213                blockersCandidate.UnionWith(dontAddABlockerHere);
 0214                return LookForLimits(blockersCandidate, blockers, currentLimitIterationEvaluation + 1);
 215            }
 216        }
 217
 218        private void OnWorldsBlockerEnabledChange(bool newState, bool _)
 219        {
 0220            SetEnabled(newState);
 0221        }
 222
 223        private bool IsSceneKnown(Vector2Int parcel)
 224        {
 225            // Note: This returns false when the set of coordinates is about a parcel
 226            // where the kernel didn't provide yet any information to the renderer
 152227            return sceneHandler.GetScene(parcel) != null;
 228        }
 229    }
 230}