< Summary

Class:Mailbox
Assembly:bamlab.micromissiles
File(s):/github/workspace/Assets/Scripts/Communication/Mailbox.cs
Covered lines:36
Uncovered lines:12
Coverable lines:48
Total lines:79
Line coverage:75% (36 of 48)
Covered branches:0
Total branches:0
Covered methods:5
Total methods:6
Method coverage:83.3% (5 of 6)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
Mailbox()0%110100%
Mailbox()0%110100%
Send(...)0%7.646064.29%
Deliver()0%440100%
Clear()0%2100%
GetLinkConfig(...)0%16.119055.56%

File(s)

/github/workspace/Assets/Scripts/Communication/Mailbox.cs

#LineLine coverage
 1using System;
 2using UnityEngine;
 3
 4// The mailbox handles the communication latencies for agent-to-agent communication. The mailbox
 5// owns the message queue and releases messages to be delivered after a set latency.
 6public class Mailbox {
 17  private static readonly Configs.LinkConfig _defaultLinkConfig = new Configs.LinkConfig {
 8    PacketDeliveryRatio = 1f,
 9  };
 10
 11  // Message queue.
 212  private readonly PriorityQueue<PendingMessage> _messageQueue =
 13      new PriorityQueue<PendingMessage>();
 14
 15  // Enqueue a message to be delivered after a set latency.
 216  public void Send(Message message) {
 217    if (message == null) {
 018      return;
 19    }
 20
 321    if (CommsManager.Instance.ContainsNode(message.Receiver)) {
 122      Configs.LinkConfig config = GetLinkConfig(message);
 23
 24      // TODO(Joseph0120): Set the packet delivery ratio to config.PacketDeliveryRatio.
 125      float packetDeliveryRatio = Mathf.Clamp01(1);
 126      if (UnityEngine.Random.value >= packetDeliveryRatio) {
 027        return;
 28      }
 29
 130      float latency = config.LatencySeconds;
 131      float jitter = Utilities.SampleStandardNormal() * config.LatencyStdSeconds;
 132      float totalLatency = Math.Max(0f, latency + jitter);
 133      float deliverAt = SimManager.Instance.ElapsedTime + totalLatency;
 34
 35      // Deliver the message immediately if it is already due.
 136      if (deliverAt <= SimManager.Instance.ElapsedTime) {
 037        if (CommsManager.Instance.ContainsNode(message.Receiver)) {
 038          message.Receiver.Receive(message);
 039        }
 140      } else {
 141        var pendingMessage = new PendingMessage(message, deliverAt);
 142        _messageQueue.Enqueue(pendingMessage, pendingMessage.DeliverAt);
 143      }
 144    }
 245  }
 46
 47  // Deliver should be called at every fixed update to check for due messages to be delivered.
 348  public void Deliver() {
 449    while (!_messageQueue.IsEmpty() &&
 150           _messageQueue.Peek().DeliverAt <= SimManager.Instance.ElapsedTime) {
 151      PendingMessage pendingMessage = _messageQueue.Dequeue();
 252      if (CommsManager.Instance.ContainsNode(pendingMessage.Receiver)) {
 153        pendingMessage.Receiver.Receive(pendingMessage.Message);
 154      }
 155    }
 356  }
 57
 58  // Clear all pending messages.
 059  public void Clear() {
 060    _messageQueue.Clear();
 061  }
 62
 163  private Configs.LinkConfig GetLinkConfig(Message message) {
 164    Configs.CommunicationConfig communicationConfig =
 65        SimManager.Instance.SimulationConfig?.CommunicationConfig;
 166    if (communicationConfig == null) {
 067      return _defaultLinkConfig;
 68    }
 69
 170    Configs.AgentType senderType = message.Sender.EndpointType;
 171    Configs.AgentType receiverType = message.Receiver.EndpointType;
 372    foreach (Configs.LinkOverride linkOverride in communicationConfig.LinkOverrides) {
 073      if (linkOverride.From == senderType && linkOverride.To == receiverType) {
 074        return linkOverride.LinkConfig;
 75      }
 076    }
 177    return communicationConfig.LinkConfig ?? _defaultLinkConfig;
 178  }
 79}