< 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:102
Uncovered lines:30
Coverable lines:132
Total lines:334
Line coverage:77.2% (102 of 132)
Covered branches:0
Total branches:0

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.0116096.77%
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
 162726        public LinkedList<QueuedSceneMessage> pendingMessages = new LinkedList<QueuedSceneMessage>();
 1727        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;
 8631        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
 162744        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
 162757        public MessagingBus(MessagingBusType type, IMessageProcessHandler handler, MessagingController owner)
 58        {
 162759            Assert.IsNotNull(handler, "IMessageHandler can't be null!");
 162760            this.handler = handler;
 162761            this.enabled = false;
 162762            this.type = type;
 162763            this.owner = owner;
 162764            this.pendingMessagesCount = 0;
 162765            manager = owner.messagingManager;
 162766        }
 67
 68        public void Start()
 69        {
 108970            enabled = true;
 108971        }
 72
 73        public void Stop()
 74        {
 467975            enabled = false;
 76
 467977            if (msgYieldInstruction is CleanableYieldInstruction cleanableYieldInstruction)
 078                cleanableYieldInstruction.Cleanup();
 79
 467980            pendingMessagesCount = 0;
 467981        }
 82
 83        public void Dispose()
 84        {
 159985            Stop();
 159986        }
 87
 88        public void Enqueue(QueuedSceneMessage message, QueueMode queueMode = QueueMode.Reliable)
 89        {
 4590            lock (unreliableMessages)
 91            {
 92                // TODO: If we check here for 'if (message == null || string.IsNullOrEmpty(message.message))' loading th
 4593                if (message == null)
 094                    throw new Exception("A null message?");
 95
 4596                bool enqueued = true;
 97
 98                // When removing an entity we have to ensure that the enqueued lossy messages after it are processed and
 4599                if (message is QueuedSceneMessage_Scene queuedSceneMessage &&
 100                    queuedSceneMessage.payload is Protocol.RemoveEntity removeEntityPayload)
 101                {
 1102                    unreliableMessages = unreliableMessages
 1103                        .Where(kvp => !kvp.Key.Contains(removeEntityPayload.entityId))
 0104                        .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
 105                }
 106
 45107                if (queueMode == QueueMode.Reliable)
 108                {
 41109                    message.isUnreliable = false;
 41110                    AddReliableMessage(message);
 111                }
 112                else
 113                {
 4114                    LinkedListNode<QueuedSceneMessage> node = null;
 4115                    message.isUnreliable = true;
 116
 4117                    if (unreliableMessages.ContainsKey(message.tag))
 118                    {
 1119                        node = unreliableMessages[message.tag];
 120
 1121                        if (node.List != null)
 122                        {
 1123                            node.Value = message;
 1124                            enqueued = false;
 1125                            unreliableMessagesReplaced++;
 126                        }
 127                    }
 128
 4129                    if (enqueued)
 130                    {
 3131                        node = AddReliableMessage(message);
 3132                        unreliableMessages[message.tag] = node;
 133                    }
 134                }
 135
 45136                if (enqueued)
 137                {
 44138                    if (message.type == QueuedSceneMessage.Type.SCENE_MESSAGE)
 139                    {
 4140                        QueuedSceneMessage_Scene sm = message as QueuedSceneMessage_Scene;
 4141                        ProfilingEvents.OnMessageWillQueue?.Invoke(sm.method);
 142                    }
 143
 44144                    if (type == MessagingBusType.INIT)
 145                    {
 35146                        manager.pendingInitMessagesCount++;
 147                    }
 148
 44149                    if (owner != null)
 150                    {
 44151                        owner.enabled = true;
 44152                        manager.MarkBusesDirty();
 153                    }
 154                }
 45155            }
 45156        }
 157
 158        public bool ProcessQueue(float timeBudget, out IEnumerator yieldReturn)
 159        {
 20160            yieldReturn = null;
 161
 162            // Note (Zak): This check is to avoid calling Time.realtimeSinceStartup
 163            // unnecessarily because it's pretty slow in JS
 20164            if (timeBudget <= 0 || !enabled || pendingMessagesCount == 0)
 0165                return false;
 166
 20167            float startTime = Time.realtimeSinceStartup;
 168
 60169            while (enabled && pendingMessagesCount > 0 && Time.realtimeSinceStartup - startTime < timeBudget)
 170            {
 171                LinkedListNode<QueuedSceneMessage> pendingMessagesFirst;
 172
 40173                lock (pendingMessages)
 174                {
 40175                    pendingMessagesFirst = pendingMessages.First;
 40176                }
 177
 178                // Note (Kinerius): This may be caused by 2 threads fighting for messages
 40179                if (pendingMessagesFirst == null)
 180                {
 0181                    pendingMessagesCount = 0;
 182
 0183                    continue;
 184                }
 185
 40186                QueuedSceneMessage m = pendingMessagesFirst.Value;
 187
 40188                PerformanceAnalytics.MessagesProcessedTracker.Track();
 189
 40190                RemoveFirstReliableMessage();
 191
 40192                if (m.isUnreliable)
 0193                    RemoveUnreliableMessage(m);
 194
 40195                bool shouldLogMessage = VERBOSE;
 196
 40197                switch (m.type)
 198                {
 199                    case QueuedSceneMessage.Type.NONE:
 200                        break;
 201                    case QueuedSceneMessage.Type.SCENE_MESSAGE:
 202
 3203                        if (!(m is QueuedSceneMessage_Scene sceneMessage))
 204                            continue;
 205
 3206                        if (handler.ProcessMessage(sceneMessage, out msgYieldInstruction))
 207                        {
 208#if UNITY_EDITOR
 2209                            if (DataStore.i.debugConfig.msgStepByStep)
 210                            {
 0211                                if (VERBOSE)
 212                                {
 0213                                    LogMessage(m, this, false);
 0214                                    shouldLogMessage = false;
 215                                }
 216
 0217                                return true;
 218                            }
 219#endif
 220                        }
 221                        else
 222                        {
 1223                            shouldLogMessage = false;
 224                        }
 225
 3226                        OnMessageProcessed();
 3227                        ProfilingEvents.OnMessageWillDequeue?.Invoke(sceneMessage.method);
 228
 3229                        if (msgYieldInstruction != null)
 230                        {
 0231                            processedMessagesCount++;
 232
 0233                            msgYieldInstruction = null;
 234                        }
 235
 0236                        break;
 237                    case QueuedSceneMessage.Type.LOAD_PARCEL:
 31238                        handler.LoadParcelScenesExecute(m.message);
 31239                        ProfilingEvents.OnMessageWillDequeue?.Invoke("LoadScene");
 240
 0241                        break;
 242                    case QueuedSceneMessage.Type.UNLOAD_PARCEL:
 4243                        handler.UnloadParcelSceneExecute(m.sceneNumber);
 4244                        ProfilingEvents.OnMessageWillDequeue?.Invoke("UnloadScene");
 245
 0246                        break;
 247                    case QueuedSceneMessage.Type.UPDATE_PARCEL:
 1248                        handler.UpdateParcelScenesExecute(m.message);
 1249                        ProfilingEvents.OnMessageWillDequeue?.Invoke("UpdateScene");
 250
 0251                        break;
 252                    case QueuedSceneMessage.Type.UNLOAD_SCENES:
 1253                        handler.UnloadAllScenes();
 1254                        ProfilingEvents.OnMessageWillDequeue?.Invoke("UnloadAllScenes");
 255
 256                        break;
 257                }
 258
 40259                OnMessageProcessed();
 260#if UNITY_EDITOR
 40261                if (shouldLogMessage)
 262                {
 0263                    LogMessage(m, this);
 264                }
 265#endif
 266            }
 267
 20268            return false;
 269        }
 270
 271        public void OnMessageProcessed()
 272        {
 43273            processedMessagesCount++;
 274
 43275            if (type == MessagingBusType.INIT)
 276            {
 37277                manager.pendingInitMessagesCount--;
 37278                manager.processedInitMessagesCount++;
 279            }
 43280        }
 281
 282        private LinkedListNode<QueuedSceneMessage> AddReliableMessage(QueuedSceneMessage message)
 283        {
 44284            manager.pendingMessagesCount++;
 44285            pendingMessagesCount++;
 286
 287            LinkedListNode<QueuedSceneMessage> addReliableMessage;
 288
 44289            lock (pendingMessages)
 290            {
 44291                addReliableMessage = pendingMessages.AddLast(message);
 44292            }
 293
 44294            return addReliableMessage;
 295        }
 296
 297        private void RemoveFirstReliableMessage()
 298        {
 40299            lock (pendingMessages)
 300            {
 40301                if (pendingMessages.First != null)
 302                {
 40303                    pendingMessages.RemoveFirst();
 40304                    pendingMessagesCount--;
 40305                    manager.pendingMessagesCount--;
 306                }
 40307            }
 40308        }
 309
 310        private void RemoveUnreliableMessage(QueuedSceneMessage message)
 311        {
 0312            lock (unreliableMessages)
 313            {
 0314                unreliableMessages.Remove(message.tag);
 0315            }
 0316        }
 317
 318        private void LogMessage(QueuedSceneMessage m, MessagingBus bus, bool logType = true)
 319        {
 0320            string finalTag = WorldStateUtils.TryToGetSceneCoordsFromSceneNumber(bus.debugSceneNumber);
 321
 0322            if (logType)
 323            {
 0324                Debug.Log(
 325                    $"#{bus.processedMessagesCount} ... bus = {finalTag}, id = {bus.type}... processing msg... type = {m
 326            }
 327            else
 328            {
 0329                Debug.Log(
 330                    $"#{bus.processedMessagesCount} ... Bus = {finalTag}, id = {bus.type}... processing msg... {m.messag
 331            }
 0332        }
 333    }
 334}