< Summary

Class:UIManager
Assembly:bamlab.micromissiles
File(s):/github/workspace/Assets/Scripts/UI/UIManager.cs
Covered lines:0
Uncovered lines:170
Coverable lines:170
Total lines:254
Line coverage:0% (0 of 170)
Covered branches:0
Total branches:0
Covered methods:0
Total methods:30
Method coverage:0% (0 of 30)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
UIManager()0%2100%
Awake()0%6200%
Start()0%2100%
LogAction(...)0%2100%
LogActionMessage(...)0%2100%
LogActionWarning(...)0%2100%
LogActionError(...)0%2100%
ToggleConfigSelectorPanel()0%2100%
SetupConfigSelectorPanel()0%2100%
PopulateConfigDropdown()0%6200%
LoadSelectedConfig()0%2100%
ToggleUIMode()0%12300%
SetUIMode(...)0%2100%
GetUIMode()0%2100%
SetAgentPanelText(...)0%2100%
GetSwarmPanelText()0%2100%
UpdateSwarmPanel()0%6200%
UpdateSimTimeText()0%6200%
UpdateTotalCostText()0%6200%
FormatCost(...)0%20400%
RegisterSimulationEnded()0%2100%
UpdateSummaryText()0%2100%
RegisterNewInterceptor(...)0%2100%
RegisterNewThreat(...)0%2100%
RegisterAgentTerminated(...)0%12300%
RegisterInterceptorHit(...)0%2100%
RegisterInterceptorMiss(...)0%2100%
Update()0%2100%

File(s)

/github/workspace/Assets/Scripts/UI/UIManager.cs

#LineLine coverage
 1using System.Collections;
 2using System.Collections.Generic;
 3using System.IO;
 4using UnityEngine;
 5using UnityEngine.UI;
 6using TMPro;
 7using System;
 8
 9public class UIManager : MonoBehaviour {
 010  public static UIManager Instance { get; private set; }
 11
 12  [SerializeField]
 13  [Tooltip("The UI panel that renders the tactical view for TACTICAL mode")]
 14  private GameObject _tacticalPanel;
 15
 16  [SerializeField]
 17  [Tooltip("The UI panel that renders the camera view for THREE_DIMENSIONAL mode")]
 18  private GameObject _cameraPanel;
 19
 20  [SerializeField]
 21
 22  private GameObject _configSelectorPanel;
 23  private TMP_Dropdown _configDropdown;
 24  public TextMeshProUGUI agentPanelText;
 25  public TextMeshProUGUI simTimeText;
 26  public TextMeshProUGUI interceptorCostText;
 27  public TextMeshProUGUI threatCostText;
 28  public TextMeshProUGUI netCostText;
 29
 30  public TextMeshProUGUI intrHitTextHandle;
 31  public TextMeshProUGUI intrMissTextHandle;
 32  public TextMeshProUGUI intrRemainTextHandle;
 33  public TextMeshProUGUI thrtRemainTextHandle;
 34
 35  public TextMeshProUGUI actionMessageTextHandle;
 36  public TextMeshProUGUI pActionMessageTextHandle;
 37  public TextMeshProUGUI ppActionMessageTextHandle;
 38  public TextMeshProUGUI ppppActionMessageTextHandle;
 39  public TextMeshProUGUI pppppActionMessageTextHandle;
 40
 041  private int _intrHitCount = 0;
 042  private int _intrMissCount = 0;
 043  private int _intrRemainCount = 0;
 044  private int _thrtRemainCount = 0;
 45  public TMP_FontAsset GlobalFont;
 46
 047  private UIMode curMode = UIMode.THREE_DIMENSIONAL;
 48
 049  void Awake() {
 050    if (Instance == null)
 051      Instance = this;
 52    else
 053      Destroy(gameObject);
 054  }
 55
 056  void Start() {
 057    SetUIMode(UIMode.THREE_DIMENSIONAL);
 058    _configSelectorPanel.SetActive(false);
 059    SetupConfigSelectorPanel();
 060    SimManager.Instance.OnNewInterceptor += RegisterNewInterceptor;
 061    SimManager.Instance.OnNewThreat += RegisterNewThreat;
 062    SimManager.Instance.OnSimulationEnded += RegisterSimulationEnded;
 063    actionMessageTextHandle.text = "";
 064    pActionMessageTextHandle.text = "";
 065    ppActionMessageTextHandle.text = "";
 066    ppppActionMessageTextHandle.text = "";
 067    pppppActionMessageTextHandle.text = "";
 068  }
 69
 070  public void LogAction(string message, Color color) {
 71    // Shift existing messages to older slots with faded colors.
 072    pppppActionMessageTextHandle.text = ppppActionMessageTextHandle.text;
 073    pppppActionMessageTextHandle.color =
 74        ppppActionMessageTextHandle.color * 0.8f;  // Fade color by 20%.
 75
 076    ppppActionMessageTextHandle.text = ppActionMessageTextHandle.text;
 077    ppppActionMessageTextHandle.color = ppActionMessageTextHandle.color * 0.85f;
 78
 079    ppActionMessageTextHandle.text = pActionMessageTextHandle.text;
 080    ppActionMessageTextHandle.color = pActionMessageTextHandle.color * 0.85f;
 81
 082    pActionMessageTextHandle.text = actionMessageTextHandle.text;
 083    pActionMessageTextHandle.color = actionMessageTextHandle.color * 0.9f;
 84
 85    // Set new message.
 086    actionMessageTextHandle.text = message;
 087    actionMessageTextHandle.color = color;
 088  }
 89
 090  public void LogActionMessage(string message) {
 091    LogAction(message, Color.white);
 092  }
 93
 094  public void LogActionWarning(string message) {
 095    LogAction(message, Color.yellow);
 096  }
 97
 098  public void LogActionError(string message) {
 099    LogAction(message, Color.red);
 0100  }
 101
 0102  public void ToggleConfigSelectorPanel() {
 0103    _configSelectorPanel.SetActive(!_configSelectorPanel.activeSelf);
 0104  }
 105
 0106  private void SetupConfigSelectorPanel() {
 0107    _configSelectorPanel.GetComponentInChildren<Button>().onClick.AddListener(
 0108        delegate { LoadSelectedConfig(); });
 0109    _configDropdown = _configSelectorPanel.GetComponentInChildren<TMP_Dropdown>();
 0110    PopulateConfigDropdown();
 0111  }
 112
 0113  private void PopulateConfigDropdown() {
 0114    _configDropdown.ClearOptions();
 0115    string configPath = ConfigLoader.GetStreamingAssetsFilePath("Configs/Simulations");
 0116    string[] configFiles = Directory.GetFiles(configPath, "*.pbtxt");
 117
 0118    List<string> configFileNames = new List<string>();
 0119    foreach (string configFile in configFiles) {
 0120      configFileNames.Add(Path.GetFileName(configFile));
 0121    }
 0122    _configDropdown.AddOptions(configFileNames);
 0123  }
 0124  private void LoadSelectedConfig() {
 0125    string selectedConfig = _configDropdown.options[_configDropdown.value].text;
 0126    SimManager.Instance.LoadNewConfig(selectedConfig);
 0127    _configSelectorPanel.SetActive(false);
 0128  }
 129
 0130  public void ToggleUIMode() {
 0131    SetUIMode(curMode == UIMode.THREE_DIMENSIONAL ? UIMode.TACTICAL : UIMode.THREE_DIMENSIONAL);
 0132  }
 133
 0134  public void SetUIMode(UIMode mode) {
 0135    curMode = mode;
 0136    _cameraPanel.SetActive(mode == UIMode.THREE_DIMENSIONAL);
 0137    _tacticalPanel.SetActive(mode == UIMode.TACTICAL);
 0138  }
 139
 0140  public UIMode GetUIMode() {
 0141    return curMode;
 0142  }
 143
 0144  public void SetAgentPanelText(string text) {
 0145    agentPanelText.text = text;
 0146  }
 147
 0148  public string GetSwarmPanelText() {
 0149    return agentPanelText.text;
 0150  }
 151
 0152  private void UpdateSwarmPanel() {
 0153    string agentPanelText = "";
 0154    foreach (Agent agent in SimManager.Instance.GetActiveAgents()) {
 0155      string jobText = agent.name + "| Phase: " + agent.GetFlightPhase().ToString();
 0156      agentPanelText += jobText + "\n";
 0157    }
 0158    SetAgentPanelText(agentPanelText);
 0159  }
 160
 0161  private void UpdateSimTimeText() {
 0162    simTimeText.text =
 163        "Elapsed Sim Time: " + SimManager.Instance.GetElapsedSimulationTime().ToString("F2");
 0164    float expectedSimTimeAdvance = Time.unscaledDeltaTime * Time.timeScale;
 0165    float actualSimTimeAdvance = Time.deltaTime;
 166
 167    // Allow a small epsilon to account for floating-point precision errors.
 0168    if (actualSimTimeAdvance < expectedSimTimeAdvance - 0.001f) {
 0169      simTimeText.text += "\nThrottling time to meet physics rate";
 0170    }
 0171  }
 172
 0173  private void UpdateTotalCostText() {
 0174    double interceptorCost = SimManager.Instance.GetCostLaunchedInterceptors();
 0175    double threatCost = SimManager.Instance.GetCostDestroyedThreats();
 0176    double netCost = interceptorCost - threatCost;
 177
 0178    interceptorCostText.text = $"Interceptors\n(launched)\n${FormatCost(interceptorCost)}";
 0179    threatCostText.text = $"Threats\n(destroyed)\n${FormatCost(threatCost)}";
 0180    netCostText.text = $"Cost\ndifference\n${FormatCost(netCost)}";
 0181    if (netCost < 0) {
 0182      netCostText.color = Color.green;
 0183    } else {
 0184      netCostText.color = Color.red;
 0185    }
 0186  }
 187
 0188  private string FormatCost(double cost) {
 0189    double absCost = Math.Abs(cost);
 0190    if (absCost >= 1e9)
 0191      return $"{cost / 1e9:F2}B";
 0192    if (absCost >= 1e6)
 0193      return $"{cost / 1e6:F2}M";
 0194    if (absCost >= 1e3)
 0195      return $"{cost / 1e3:F2}k";
 0196    return $"{cost:F2}";
 0197  }
 198
 0199  private void RegisterSimulationEnded() {
 0200    _intrRemainCount = 0;
 0201    _thrtRemainCount = 0;
 0202    _intrHitCount = 0;
 0203    _intrMissCount = 0;
 0204    UpdateSummaryText();
 0205  }
 206
 0207  private void UpdateSummaryText() {
 0208    intrRemainTextHandle.text = _intrRemainCount.ToString();
 0209    thrtRemainTextHandle.text = _thrtRemainCount.ToString();
 0210    intrHitTextHandle.text = _intrHitCount.ToString();
 0211    intrMissTextHandle.text = _intrMissCount.ToString();
 0212  }
 213
 0214  private void RegisterNewInterceptor(Interceptor interceptor) {
 0215    ++_intrRemainCount;
 0216    interceptor.OnInterceptHit += RegisterInterceptorHit;
 0217    interceptor.OnInterceptMiss += RegisterInterceptorMiss;
 0218    interceptor.OnTerminated += RegisterAgentTerminated;
 0219    UpdateSummaryText();
 0220  }
 221
 0222  private void RegisterNewThreat(Threat threat) {
 0223    ++_thrtRemainCount;
 0224    threat.OnTerminated += RegisterAgentTerminated;
 0225    UpdateSummaryText();
 0226  }
 227
 0228  private void RegisterAgentTerminated(Agent agent) {
 0229    if (agent is Interceptor) {
 0230      --_intrRemainCount;
 0231    } else if (agent is Threat) {
 0232      --_thrtRemainCount;
 0233    }
 0234    UpdateSummaryText();
 0235  }
 236
 0237  private void RegisterInterceptorHit(Interceptor interceptor, Threat threat) {
 0238    ++_intrHitCount;
 0239    UpdateSummaryText();
 0240  }
 241
 0242  private void RegisterInterceptorMiss(Interceptor interceptor, Threat threat) {
 0243    ++_intrMissCount;
 0244    UpdateSummaryText();
 0245  }
 246
 0247  void Update() {
 248    // UpdateSwarmPanel();
 0249    UpdateSimTimeText();
 0250    UpdateTotalCostText();
 0251  }
 252}
 253
 254public enum UIMode { THREE_DIMENSIONAL, TACTICAL }