< Summary

Class:DCL.MessagingBus
Assembly:MainScripts
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/Scene/Messaging/MessagingBus.cs
Covered lines:97
Uncovered lines:34
Coverable lines:131
Total lines:316
Line coverage:74% (97 of 131)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
MessagingBus(...)0%110100%
Start()0%2100%
Stop()0%2.032080%
Dispose()0%110100%
Enqueue(...)0%16.0116096.97%
ProcessQueue(...)0%54.4426065.22%
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/Controllers/Scene/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 UnityEngine.SceneManagement;
 10
 11namespace DCL
 12{
 13    public enum QueueMode
 14    {
 15        Reliable,
 16        Lossy,
 17    }
 18
 19    public class MessagingBus : IDisposable
 20    {
 21        public static bool VERBOSE = false;
 22
 23        public IMessageProcessHandler handler;
 24
 199625        public LinkedList<QueuedSceneMessage> pendingMessages = new LinkedList<QueuedSceneMessage>();
 026        public bool hasPendingMessages => pendingMessagesCount > 0;
 27
 28        //NOTE(Brian): This is handled manually. We aren't using pendingMessages.Count because is slow. Used heavily on 
 29        public int pendingMessagesCount;
 030        public long processedMessagesCount { get; set; }
 31
 032        private static bool renderingIsDisabled => !CommonScriptableObjects.rendererState.Get();
 33        private float timeBudgetValue;
 34
 35        public CustomYieldInstruction msgYieldInstruction;
 36
 37        public MessagingBusType type;
 38        public string debugTag;
 39
 40        public MessagingController owner;
 41        private IMessagingControllersManager manager;
 42
 199643        Dictionary<string, LinkedListNode<QueuedSceneMessage>> unreliableMessages = new Dictionary<string, LinkedListNod
 44        public int unreliableMessagesReplaced = 0;
 45
 46        public bool enabled;
 47
 048        public float timeBudget { get => renderingIsDisabled ? float.MaxValue : timeBudgetValue; set => timeBudgetValue 
 49
 199650        public MessagingBus(MessagingBusType type, IMessageProcessHandler handler, MessagingController owner)
 51        {
 199652            Assert.IsNotNull(handler, "IMessageHandler can't be null!");
 199653            this.handler = handler;
 199654            this.enabled = false;
 199655            this.type = type;
 199656            this.owner = owner;
 199657            this.pendingMessagesCount = 0;
 199658            manager = owner.messagingManager;
 199659        }
 60
 061        public void Start() { enabled = true; }
 62
 63        public void Stop()
 64        {
 582365            enabled = false;
 66
 582367            if ( msgYieldInstruction is CleanableYieldInstruction cleanableYieldInstruction )
 068                cleanableYieldInstruction.Cleanup();
 69
 582370            pendingMessagesCount = 0;
 582371        }
 72
 393673        public void Dispose() { Stop(); }
 74
 75        public void Enqueue(QueuedSceneMessage message, QueueMode queueMode = QueueMode.Reliable)
 76        {
 3777            lock (unreliableMessages)
 78            {
 3779                if (message == null)
 080                    throw new Exception("A null message?");
 81
 3782                bool enqueued = true;
 83
 84                // When removing an entity we have to ensure that the enqueued lossy messages after it are processed and
 3785                if (message is QueuedSceneMessage_Scene queuedSceneMessage && queuedSceneMessage.payload is Protocol.Rem
 86                {
 187                    unreliableMessages = unreliableMessages
 188                                         .Where(kvp => !kvp.Key.Contains(removeEntityPayload.entityId))
 089                                         .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
 90                }
 91
 3792                if (queueMode == QueueMode.Reliable)
 93                {
 3394                    message.isUnreliable = false;
 3395                    AddReliableMessage(message);
 3396                }
 97                else
 98                {
 499                    LinkedListNode<QueuedSceneMessage> node = null;
 4100                    message.isUnreliable = true;
 4101                    message.unreliableMessageKey = message.tag;
 102
 4103                    if (unreliableMessages.ContainsKey(message.unreliableMessageKey))
 104                    {
 1105                        node = unreliableMessages[message.unreliableMessageKey];
 106
 1107                        if (node.List != null)
 108                        {
 1109                            node.Value = message;
 1110                            enqueued = false;
 1111                            unreliableMessagesReplaced++;
 112                        }
 113                    }
 114
 4115                    if (enqueued)
 116                    {
 3117                        node = AddReliableMessage(message);
 3118                        unreliableMessages[message.unreliableMessageKey] = node;
 119                    }
 120                }
 121
 37122                if (enqueued)
 123                {
 36124                    if (message.type == QueuedSceneMessage.Type.SCENE_MESSAGE)
 125                    {
 2126                        QueuedSceneMessage_Scene sm = message as QueuedSceneMessage_Scene;
 2127                        ProfilingEvents.OnMessageWillQueue?.Invoke(sm.method);
 128                    }
 129
 36130                    if (type == MessagingBusType.INIT)
 131                    {
 27132                        manager.pendingInitMessagesCount++;
 133                    }
 134
 36135                    if (owner != null)
 136                    {
 36137                        owner.enabled = true;
 36138                        manager.MarkBusesDirty();
 139                    }
 140                }
 37141            }
 37142        }
 143
 144        public bool ProcessQueue(float timeBudget, out IEnumerator yieldReturn)
 145        {
 14146            yieldReturn = null;
 147
 148            // Note (Zak): This check is to avoid calling Time.realtimeSinceStartup
 149            // unnecessarily because it's pretty slow in JS
 14150            if (timeBudget <= 0 || !enabled || pendingMessagesCount == 0)
 0151                return false;
 152
 14153            float startTime = Time.realtimeSinceStartup;
 154
 46155            while (enabled && pendingMessagesCount > 0 && Time.realtimeSinceStartup - startTime < timeBudget)
 156            {
 157                LinkedListNode<QueuedSceneMessage> pendingMessagesFirst;
 158
 32159                lock (pendingMessages)
 160                {
 32161                    pendingMessagesFirst = pendingMessages.First;
 32162                }
 163
 164                // Note (Kinerius): This may be caused by 2 threads fighting for messages
 32165                if (pendingMessagesFirst == null)
 166                {
 0167                    pendingMessagesCount = 0;
 168
 0169                    continue;
 170                }
 171
 32172                QueuedSceneMessage m = pendingMessagesFirst.Value;
 173
 32174                RemoveFirstReliableMessage();
 175
 32176                if (m.isUnreliable)
 0177                    RemoveUnreliableMessage(m);
 178
 32179                bool shouldLogMessage = VERBOSE;
 180
 32181                switch (m.type)
 182                {
 183                    case QueuedSceneMessage.Type.NONE:
 184                        break;
 185                    case QueuedSceneMessage.Type.SCENE_MESSAGE:
 186
 1187                        if (!(m is QueuedSceneMessage_Scene sceneMessage))
 188                            continue;
 189
 1190                        if (handler.ProcessMessage(sceneMessage, out msgYieldInstruction))
 191                        {
 192#if UNITY_EDITOR
 0193                            if (DataStore.i.debugConfig.msgStepByStep)
 194                            {
 0195                                if (VERBOSE)
 196                                {
 0197                                    LogMessage(m, this, false);
 0198                                    shouldLogMessage = false;
 199                                }
 200
 0201                                return true;
 202                            }
 203#endif
 204                        }
 205                        else
 206                        {
 1207                            shouldLogMessage = false;
 208                        }
 209
 1210                        OnMessageProcessed();
 1211                        ProfilingEvents.OnMessageWillDequeue?.Invoke(sceneMessage.method);
 212
 1213                        if (msgYieldInstruction != null)
 214                        {
 0215                            processedMessagesCount++;
 216
 0217                            msgYieldInstruction = null;
 218                        }
 219
 0220                        break;
 221                    case QueuedSceneMessage.Type.LOAD_PARCEL:
 27222                        handler.LoadParcelScenesExecute(m.message);
 27223                        ProfilingEvents.OnMessageWillDequeue?.Invoke("LoadScene");
 224
 0225                        break;
 226                    case QueuedSceneMessage.Type.UNLOAD_PARCEL:
 2227                        handler.UnloadParcelSceneExecute(m.message);
 2228                        ProfilingEvents.OnMessageWillDequeue?.Invoke("UnloadScene");
 229
 0230                        break;
 231                    case QueuedSceneMessage.Type.UPDATE_PARCEL:
 1232                        handler.UpdateParcelScenesExecute(m.message);
 1233                        ProfilingEvents.OnMessageWillDequeue?.Invoke("UpdateScene");
 234
 0235                        break;
 236                    case QueuedSceneMessage.Type.UNLOAD_SCENES:
 1237                        handler.UnloadAllScenes();
 1238                        ProfilingEvents.OnMessageWillDequeue?.Invoke("UnloadAllScenes");
 239
 240                        break;
 241                }
 242
 32243                OnMessageProcessed();
 244#if UNITY_EDITOR
 32245                if (shouldLogMessage)
 246                {
 0247                    LogMessage(m, this);
 248                }
 249#endif
 250            }
 251
 14252            return false;
 253        }
 254
 255        public void OnMessageProcessed()
 256        {
 33257            processedMessagesCount++;
 258
 33259            if (type == MessagingBusType.INIT)
 260            {
 27261                manager.pendingInitMessagesCount--;
 27262                manager.processedInitMessagesCount++;
 263            }
 33264        }
 265
 266        private LinkedListNode<QueuedSceneMessage> AddReliableMessage(QueuedSceneMessage message)
 267        {
 36268            manager.pendingMessagesCount++;
 36269            pendingMessagesCount++;
 270
 271            LinkedListNode<QueuedSceneMessage> addReliableMessage;
 272
 36273            lock (pendingMessages)
 274            {
 36275                addReliableMessage  = pendingMessages.AddLast(message);
 36276            }
 277
 36278            return addReliableMessage;
 279        }
 280
 281        private void RemoveFirstReliableMessage()
 282        {
 32283            lock (pendingMessages)
 284            {
 32285                if (pendingMessages.First != null)
 286                {
 32287                    pendingMessages.RemoveFirst();
 32288                    pendingMessagesCount--;
 32289                    manager.pendingMessagesCount--;
 290                }
 32291            }
 32292        }
 293
 294        private void RemoveUnreliableMessage(QueuedSceneMessage message)
 295        {
 0296            lock (unreliableMessages)
 297            {
 0298                unreliableMessages.Remove(message.unreliableMessageKey);
 0299            }
 0300        }
 301
 302        private void LogMessage(QueuedSceneMessage m, MessagingBus bus, bool logType = true)
 303        {
 0304            string finalTag = WorldStateUtils.TryToGetSceneCoordsID(bus.debugTag);
 305
 0306            if (logType)
 307            {
 0308                Debug.Log($"#{bus.processedMessagesCount} ... bus = {finalTag}, id = {bus.type}... processing msg... typ
 0309            }
 310            else
 311            {
 0312                Debug.Log($"#{bus.processedMessagesCount} ... Bus = {finalTag}, id = {bus.type}... processing msg... {m.
 313            }
 0314        }
 315    }
 316}