< Summary

Class:DCL.MessagingBus
Assembly:DCL.Runtime
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/WorldRuntime/Messaging/MessagingBus.cs
Covered lines:105
Uncovered lines:30
Coverable lines:135
Total lines:339
Line coverage:77.7% (105 of 135)
Covered branches:0
Total branches:0
Covered methods:12
Total methods:17
Method coverage:70.5% (12 of 17)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
MessagingBus(...)0%110100%
Start()0%110100%
Stop()0%2.032080%
Dispose()0%110100%
Enqueue(...)0%16.0416094.59%
ProcessQueue(...)0%47.9626068.09%
OnMessageProcessed()0%220100%
AddReliableMessage(...)0%220100%
RemoveFirstReliableMessage()0%330100%
RemoveUnreliableMessage(...)0%6200%
LogMessage(...)0%6200%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/WorldRuntime/Messaging/MessagingBus.cs

#LineLine coverage
 1using System;
 2using System.Collections;
 3using System.Collections.Generic;
 4using System.Linq;
 5using UnityEngine;
 6using UnityEngine.Assertions;
 7using DCL.Interface;
 8using DCL.Models;
 9using MainScripts.DCL.Analytics.PerformanceAnalytics;
 10using UnityEngine.SceneManagement;
 11
 12namespace DCL
 13{
 14    public enum QueueMode
 15    {
 16        Reliable,
 17        Lossy,
 18    }
 19
 20    public class MessagingBus : IDisposable
 21    {
 22        public static bool VERBOSE = false;
 23
 24        public IMessageProcessHandler handler;
 25
 142626        public LinkedList<QueuedSceneMessage> pendingMessages = new LinkedList<QueuedSceneMessage>();
 627        public bool hasPendingMessages => pendingMessagesCount > 0;
 28
 29        //NOTE(Brian): This is handled manually. We aren't using pendingMessages.Count because is slow. Used heavily on 
 30        public int pendingMessagesCount;
 7631        public long processedMessagesCount { get; set; }
 32
 033        private static bool renderingIsDisabled => !CommonScriptableObjects.rendererState.Get();
 34        private float timeBudgetValue;
 35
 36        public CustomYieldInstruction msgYieldInstruction;
 37
 38        public MessagingBusType type;
 39        public int debugSceneNumber;
 40
 41        public MessagingController owner;
 42        private IMessagingControllersManager manager;
 43
 142644        Dictionary<string, LinkedListNode<QueuedSceneMessage>> unreliableMessages =
 45            new Dictionary<string, LinkedListNode<QueuedSceneMessage>>();
 46
 47        public int unreliableMessagesReplaced = 0;
 48
 49        public bool enabled;
 50
 51        public float timeBudget
 52        {
 053            get => renderingIsDisabled ? float.MaxValue : timeBudgetValue;
 054            set => timeBudgetValue = value;
 55        }
 56
 142657        public MessagingBus(MessagingBusType type, IMessageProcessHandler handler, MessagingController owner)
 58        {
 142659            Assert.IsNotNull(handler, "IMessageHandler can't be null!");
 142660            this.handler = handler;
 142661            this.enabled = false;
 142662            this.type = type;
 142663            this.owner = owner;
 142664            this.pendingMessagesCount = 0;
 142665            manager = owner.messagingManager;
 142666        }
 67
 68        public void Start()
 69        {
 95370            enabled = true;
 95371        }
 72
 73        public void Stop()
 74        {
 407275            enabled = false;
 76
 407277            if (msgYieldInstruction is CleanableYieldInstruction cleanableYieldInstruction)
 078                cleanableYieldInstruction.Cleanup();
 79
 407280            pendingMessagesCount = 0;
 407281        }
 82
 83        public void Dispose()
 84        {
 139885            Stop();
 139886        }
 87
 142688        Dictionary<string, LinkedListNode<QueuedSceneMessage>> tempDictionary = new Dictionary<string, LinkedListNode<Qu
 89
 90        public void Enqueue(QueuedSceneMessage message, QueueMode queueMode = QueueMode.Reliable)
 91        {
 4192            lock (unreliableMessages)
 93            {
 94                // TODO: If we check here for 'if (message == null || string.IsNullOrEmpty(message.message))' loading th
 4195                if (message == null)
 096                    throw new Exception("A null message?");
 97
 4198                bool enqueued = true;
 99
 100                // When removing an entity we have to ensure that the enqueued lossy messages after it are processed and
 41101                if (message is QueuedSceneMessage_Scene { payload: Protocol.RemoveEntity removeEntityPayload })
 102                {
 1103                    tempDictionary.Clear();
 104
 4105                    foreach (var unreliableMessage in unreliableMessages)
 1106                        if (!unreliableMessage.Key.Contains(removeEntityPayload.entityId))
 0107                            tempDictionary.Add(unreliableMessage.Key, unreliableMessage.Value);
 108
 1109                    unreliableMessages = tempDictionary;
 110                }
 111
 41112                if (queueMode == QueueMode.Reliable)
 113                {
 37114                    message.isUnreliable = false;
 37115                    AddReliableMessage(message);
 116                }
 117                else
 118                {
 4119                    LinkedListNode<QueuedSceneMessage> node = null;
 4120                    message.isUnreliable = true;
 121
 4122                    if (unreliableMessages.ContainsKey(message.tag))
 123                    {
 1124                        node = unreliableMessages[message.tag];
 125
 1126                        if (node.List != null)
 127                        {
 1128                            node.Value = message;
 1129                            enqueued = false;
 1130                            unreliableMessagesReplaced++;
 131                        }
 132                    }
 133
 4134                    if (enqueued)
 135                    {
 3136                        node = AddReliableMessage(message);
 3137                        unreliableMessages[message.tag] = node;
 138                    }
 139                }
 140
 41141                if (enqueued)
 142                {
 40143                    if (message.type == QueuedSceneMessage.Type.SCENE_MESSAGE)
 144                    {
 3145                        QueuedSceneMessage_Scene sm = message as QueuedSceneMessage_Scene;
 3146                        ProfilingEvents.OnMessageWillQueue?.Invoke(sm.method);
 147                    }
 148
 40149                    if (type == MessagingBusType.INIT)
 150                    {
 31151                        manager.pendingInitMessagesCount++;
 152                    }
 153
 40154                    if (owner != null)
 155                    {
 40156                        owner.enabled = true;
 40157                        manager.MarkBusesDirty();
 158                    }
 159                }
 41160            }
 41161        }
 162
 163        public bool ProcessQueue(float timeBudget, out IEnumerator yieldReturn)
 164        {
 16165            yieldReturn = null;
 166
 167            // Note (Zak): This check is to avoid calling Time.realtimeSinceStartup
 168            // unnecessarily because it's pretty slow in JS
 16169            if (timeBudget <= 0 || !enabled || pendingMessagesCount == 0)
 0170                return false;
 171
 16172            float startTime = Time.realtimeSinceStartup;
 173
 52174            while (enabled && pendingMessagesCount > 0 && Time.realtimeSinceStartup - startTime < timeBudget)
 175            {
 176                LinkedListNode<QueuedSceneMessage> pendingMessagesFirst;
 177
 36178                lock (pendingMessages)
 179                {
 36180                    pendingMessagesFirst = pendingMessages.First;
 36181                }
 182
 183                // Note (Kinerius): This may be caused by 2 threads fighting for messages
 36184                if (pendingMessagesFirst == null)
 185                {
 0186                    pendingMessagesCount = 0;
 187
 0188                    continue;
 189                }
 190
 36191                QueuedSceneMessage m = pendingMessagesFirst.Value;
 192
 36193                PerformanceAnalytics.MessagesProcessedTracker.Track();
 194
 36195                RemoveFirstReliableMessage();
 196
 36197                if (m.isUnreliable)
 0198                    RemoveUnreliableMessage(m);
 199
 36200                bool shouldLogMessage = VERBOSE;
 201
 36202                switch (m.type)
 203                {
 204                    case QueuedSceneMessage.Type.NONE:
 205                        break;
 206                    case QueuedSceneMessage.Type.SCENE_MESSAGE:
 207
 2208                        if (!(m is QueuedSceneMessage_Scene sceneMessage))
 209                            continue;
 210
 2211                        if (handler.ProcessMessage(sceneMessage, out msgYieldInstruction))
 212                        {
 213#if UNITY_EDITOR
 1214                            if (DataStore.i.debugConfig.msgStepByStep)
 215                            {
 0216                                if (VERBOSE)
 217                                {
 0218                                    LogMessage(m, this, false);
 0219                                    shouldLogMessage = false;
 220                                }
 221
 0222                                return true;
 223                            }
 224#endif
 225                        }
 226                        else
 227                        {
 1228                            shouldLogMessage = false;
 229                        }
 230
 2231                        OnMessageProcessed();
 2232                        ProfilingEvents.OnMessageWillDequeue?.Invoke(sceneMessage.method);
 233
 2234                        if (msgYieldInstruction != null)
 235                        {
 0236                            processedMessagesCount++;
 237
 0238                            msgYieldInstruction = null;
 239                        }
 240
 0241                        break;
 242                    case QueuedSceneMessage.Type.LOAD_PARCEL:
 29243                        handler.LoadParcelScenesExecute(m.message);
 29244                        ProfilingEvents.OnMessageWillDequeue?.Invoke("LoadScene");
 245
 0246                        break;
 247                    case QueuedSceneMessage.Type.UNLOAD_PARCEL:
 3248                        handler.UnloadParcelSceneExecute(m.sceneNumber);
 3249                        ProfilingEvents.OnMessageWillDequeue?.Invoke("UnloadScene");
 250
 0251                        break;
 252                    case QueuedSceneMessage.Type.UPDATE_PARCEL:
 1253                        handler.UpdateParcelScenesExecute(m.message);
 1254                        ProfilingEvents.OnMessageWillDequeue?.Invoke("UpdateScene");
 255
 0256                        break;
 257                    case QueuedSceneMessage.Type.UNLOAD_SCENES:
 1258                        handler.UnloadAllScenes();
 1259                        ProfilingEvents.OnMessageWillDequeue?.Invoke("UnloadAllScenes");
 260
 261                        break;
 262                }
 263
 36264                OnMessageProcessed();
 265#if UNITY_EDITOR
 36266                if (shouldLogMessage)
 267                {
 0268                    LogMessage(m, this);
 269                }
 270#endif
 271            }
 272
 16273            return false;
 274        }
 275
 276        public void OnMessageProcessed()
 277        {
 38278            processedMessagesCount++;
 279
 38280            if (type == MessagingBusType.INIT)
 281            {
 32282                manager.pendingInitMessagesCount--;
 32283                manager.processedInitMessagesCount++;
 284            }
 38285        }
 286
 287        private LinkedListNode<QueuedSceneMessage> AddReliableMessage(QueuedSceneMessage message)
 288        {
 40289            manager.pendingMessagesCount++;
 40290            pendingMessagesCount++;
 291
 292            LinkedListNode<QueuedSceneMessage> addReliableMessage;
 293
 40294            lock (pendingMessages)
 295            {
 40296                addReliableMessage = pendingMessages.AddLast(message);
 40297            }
 298
 40299            return addReliableMessage;
 300        }
 301
 302        private void RemoveFirstReliableMessage()
 303        {
 36304            lock (pendingMessages)
 305            {
 36306                if (pendingMessages.First != null)
 307                {
 36308                    pendingMessages.RemoveFirst();
 36309                    pendingMessagesCount--;
 36310                    manager.pendingMessagesCount--;
 311                }
 36312            }
 36313        }
 314
 315        private void RemoveUnreliableMessage(QueuedSceneMessage message)
 316        {
 0317            lock (unreliableMessages)
 318            {
 0319                unreliableMessages.Remove(message.tag);
 0320            }
 0321        }
 322
 323        private void LogMessage(QueuedSceneMessage m, MessagingBus bus, bool logType = true)
 324        {
 0325            string finalTag = WorldStateUtils.TryToGetSceneCoordsFromSceneNumber(bus.debugSceneNumber);
 326
 0327            if (logType)
 328            {
 0329                Debug.Log(
 330                    $"#{bus.processedMessagesCount} ... bus = {finalTag}, id = {bus.type}... processing msg... type = {m
 331            }
 332            else
 333            {
 0334                Debug.Log(
 335                    $"#{bus.processedMessagesCount} ... Bus = {finalTag}, id = {bus.type}... processing msg... {m.messag
 336            }
 0337        }
 338    }
 339}