< 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:118
Uncovered lines:16
Coverable lines:134
Total lines:304
Line coverage:88% (118 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%17.3517089.36%
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.1711088.89%
ProcessBus(...)0%440100%
RefreshControllerEnabledState(...)0%6.976070%

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
 64820        public Dictionary<string, MessagingController> messagingControllers { get; set; } = new Dictionary<string, Messa
 21
 22        private Coroutine mainCoroutine;
 23
 2824        public bool hasPendingMessages => pendingMessagesCount > 0;
 25
 64826        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
 4233        public bool paused { get; set; }
 34
 64835        private Dictionary<string, MessagingController> globalSceneControllers = new Dictionary<string, MessagingControl
 64836        private List<MessagingController> sortedControllers = new List<MessagingController>();
 64837        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        {
 64846            messagingControllers[GLOBAL_MESSAGING_CONTROLLER] = new MessagingController(messageHandler, GLOBAL_MESSAGING
 47
 64848            if (!string.IsNullOrEmpty(GLOBAL_MESSAGING_CONTROLLER))
 64849                messagingControllers.TryGetValue(GLOBAL_MESSAGING_CONTROLLER, out globalController);
 50
 64851            Environment.i.world.sceneController.OnSortScenes += MarkBusesDirty;
 52
 64853            if (mainCoroutine == null)
 54            {
 64855                mainCoroutine = CoroutineStarter.Start(ProcessMessages());
 56            }
 64857        }
 58
 64859        bool populateBusesDirty = true;
 60
 120661        public void MarkBusesDirty() { populateBusesDirty = true; }
 62
 63        public void PopulateBusesToBeProcessed()
 64        {
 128365            IWorldState worldState = Environment.i.world.state;
 128366            string currentSceneId = worldState.currentSceneId;
 128367            List<IParcelScene> scenesSortedByDistance = worldState.scenesSortedByDistance;
 68
 128369            int count = scenesSortedByDistance.Count; // we need to retrieve list count everytime because it
 70            // may change after a yield return
 71
 128372            sortedControllers.Clear();
 73
 128374            if (!string.IsNullOrEmpty(currentSceneId) && messagingControllers.ContainsKey(currentSceneId))
 075                currentSceneController = messagingControllers[currentSceneId];
 76
 295277            for (int i = 0; i < count; i++)
 78            {
 19379                string controllerId = scenesSortedByDistance[i].sceneData.id;
 80
 19381                if (controllerId != currentSceneId)
 82                {
 18383                    if (!messagingControllers.ContainsKey(controllerId))
 84                        continue;
 85
 15586                    sortedControllers.Add(messagingControllers[controllerId]);
 87                }
 88            }
 89
 128390            sortedControllersCount = sortedControllers.Count;
 91
 128392            bool globalSceneControllerActive = globalSceneControllers.Count > 0;
 128393            bool globalControllerActive = globalController != null && globalController.enabled;
 128394            bool currentSceneControllerActive = currentSceneController != null && currentSceneController.enabled;
 95
 128396            bool atLeastOneControllerShouldBeProcessed = globalSceneControllerActive || globalControllerActive || curren
 97
 128398            if (!atLeastOneControllerShouldBeProcessed)
 099                return;
 100
 1283101            busesToProcess.Clear();
 102            //-------------------------------------------------------------------------------------------
 103            // Global scenes
 1283104            using (var globalScenecontrollersIterator = globalSceneControllers.GetEnumerator())
 105            {
 1285106                while (globalScenecontrollersIterator.MoveNext())
 107                {
 2108                    busesToProcess.Add(globalScenecontrollersIterator.Current.Value.uiBus);
 2109                    busesToProcess.Add(globalScenecontrollersIterator.Current.Value.initBus);
 2110                    busesToProcess.Add(globalScenecontrollersIterator.Current.Value.systemBus);
 111                }
 1283112            }
 113
 1283114            if (globalControllerActive)
 115            {
 1280116                busesToProcess.Add(globalController.initBus);
 117            }
 118
 1283119            if (currentSceneControllerActive)
 120            {
 0121                busesToProcess.Add(currentSceneController.initBus);
 0122                busesToProcess.Add(currentSceneController.uiBus);
 0123                busesToProcess.Add(currentSceneController.systemBus);
 124            }
 125
 2876126            for (int i = 0; i < sortedControllersCount; ++i)
 127            {
 155128                MessagingController msgController = sortedControllers[i];
 129
 155130                busesToProcess.Add(msgController.initBus);
 155131                busesToProcess.Add(msgController.uiBus);
 132            }
 133
 2876134            for (int i = 0; i < sortedControllersCount; ++i)
 135            {
 155136                MessagingController msgController = sortedControllers[i];
 155137                busesToProcess.Add(msgController.systemBus);
 138            }
 139
 1283140            busesToProcessCount = busesToProcess.Count;
 1283141        }
 142
 143        public void Dispose()
 144        {
 653145            if (mainCoroutine != null)
 146            {
 648147                CoroutineStarter.Stop(mainCoroutine);
 648148                mainCoroutine = null;
 149            }
 150
 653151            using (var controllersIterator = messagingControllers.GetEnumerator())
 152            {
 1316153                while (controllersIterator.MoveNext())
 154                {
 663155                    controllersIterator.Current.Value.Stop();
 663156                    DisposeController(controllersIterator.Current.Value);
 157                }
 653158            }
 159
 653160            Environment.i.world.sceneController.OnSortScenes -= PopulateBusesToBeProcessed;
 161
 653162            messagingControllers.Clear();
 653163        }
 164
 27165        public bool ContainsController(string sceneId) { return messagingControllers.ContainsKey(sceneId); }
 166
 167        public void AddController(IMessageProcessHandler messageHandler, string sceneId, bool isGlobal = false)
 168        {
 27169            if (!messagingControllers.ContainsKey(sceneId))
 27170                messagingControllers[sceneId] = new MessagingController(messageHandler, sceneId);
 171
 27172            if (isGlobal && !string.IsNullOrEmpty(sceneId))
 173            {
 1174                messagingControllers.TryGetValue(sceneId, out MessagingController newGlobalSceneController);
 175
 1176                if (!globalSceneControllers.ContainsKey(sceneId))
 1177                    globalSceneControllers.Add(sceneId, newGlobalSceneController);
 178            }
 179
 27180            PopulateBusesToBeProcessed();
 27181        }
 182
 183        public void AddControllerIfNotExists(IMessageProcessHandler messageHandler, string sceneId, bool isGlobal = fals
 184        {
 27185            if (!ContainsController(sceneId))
 27186                AddController(messageHandler, sceneId, isGlobal);
 27187        }
 188
 189        public void RemoveController(string sceneId)
 190        {
 401191            if (messagingControllers.ContainsKey(sceneId))
 192            {
 193                // In case there is any pending message from a scene being unloaded we decrease the count accordingly
 12194                pendingMessagesCount -= messagingControllers[sceneId].messagingBuses[MessagingBusType.INIT].pendingMessa
 195                                        messagingControllers[sceneId].messagingBuses[MessagingBusType.UI].pendingMessage
 196                                        messagingControllers[sceneId].messagingBuses[MessagingBusType.SYSTEM].pendingMes
 197
 12198                DisposeController(messagingControllers[sceneId]);
 12199                messagingControllers.Remove(sceneId);
 200            }
 201
 401202            globalSceneControllers.Remove(sceneId);
 401203        }
 204
 205        void DisposeController(MessagingController controller)
 206        {
 675207            controller.Stop();
 675208            controller.Dispose();
 675209        }
 210
 0211        public void Enqueue(bool isUiBus, QueuedSceneMessage_Scene queuedMessage) { messagingControllers[queuedMessage.s
 212
 54213        public void ForceEnqueueToGlobal(MessagingBusType busId, QueuedSceneMessage queuedMessage) { messagingController
 214
 215        public void SetSceneReady(string sceneId)
 216        {
 217            // Start processing SYSTEM queue
 376218            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            }
 376226        }
 227
 228        IEnumerator ProcessMessages()
 229        {
 11457230            while (true)
 231            {
 12105232                if (paused)
 233                {
 0234                    yield return null;
 0235                    continue;
 236                }
 237
 12105238                if (populateBusesDirty)
 239                {
 1256240                    PopulateBusesToBeProcessed();
 1256241                    populateBusesDirty = false;
 242                }
 243
 12105244                timeBudgetCounter = CommonScriptableObjects.rendererState.Get() ? MAX_GLOBAL_MSG_BUDGET : float.MaxValue
 245
 48686246                for (int i = 0; i < busesToProcessCount; ++i)
 247                {
 12241248                    MessagingBus bus = busesToProcess[i];
 249
 12241250                    if (ProcessBus(bus))
 251                        break;
 252                }
 253
 12105254                if (pendingInitMessagesCount == 0)
 255                {
 12103256                    AssetPromiseKeeper_GLTF.i.throttlingCounter.budgetPerFrameInMilliseconds = Mathf.Clamp(timeBudgetCou
 12103257                }
 258                else
 259                {
 2260                    AssetPromiseKeeper_GLTF.i.throttlingCounter.budgetPerFrameInMilliseconds = 0;
 261                }
 262
 12105263                yield return null;
 264            }
 265        }
 266
 267        bool ProcessBus(MessagingBus bus)
 268        {
 12241269            if (!bus.enabled || bus.pendingMessagesCount <= 0)
 12232270                return false;
 271
 9272            float startTime = Time.realtimeSinceStartup;
 273
 9274            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.
 9278            bus.ProcessQueue(timeBudget, out _);
 9279            RefreshControllerEnabledState(bus.owner);
 280
 9281            timeBudgetCounter -= Time.realtimeSinceStartup - startTime;
 282
 9283            if (timeBudgetCounter <= 0)
 3284                return true;
 285
 6286            return false;
 287        }
 288
 289        private void RefreshControllerEnabledState(MessagingController controller)
 290        {
 9291            if (controller == null || !controller.enabled)
 0292                return;
 293
 9294            if (controller.uiBus.pendingMessagesCount != 0)
 0295                return;
 9296            if (controller.initBus.pendingMessagesCount != 0)
 2297                return;
 7298            if (controller.systemBus.pendingMessagesCount != 0)
 0299                return;
 300
 7301            controller.enabled = false;
 7302        }
 303    }
 304}