ARMapRenderer: Minor logging tweaks
ARMapRenderer: Minor logging tweaks

// AntennaRange // AntennaRange
// //
// ARMapRenderer.cs // ARMapRenderer.cs
// //
// Copyright © 2014, toadicus // Copyright © 2014, toadicus
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without modification, // Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met: // are permitted provided that the following conditions are met:
// //
// 1. Redistributions of source code must retain the above copyright notice, // 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. // this list of conditions and the following disclaimer.
// //
// 2. Redistributions in binary form must reproduce the above copyright notice, // 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation and/or other // this list of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution. // materials provided with the distribution.
// //
// 3. Neither the name of the copyright holder nor the names of its contributors may be used // 3. Neither the name of the copyright holder nor the names of its contributors may be used
// to endorse or promote products derived from this software without specific prior written permission. // to endorse or promote products derived from this software without specific prior written permission.
// //
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   
#pragma warning disable 1591 #pragma warning disable 1591
   
using KSP; using KSP;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using ToadicusTools; using ToadicusTools;
using UnityEngine; using UnityEngine;
   
namespace AntennaRange namespace AntennaRange
{ {
public class ARMapRenderer : MonoBehaviour public class ARMapRenderer : MonoBehaviour
{ {
#region Fields #region Fields
private Dictionary<Guid, LineRenderer> vesselLineRenderers; private Dictionary<Guid, LineRenderer> vesselLineRenderers;
   
// Debug Stuff // Debug Stuff
#pragma warning disable 649 #pragma warning disable 649
private System.Diagnostics.Stopwatch timer; private System.Diagnostics.Stopwatch timer;
private Tools.DebugLogger log; private Tools.DebugLogger log;
private long relayStart; private long relayStart;
private long start; private long start;
#pragma warning restore 649 #pragma warning restore 649
   
#pragma warning disable 414 #pragma warning disable 414
private Color thisColor; private Color thisColor;
#pragma warning restore 414 #pragma warning restore 414
#endregion #endregion
   
#region Properties #region Properties
public LineRenderer this[Guid idx] public LineRenderer this[Guid idx]
{ {
get get
{ {
if (this.vesselLineRenderers == null) if (this.vesselLineRenderers == null)
{ {
this.vesselLineRenderers = new Dictionary<Guid, LineRenderer>(); this.vesselLineRenderers = new Dictionary<Guid, LineRenderer>();
} }
   
LineRenderer lr; LineRenderer lr;
   
if (this.vesselLineRenderers.TryGetValue(idx, out lr)) if (this.vesselLineRenderers.TryGetValue(idx, out lr))
{ {
return lr; return lr;
} }
else else
{ {
GameObject obj = new GameObject(); GameObject obj = new GameObject();
obj.layer = 31; obj.layer = 31;
   
lr = obj.AddComponent<LineRenderer>(); lr = obj.AddComponent<LineRenderer>();
   
// lr.SetColors(Color.green, Color.green); // lr.SetColors(Color.green, Color.green);
lr.material = MapView.OrbitLinesMaterial; lr.material = MapView.OrbitLinesMaterial;
// lr.SetVertexCount(2); // lr.SetVertexCount(2);
   
this.vesselLineRenderers[idx] = lr; this.vesselLineRenderers[idx] = lr;
   
return lr; return lr;
} }
} }
} }
#endregion #endregion
   
#region MonoBehaviour Lifecycle #region MonoBehaviour Lifecycle
private void Awake() private void Awake()
{ {
if (ARConfiguration.PrettyLines) if (ARConfiguration.PrettyLines)
{ {
this.vesselLineRenderers = new Dictionary<Guid, LineRenderer>(); this.vesselLineRenderers = new Dictionary<Guid, LineRenderer>();
} }
   
#if DEBUG #if DEBUG
this.timer = new System.Diagnostics.Stopwatch(); this.timer = new System.Diagnostics.Stopwatch();
this.log = Tools.DebugLogger.New(this); this.log = Tools.DebugLogger.New(this);
#endif #endif
} }
   
private void OnPreCull() private void OnPreCull()
{ {
if (!HighLogic.LoadedSceneIsFlight || !MapView.MapIsEnabled || !ARConfiguration.PrettyLines) if (!HighLogic.LoadedSceneIsFlight || !MapView.MapIsEnabled || !ARConfiguration.PrettyLines)
{ {
this.Cleanup(); this.Cleanup();
   
return; return;
} }
   
#if DEBUG #if DEBUG
timer.Restart(); timer.Restart();
#endif #endif
   
try try
{ {
log.Clear(); log.Clear();
   
log.AppendFormat("OnPreCull.\n"); log.AppendFormat("OnPreCull.\n");
   
log.AppendFormat("\tMapView: Draw3DLines: {0}\n" + log.AppendFormat("\tMapView: Draw3DLines: {0}\n" +
"\tMapView.MapCamera.camera.fieldOfView: {1}\n" + "\tMapView.MapCamera.camera.fieldOfView: {1}\n" +
"\tMapView.MapCamera.Distance: {2}\n", "\tMapView.MapCamera.Distance: {2}\n",
MapView.Draw3DLines, MapView.Draw3DLines,
MapView.MapCamera.camera.fieldOfView, MapView.MapCamera.camera.fieldOfView,
MapView.MapCamera.Distance MapView.MapCamera.Distance
); );
   
if (FlightGlobals.ready && FlightGlobals.Vessels != null) if (FlightGlobals.ready && FlightGlobals.Vessels != null)
{ {
log.AppendLine("FlightGlobals ready and Vessels list not null."); log.AppendLine("FlightGlobals ready and Vessels list not null.");
   
for (int i = 0; i < FlightGlobals.Vessels.Count; i++) for (int i = 0; i < FlightGlobals.Vessels.Count; i++)
{ {
Vessel vessel = FlightGlobals.Vessels[i]; Vessel vessel = FlightGlobals.Vessels[i];
   
log.AppendFormat("\nStarting check for vessel {0} at {1}ms", vessel, timer.ElapsedMilliseconds); log.AppendFormat("\nStarting check for vessel {0} at {1}ms", vessel, timer.ElapsedMilliseconds);
   
if (vessel == null) if (vessel == null)
{ {
log.AppendFormat("\n\tSkipping vessel {0} altogether because it is null.", vessel); log.AppendFormat("\n\tSkipping vessel {0} altogether because it is null.", vessel);
continue; continue;
} }
   
switch (vessel.vesselType) switch (vessel.vesselType)
{ {
case VesselType.Debris: case VesselType.Debris:
case VesselType.EVA: case VesselType.EVA:
case VesselType.Unknown: case VesselType.Unknown:
case VesselType.SpaceObject: case VesselType.SpaceObject:
log.AppendFormat("\n\tDiscarded because vessel is of invalid type {0}", log.AppendFormat("\n\tDiscarded because vessel is of invalid type {0}",
vessel.vesselType); vessel.vesselType);
continue; continue;
} }
   
log.AppendFormat("\n\tChecking vessel {0}.", vessel.vesselName); log.AppendFormat("\n\tChecking vessel {0}.", vessel.vesselName);
   
#if DEBUG #if DEBUG
start = timer.ElapsedMilliseconds; start = timer.ElapsedMilliseconds;
#endif #endif
   
IAntennaRelay vesselRelay = vessel.GetBestRelay(); IAntennaRelay vesselRelay = vessel.GetBestRelay();
   
if (vesselRelay == null) if (vesselRelay == null)
{ {
  log.AppendFormat("\n\tGot null relay for vessel {0}", vessel.vesselName);
continue; continue;
} }
   
log.AppendFormat("\n\tGot best relay {0} ({3}) for vessel {1} in {2} ms", log.AppendFormat("\n\tGot best relay {0} ({3}) for vessel {1} in {2} ms",
vesselRelay, vessel, timer.ElapsedMilliseconds - start, vesselRelay.GetType().Name); vesselRelay, vessel, timer.ElapsedMilliseconds - start, vesselRelay.GetType().Name);
   
if (vesselRelay != null) if (vesselRelay != null)
{ {
#if DEBUG #if DEBUG
start = timer.ElapsedMilliseconds; start = timer.ElapsedMilliseconds;
#endif #endif
   
this.SetRelayVertices(vesselRelay); this.SetRelayVertices(vesselRelay);
   
log.AppendFormat("\n\tSet relay vertices for {0} in {1}ms", log.AppendFormat("\n\tSet relay vertices for {0} in {1}ms",
vessel, timer.ElapsedMilliseconds - start); vessel, timer.ElapsedMilliseconds - start);
} }
} }
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
this.LogError("Caught {0}: {1}\n{2}\n", ex.GetType().Name, ex.ToString(), ex.StackTrace.ToString()); this.LogError("Caught {0}: {1}\n{2}\n", ex.GetType().Name, ex.ToString(), ex.StackTrace.ToString());
this.Cleanup(); this.Cleanup();
} }
#if DEBUG #if DEBUG
finally finally
{ {
log.AppendFormat("\n\tOnPreCull finished in {0}ms\n", timer.ElapsedMilliseconds); log.AppendFormat("\n\tOnPreCull finished in {0}ms\n", timer.ElapsedMilliseconds);
   
log.Print(); log.Print();
} }
#endif #endif
} }
   
private void OnDestroy() private void OnDestroy()
{ {
this.Cleanup(); this.Cleanup();
   
print("ARMapRenderer: Destroyed."); this.Log("Destroyed");
} }
#endregion #endregion
   
#region Utility #region Utility
private void SetRelayVertices(IAntennaRelay relay) private void SetRelayVertices(IAntennaRelay relay)
{ {
log.AppendFormat("\n\t\tDrawing line for relay chain starting at {0}.", relay); log.AppendFormat("\n\t\tDrawing line for relay chain starting at {0}.", relay);
   
if (relay.vessel == null) if (relay.vessel == null)
{ {
log.Append("\n\t\tvessel is null, bailing out"); log.Append("\n\t\tvessel is null, bailing out");
return; return;
} }
   
LineRenderer renderer = this[relay.vessel.id]; LineRenderer renderer = this[relay.vessel.id];
Vector3d start = ScaledSpace.LocalToScaledSpace(relay.vessel.GetWorldPos3D()); Vector3d start = ScaledSpace.LocalToScaledSpace(relay.vessel.GetWorldPos3D());
   
float lineWidth; float lineWidth;
float d = Screen.height / 2f + 0.01f; float d = Screen.height / 2f + 0.01f;
   
if (MapView.Draw3DLines) if (MapView.Draw3DLines)
{ {
lineWidth = 0.005859375f * MapView.MapCamera.Distance; lineWidth = 0.005859375f * MapView.MapCamera.Distance;
} }
else else
{ {
lineWidth = 2f; lineWidth = 2f;
   
start = MapView.MapCamera.camera.WorldToScreenPoint(start); start = MapView.MapCamera.camera.WorldToScreenPoint(start);
   
start.z = start.z >= 0f ? d : -d; start.z = start.z >= 0f ? d : -d;
} }
   
renderer.SetWidth(lineWidth, lineWidth); renderer.SetWidth(lineWidth, lineWidth);
   
renderer.SetPosition(0, start); renderer.SetPosition(0, start);
   
int idx = 0; int idx = 0;
   
#if DEBUG #if DEBUG
relayStart = timer.ElapsedMilliseconds; relayStart = timer.ElapsedMilliseconds;
#endif #endif
   
Vector3d nextPoint; Vector3d nextPoint;
   
renderer.enabled = true; renderer.enabled = true;
   
if (!relay.CanTransmit()) if (!relay.CanTransmit())
{ {
thisColor = Color.red; thisColor = Color.red;
} }
else else
{ {
if (relay.transmitDistance < relay.nominalTransmitDistance) if (relay.transmitDistance < relay.nominalTransmitDistance)
{ {
thisColor = Color.green; thisColor = Color.green;
} }
else else
{ {
thisColor = Color.yellow; thisColor = Color.yellow;
} }
} }
   
if (relay.KerbinDirect) if (relay.KerbinDirect)
{ {
nextPoint = ScaledSpace.LocalToScaledSpace(AntennaRelay.Kerbin.position); nextPoint = ScaledSpace.LocalToScaledSpace(AntennaRelay.Kerbin.position);
relay = null; relay = null;
} }
else else
{ {
if (relay.targetRelay == null) if (relay.targetRelay == null)
{ {
renderer.enabled = false; renderer.enabled = false;
return; return;
} }
   
nextPoint = ScaledSpace.LocalToScaledSpace(relay.targetRelay.vessel.GetWorldPos3D()); nextPoint = ScaledSpace.LocalToScaledSpace(relay.targetRelay.vessel.GetWorldPos3D());
relay = relay.targetRelay; relay = relay.targetRelay;
} }
   
renderer.SetColors(thisColor, thisColor); renderer.SetColors(thisColor, thisColor);
   
if (!MapView.Draw3DLines) if (!MapView.Draw3DLines)
{ {
nextPoint = MapView.MapCamera.camera.WorldToScreenPoint(nextPoint); nextPoint = MapView.MapCamera.camera.WorldToScreenPoint(nextPoint);
nextPoint.z = nextPoint.z >= 0f ? d : -d; nextPoint.z = nextPoint.z >= 0f ? d : -d;
} }
   
idx++; idx++;
   
renderer.SetVertexCount(idx + 1); renderer.SetVertexCount(idx + 1);
renderer.SetPosition(idx, nextPoint); renderer.SetPosition(idx, nextPoint);
   
log.AppendFormat("\n\t\t\t...finished segment in {0} ms", timer.ElapsedMilliseconds - relayStart); log.AppendFormat("\n\t\t\t...finished segment in {0} ms", timer.ElapsedMilliseconds - relayStart);
} }
   
private void Cleanup() private void Cleanup()
{ {
if (this.vesselLineRenderers != null && this.vesselLineRenderers.Count > 0) if (this.vesselLineRenderers != null && this.vesselLineRenderers.Count > 0)
{ {
IEnumerator<LineRenderer> enumerator = this.vesselLineRenderers.Values.GetEnumerator(); IEnumerator<LineRenderer> enumerator = this.vesselLineRenderers.Values.GetEnumerator();
LineRenderer lineRenderer; LineRenderer lineRenderer;
   
while (enumerator.MoveNext()) while (enumerator.MoveNext())
{ {
lineRenderer = enumerator.Current; lineRenderer = enumerator.Current;
lineRenderer.enabled = false; lineRenderer.enabled = false;
GameObject.Destroy(lineRenderer.gameObject); GameObject.Destroy(lineRenderer.gameObject);
} }
this.vesselLineRenderers.Clear(); this.vesselLineRenderers.Clear();
} }
} }
#endregion #endregion
} }
} }