< Summary

Class:DCL.MessagingControllersManager
Assembly:MainScripts
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/Scene/Messaging/MessagingControllersManager.cs
Covered lines:119
Uncovered lines:15
Coverable lines:134
Total lines:304
Line coverage:88.8% (119 of 134)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
MessagingControllersManager()0%110100%
Initialize(...)0%330100%
MarkBusesDirty()0%110100%
PopulateBusesToBeProcessed()0%1717097.87%
Dispose()0%330100%
ContainsController(...)0%110100%
AddController(...)0%550100%
AddControllerIfNotExists(...)0%220100%
RemoveController(...)0%220100%
DisposeController(...)0%110100%
Enqueue(...)0%2100%
ForceEnqueueToGlobal(...)0%110100%
SetSceneReady(...)0%3.192033.33%
ProcessMessages()0%11.5611083.33%
ProcessBus(...)0%4.024090%
RefreshControllerEnabledState(...)0%8.36060%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/Scene/Messaging/MessagingControllersManager.cs

#LineLine coverage
 1using DCL.Controllers;
 2using System.Collections;
 3using System.Collections.Generic;
 4using UnityEngine;
 5
 6namespace DCL
 7{
 8    public class MessagingControllersManager : IMessagingControllersManager
 9    {
 10        public static bool VERBOSE = false;
 11
 12        private const float MAX_GLOBAL_MSG_BUDGET = 0.006f;
 13        private const float MAX_SYSTEM_MSG_BUDGET_FOR_FAR_SCENES = 0.003f;
 14
 15        private const float GLTF_BUDGET_MAX = 0.033f;
 16        private const float GLTF_BUDGET_MIN = 0.008f;
 17
 18        public const string GLOBAL_MESSAGING_CONTROLLER = "global_messaging_controller";
 19
 53120        public Dictionary<string, MessagingController> messagingControllers { get; set; } = new Dictionary<string, Messa
 21
 22        private Coroutine mainCoroutine;
 23
 3024        public bool hasPendingMessages => pendingMessagesCount > 0;
 25
 53126        public float timeBudgetCounter = MAX_GLOBAL_MSG_BUDGET;
 27        public int pendingMessagesCount;
 28        public int pendingInitMessagesCount;
 29        public long processedInitMessagesCount;
 30
 031        public bool isRunning { get { return mainCoroutine != null; } }
 32
 4033        public bool paused { get; set; }
 34
 53135        private Dictionary<string, MessagingController> globalSceneControllers = new Dictionary<string, MessagingControl
 53136        private List<MessagingController> sortedControllers = new List<MessagingController>();
 53137        private List<MessagingBus> busesToProcess = new List<MessagingBus>();
 38        private int busesToProcessCount = 0;
 39        private int sortedControllersCount = 0;
 40
 41        private MessagingController globalController = null;
 42        private MessagingController currentSceneController = null;
 43
 44        public void Initialize(IMessageProcessHandler messageHandler)
 45        {
 53146            messagingControllers[GLOBAL_MESSAGING_CONTROLLER] = new MessagingController(messageHandler, GLOBAL_MESSAGING
 47
 53148            if (!string.IsNullOrEmpty(GLOBAL_MESSAGING_CONTROLLER))
 53149                messagingControllers.TryGetValue(GLOBAL_MESSAGING_CONTROLLER, out globalController);
 50
 53151            Environment.i.world.sceneController.OnSortScenes += MarkBusesDirty;
 52
 53153            if (mainCoroutine == null)
 54            {
 53155                mainCoroutine = CoroutineStarter.Start(ProcessMessages());
 56            }
 53157        }
 58
 53159        bool populateBusesDirty = true;
 60
 141261        public void MarkBusesDirty() { populateBusesDirty = true; }
 62
 63        public void PopulateBusesToBeProcessed()
 64        {
 176765            IWorldState worldState = Environment.i.world.state;
 176766            string currentSceneId = worldState.currentSceneId;
 176767            List<IParcelScene> scenesSortedByDistance = worldState.scenesSortedByDistance;
 68
 176769            int count = scenesSortedByDistance.Count; // we need to retrieve list count everytime because it
 70            // may change after a yield return
 71
 176772            sortedControllers.Clear();
 73
 176774            if (!string.IsNullOrEmpty(currentSceneId) && messagingControllers.ContainsKey(currentSceneId))
 14675                currentSceneController = messagingControllers[currentSceneId];
 76
 622677            for (int i = 0; i < count; i++)
 78            {
 134679                string controllerId = scenesSortedByDistance[i].sceneData.id;
 80
 134681                if (controllerId != currentSceneId)
 82                {
 120083                    if (!messagingControllers.ContainsKey(controllerId))
 84                        continue;
 85
 119986                    sortedControllers.Add(messagingControllers[controllerId]);
 87                }
 88            }
 89
 176790            sortedControllersCount = sortedControllers.Count;
 91
 176792            bool globalSceneControllerActive = globalSceneControllers.Count > 0;
 176793            bool globalControllerActive = globalController != null && globalController.enabled;
 176794            bool currentSceneControllerActive = currentSceneController != null && currentSceneController.enabled;
 95
 176796            bool atLeastOneControllerShouldBeProcessed = globalSceneControllerActive || globalControllerActive || curren
 97
 176798            if (!atLeastOneControllerShouldBeProcessed)
 099                return;
 100
 1767101            busesToProcess.Clear();
 102            //-------------------------------------------------------------------------------------------
 103            // Global scenes
 1767104            using (var globalScenecontrollersIterator = globalSceneControllers.GetEnumerator())
 105            {
 1776106                while (globalScenecontrollersIterator.MoveNext())
 107                {
 9108                    busesToProcess.Add(globalScenecontrollersIterator.Current.Value.uiBus);
 9109                    busesToProcess.Add(globalScenecontrollersIterator.Current.Value.initBus);
 9110                    busesToProcess.Add(globalScenecontrollersIterator.Current.Value.systemBus);
 111                }
 1767112            }
 113
 1767114            if (globalControllerActive)
 115            {
 1762116                busesToProcess.Add(globalController.initBus);
 117            }
 118
 1767119            if (currentSceneControllerActive)
 120            {
 234121                busesToProcess.Add(currentSceneController.initBus);
 234122                busesToProcess.Add(currentSceneController.uiBus);
 234123                busesToProcess.Add(currentSceneController.systemBus);
 124            }
 125
 5932126            for (int i = 0; i < sortedControllersCount; ++i)
 127            {
 1199128                MessagingController msgController = sortedControllers[i];
 129
 1199130                busesToProcess.Add(msgController.initBus);
 1199131                busesToProcess.Add(msgController.uiBus);
 132            }
 133
 5932134            for (int i = 0; i < sortedControllersCount; ++i)
 135            {
 1199136                MessagingController msgController = sortedControllers[i];
 1199137                busesToProcess.Add(msgController.systemBus);
 138            }
 139
 1767140            busesToProcessCount = busesToProcess.Count;
 1767141        }
 142
 143        public void Dispose()
 144        {
 537145            if (mainCoroutine != null)
 146            {
 531147                CoroutineStarter.Stop(mainCoroutine);
 531148                mainCoroutine = null;
 149            }
 150
 537151            using (var controllersIterator = messagingControllers.GetEnumerator())
 152            {
 1594153                while (controllersIterator.MoveNext())
 154                {
 1057155                    controllersIterator.Current.Value.Stop();
 1057156                    DisposeController(controllersIterator.Current.Value);
 157                }
 537158            }
 159
 537160            Environment.i.world.sceneController.OnSortScenes -= PopulateBusesToBeProcessed;
 161
 537162            messagingControllers.Clear();
 537163        }
 164
 542165        public bool ContainsController(string sceneId) { return messagingControllers.ContainsKey(sceneId); }
 166
 167        public void AddController(IMessageProcessHandler messageHandler, string sceneId, bool isGlobal = false)
 168        {
 542169            if (!messagingControllers.ContainsKey(sceneId))
 542170                messagingControllers[sceneId] = new MessagingController(messageHandler, sceneId);
 171
 542172            if (isGlobal && !string.IsNullOrEmpty(sceneId))
 173            {
 7174                messagingControllers.TryGetValue(sceneId, out MessagingController newGlobalSceneController);
 175
 7176                if (!globalSceneControllers.ContainsKey(sceneId))
 7177                    globalSceneControllers.Add(sceneId, newGlobalSceneController);
 178            }
 179
 542180            PopulateBusesToBeProcessed();
 542181        }
 182
 183        public void AddControllerIfNotExists(IMessageProcessHandler messageHandler, string sceneId, bool isGlobal = fals
 184        {
 542185            if (!ContainsController(sceneId))
 542186                AddController(messageHandler, sceneId, isGlobal);
 542187        }
 188
 189        public void RemoveController(string sceneId)
 190        {
 542191            if (messagingControllers.ContainsKey(sceneId))
 192            {
 193                // In case there is any pending message from a scene being unloaded we decrease the count accordingly
 15194                pendingMessagesCount -= messagingControllers[sceneId].messagingBuses[MessagingBusType.INIT].pendingMessa
 195                                        messagingControllers[sceneId].messagingBuses[MessagingBusType.UI].pendingMessage
 196                                        messagingControllers[sceneId].messagingBuses[MessagingBusType.SYSTEM].pendingMes
 197
 15198                DisposeController(messagingControllers[sceneId]);
 15199                messagingControllers.Remove(sceneId);
 200            }
 201
 542202            globalSceneControllers.Remove(sceneId);
 542203        }
 204
 205        void DisposeController(MessagingController controller)
 206        {
 1072207            controller.Stop();
 1072208            controller.Dispose();
 1072209        }
 210
 0211        public void Enqueue(bool isUiBus, QueuedSceneMessage_Scene queuedMessage) { messagingControllers[queuedMessage.s
 212
 56213        public void ForceEnqueueToGlobal(MessagingBusType busId, QueuedSceneMessage queuedMessage) { messagingController
 214
 215        public void SetSceneReady(string sceneId)
 216        {
 217            // Start processing SYSTEM queue
 508218            if (messagingControllers.ContainsKey(sceneId))
 219            {
 220                // Start processing SYSTEM queue
 0221                MessagingController sceneMessagingController = messagingControllers[sceneId];
 0222                sceneMessagingController.StartBus(MessagingBusType.SYSTEM);
 0223                sceneMessagingController.StartBus(MessagingBusType.UI);
 0224                sceneMessagingController.StopBus(MessagingBusType.INIT);
 225            }
 508226        }
 227
 228        IEnumerator ProcessMessages()
 229        {
 6901230            while (true)
 231            {
 7432232                if (paused)
 233                {
 0234                    yield return null;
 0235                    continue;
 236                }
 237
 7432238                if (populateBusesDirty)
 239                {
 1225240                    PopulateBusesToBeProcessed();
 1225241                    populateBusesDirty = false;
 242                }
 243
 7432244                timeBudgetCounter = CommonScriptableObjects.rendererState.Get() ? MAX_GLOBAL_MSG_BUDGET : float.MaxValue
 245
 68622246                for (int i = 0; i < busesToProcessCount; ++i)
 247                {
 26879248                    MessagingBus bus = busesToProcess[i];
 249
 26879250                    if (ProcessBus(bus))
 251                        break;
 252                }
 253
 7432254                if (pendingInitMessagesCount == 0)
 255                {
 7432256                    UnityGLTF.GLTFSceneImporter.budgetPerFrameInMilliseconds = Mathf.Clamp(timeBudgetCounter, GLTF_BUDGE
 7432257                }
 258                else
 259                {
 0260                    UnityGLTF.GLTFSceneImporter.budgetPerFrameInMilliseconds = 0;
 261                }
 262
 7432263                yield return null;
 264            }
 265        }
 266
 267        bool ProcessBus(MessagingBus bus)
 268        {
 26879269            if (!bus.enabled || bus.pendingMessagesCount <= 0)
 26871270                return false;
 271
 8272            float startTime = Time.realtimeSinceStartup;
 273
 8274            float timeBudget = timeBudgetCounter;
 275
 276            //TODO(Brian): We should use the returning yieldReturn IEnumerator and MoveNext() it manually each frame to
 277            //             account the coroutine processing into the budget. Until we do that we just skip it.
 8278            bus.ProcessQueue(timeBudget, out _);
 8279            RefreshControllerEnabledState(bus.owner);
 280
 8281            timeBudgetCounter -= Time.realtimeSinceStartup - startTime;
 282
 8283            if (timeBudgetCounter <= 0)
 0284                return true;
 285
 8286            return false;
 287        }
 288
 289        private void RefreshControllerEnabledState(MessagingController controller)
 290        {
 8291            if (controller == null || !controller.enabled)
 0292                return;
 293
 8294            if (controller.uiBus.pendingMessagesCount != 0)
 0295                return;
 8296            if (controller.initBus.pendingMessagesCount != 0)
 0297                return;
 8298            if (controller.systemBus.pendingMessagesCount != 0)
 0299                return;
 300
 8301            controller.enabled = false;
 8302        }
 303    }
 304}