Skip to content

Commit

Permalink
Merge branch 'release/0.8.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
dbent committed Jul 10, 2017
2 parents 14e3b68 + 74abcb1 commit 1597d45
Show file tree
Hide file tree
Showing 19 changed files with 540 additions and 249 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/.build/
/.vs/

*.suo
*.user
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## v0.8.0
##### Changed
- Added new setting to `CONTEXT_MENU` node named `updatePeriod`. Its value is the number of seconds to wait between
updates of context menu values. Defaults to a value of `0.250` (250 milliseconds or 4 times per second).
- Various performance improvements.

## v0.7.3
##### Changed
- Compatibility with KSP 1.3.0.
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ supports the following metrics:
- Temperature
- Thermal Rate

Hot Spot can display two kinds of temperatures:
Hot Spot can display three kinds of temperatures:

- *Skin Temperature* — The temperature of the exposed surface of a part.
- *Internal Temperature* — The temperature of the interior of a part.
Expand Down Expand Up @@ -35,7 +35,7 @@ of a part are displayed and the unit can be changed between [Kelvin][wiki-kelvin
### Part Overlay

Hot Spot will also replace the stock *Thermal Debug Overlay* with one displaying the metric of the user's choice and
will replace the standard black body color gradient with one more intuitive.
will replace the standard black body color gradient with one that is more intuitive.

#### Temperature
The color gradient used for temperature is as follows:
Expand Down
2 changes: 2 additions & 0 deletions src/GameData/Configuration/HotSpot.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ HOT_SPOT

CONTEXT_MENU
{
updatePeriod = 0.250

METRIC
{
name = TemperatureTemplate
Expand Down
12 changes: 8 additions & 4 deletions src/HotSpot/Configuration/ContextMenuNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ namespace HotSpot.Configuration
{
internal sealed class ContextMenuNode
{
private const double DefaultUpdatePeriod = 0.250;
private readonly Dictionary<string, MetricNode> _metricsDictionary;

public MetricNode[] Metrics { get; }
public double UpdatePeriod { get; }
public MetricNode[] Metrics { get; }

private ContextMenuNode(MetricNode[] metrics)
private ContextMenuNode(double updatePeriod, MetricNode[] metrics)
{
UpdatePeriod = updatePeriod;
Metrics = metrics;
_metricsDictionary = metrics.ToDictionary(i => i.Name.Name);
}
Expand All @@ -36,21 +39,22 @@ public void Save(ConfigNode node)

public static ContextMenuNode GetDefault()
{
return new ContextMenuNode(new MetricNode[] { });
return new ContextMenuNode(DefaultUpdatePeriod, new MetricNode[] { });
}

public static ContextMenuNode TryParse(ConfigNode node)
{
if (node != null)
{
var updatePeriod = node.TryParse<double>("updatePeriod") ?? DefaultUpdatePeriod;
var metrics = node
.GetNodes("METRIC")
.Where(i => !i.GetValue("name").EndsWith("Template"))
.Select(MetricNode.TryParse)
.Where(i => i != null)
.ToArray();

return new ContextMenuNode(metrics);
return new ContextMenuNode(updatePeriod, metrics);
}

return null;
Expand Down
3 changes: 1 addition & 2 deletions src/HotSpot/Configuration/Overlay/GradientNode.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using HotSpot.Model;

Expand All @@ -22,7 +21,7 @@ private GradientNode(string name, Expression min, Expression max, OnConflict onC
Stops = stops;
}

public EvaluatedGradientNode Evaluate(Dictionary<Variable, double> variables)
public EvaluatedGradientNode Evaluate(VariableBag variables)
{
return new EvaluatedGradientNode(this, variables);
}
Expand Down
22 changes: 15 additions & 7 deletions src/HotSpot/Configuration/Overlay/SchemeNode.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using HotSpot.Model;
using UnityEngine;
Expand All @@ -20,13 +19,22 @@ private SchemeNode(string name, string friendlyName, GradientNode[] gradients)
_gradients = gradients;
}

public Color? EvaluateColor(double partCurrent, Dictionary<Variable, double> variables)
public Color? EvaluateColor(VariableBag variables)
{
return _gradients
.Select(i => i.Evaluate(variables))
.Where(i => i.Min < i.Max)
.FirstOrDefault(i => i.Min <= partCurrent && partCurrent <= i.Max)
?.EvaluateColor(partCurrent);
var partCurrent = variables.PartCurrent;

// ReSharper disable once ForCanBeConvertedToForeach
for (var i = 0; i < _gradients.Length; i++)
{
var gradient = _gradients[i];
var evaluatedGradient = gradient.Evaluate(variables);

if (evaluatedGradient.Min < evaluatedGradient.Max)
if (evaluatedGradient.Min <= partCurrent && partCurrent <= evaluatedGradient.Max)
return evaluatedGradient.EvaluateColor(partCurrent);
}

return null;
}

public static SchemeNode TryParse(ConfigNode node)
Expand Down
3 changes: 1 addition & 2 deletions src/HotSpot/Configuration/Overlay/StopNode.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using HotSpot.Model;
Expand Down Expand Up @@ -27,7 +26,7 @@ private StopNode(string name, Expression value, double factor, Color? color, flo
Alpha = alpha;
}

public EvaluatedStopNode Evaluate(Dictionary<Variable, double> variables)
public EvaluatedStopNode Evaluate(VariableBag variables)
{
return new EvaluatedStopNode(this, variables);
}
Expand Down
7 changes: 6 additions & 1 deletion src/HotSpot/Configuration/OverlayNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ internal sealed class OverlayNode
public Metric Metric { get; set; }
public MetricNode[] Metrics { get; }

private OverlayNode(bool enable, bool enableScreenMessage, Metric metric, MetricNode[] metrics)
private OverlayNode(
bool enable,
bool enableScreenMessage,
Metric metric,
MetricNode[] metrics
)
{
Enable = enable;
EnableScreenMessage = enableScreenMessage;
Expand Down
1 change: 1 addition & 0 deletions src/HotSpot/HotSpot.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
<Compile Include="Model\Prefix.cs" />
<Compile Include="Model\Unit.cs" />
<Compile Include="Model\Variable.cs" />
<Compile Include="Model\VariableBag.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Reflection\FlightOverlaysExtensions.cs" />
<Compile Include="Reflection\PartExtensions.cs" />
Expand Down
79 changes: 26 additions & 53 deletions src/HotSpot/HotSpotBehavior.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
using System.Collections.Generic;
using System.Linq;
using HotSpot.Model;
using HotSpot.Reflection;
using UnityEngine;
Expand All @@ -9,84 +7,59 @@ namespace HotSpot
[KSPAddon(KSPAddon.Startup.Flight, false)]
public class HotSpotBehavior : MonoBehaviour
{
private readonly VariableBag _variables = new VariableBag();

#region MonoBehaviour

public void LateUpdate()
{
Log.Trace("Entering HotSpotBehavior.LateUpdate()");

if (Config.Instance.Overlay.Enable)
if (ShouldUpdate())
{
LateUpdateColor();
}

Log.Trace("Leaving HotSpotBehavior.LateUpdate()");
}
_variables.ResetAll();

private static void LateUpdateColor()
{
if (PhysicsGlobals.ThermalColorsDebug)
{
var metric = Config.Instance.Overlay.Metric;
var scheme = Config.Instance.Overlay.GetActiveMetric().GetActiveScheme();

foreach (var vessel in FlightGlobals.Vessels.Where(i => i.loaded))
var vessels = FlightGlobals.Vessels;
// ReSharper disable once ForCanBeConvertedToForeach
for (var iv = 0; iv < vessels.Count; iv++)
{
var vesselVariables = metric.GetVesselValues(vessel);
var vessel = vessels[iv];
if (!vessel.loaded) continue;

_variables.ResetVesselSpecific();
metric.PopulateVesselVariables(vessel, _variables);

foreach (var part in vessel.Parts)
var parts = vessel.Parts;
// ReSharper disable once ForCanBeConvertedToForeach
for (var ip = 0; ip < parts.Count; ip++)
{
var part = parts[ip];

Color? color = null;

if (metric.IsApplicable(part))
{
var partVariables = metric.GetPartValues(part);
var partCurrent = metric.GetPartCurrent(part);
_variables.ResetPartSpecific();
metric.PopulatePartVariables(part, _variables);

if (partCurrent != null)
{
color = Config
.Instance
.Overlay
.GetActiveMetric()
.GetActiveScheme()
.EvaluateColor(partCurrent.Value, MergeVariables(vesselVariables, partVariables));
}
else
{
Log.Warning(
$"Received null value for for applicable metric `{metric.Name}` on part " +
$"`{part.name}`."
);
}
color = scheme.EvaluateColor(_variables);
}

part.TryGetMaterialColorUpdater()?.Update(color ?? Part.defaultHighlightNone);
}
}
}
}

#endregion

#region Helpers
Log.Trace("Leaving HotSpotBehavior.LateUpdate()");
}

private static Dictionary<Variable, double> MergeVariables(
Dictionary<Variable, double> vesselVariables, Dictionary<Variable, double> partVariables
)
private static bool ShouldUpdate()
{
var result = new Dictionary<Variable, double>();

foreach(var kv in vesselVariables)
{
result[kv.Key] = kv.Value;
}

foreach (var kv in partVariables)
{
result[kv.Key] = kv.Value;
}

return result;
return Config.Instance.Overlay.Enable
&& PhysicsGlobals.ThermalColorsDebug;
}

#endregion
Expand Down
63 changes: 42 additions & 21 deletions src/HotSpot/HotSpotModule.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace HotSpot
using UnityEngine;

namespace HotSpot
{
public sealed class HotSpotModule : PartModule
{
Expand Down Expand Up @@ -32,6 +34,8 @@ public sealed class HotSpotModule : PartModule
[KSPField(guiActive = false)]
public string ThermalRateInternalToSkin;

private float _timeSinceLastUpdate = float.PositiveInfinity;

public override void OnStart(StartState state)
{
base.OnStart(state);
Expand All @@ -42,42 +46,59 @@ public override void OnStart(StartState state)

public override void OnUpdate()
{
if (!HighLogic.LoadedSceneIsFlight) return;

foreach (var metricNode in Config.Instance.ContextMenu.Metrics)
if (ShouldUpdate())
{
var metric = metricNode.Name;
var metrics = Config.Instance.ContextMenu.Metrics;

if (metric.IsApplicable(part))
// ReSharper disable once ForCanBeConvertedToForeach
for (var i = 0; i < metrics.Length; i++)
{
var value = metric.GetPartCurrentString(part, metricNode.Unit, metricNode.Prefix);
var metricNode = metrics[i];

var metric = metricNode.Name;

if (value != null)
if (metric.IsApplicable(part))
{
var field = Fields[metric.Name];
var value = metric.GetPartCurrentString(part, metricNode.Unit, metricNode.Prefix);

if (field != null)
if (value != null)
{
field.guiName = metric.ShortFriendlyName;
field.guiActive = metricNode.Enable;

field.SetValue(value, this);
var field = Fields[metric.Name];

if (field != null)
{
field.guiName = metric.ShortFriendlyName;
field.guiActive = metricNode.Enable;

field.SetValue(value, this);
}
else
{
Log.Warning($"Could not find field for metric `{metric.Name}`.");
}
}
else
{
Log.Warning($"Could not find field for metric `{metric.Name}`.");
Log.Warning(
$"Received null value for for applicable metric `{metric.Name}` on part `{part.name}`."
);
}
}
else
{
Log.Warning(
$"Received null value for for applicable metric `{metric.Name}` on part `{part.name}`."
);
}
}

_timeSinceLastUpdate = 0;
}
else
{
_timeSinceLastUpdate += Time.deltaTime;
}
}

private bool ShouldUpdate()
{
return HighLogic.LoadedSceneIsFlight && _timeSinceLastUpdate >= Config.Instance.ContextMenu.UpdatePeriod;
}

private void DisableStockCoreTempDisplay()
{
var coreTempDisplayField = part
Expand Down
Loading

0 comments on commit 1597d45

Please sign in to comment.