Files

68 lines
2.9 KiB
GDScript

@tool
extends PanelContainer
@export var maximum_depth_m := 1000.0
@export var maximum_pressure_mpa := 10.0
@export var shallow_scale_knee_m := 1.0
@export_range(0, 1) var warning_fraction := 0.8
@export_range(0, 1) var fault_fraction := 0.95
@export var stale_after_seconds := 2.0
var _depth := 0.0
var _pressure := 0.0
var _temperature := 0.0
var _received_ms := -1
var _stale := false
func _ready() -> void:
_refresh()
## Depth in metres, pressure in MPa, water temperature in Celsius; supplied independently.
func set_telemetry(depth_m: float, pressure_mpa: float, water_temperature_c: float) -> bool:
if not is_finite(depth_m) or not is_finite(pressure_mpa) or not is_finite(water_temperature_c) or pressure_mpa < 0:
return false
_depth = depth_m
_pressure = pressure_mpa
_temperature = water_temperature_c
_received_ms = Time.get_ticks_msec()
_refresh()
return true
func clear_telemetry() -> void:
_received_ms = -1
_refresh()
func _severity(ratio: float) -> int:
return 2 if ratio >= maxf(warning_fraction, fault_fraction) else (1 if ratio >= warning_fraction else 0)
func _process(_delta: float) -> void:
var stale := _received_ms >= 0 and Time.get_ticks_msec() - _received_ms > stale_after_seconds * 1000
if stale != _stale:
_refresh()
func _refresh() -> void:
if not is_node_ready():
return
var measured := _received_ms >= 0
_stale = measured and Time.get_ticks_msec() - _received_ms > stale_after_seconds * 1000
var depth_ratio := _depth / maxf(maximum_depth_m, 0.001)
var pressure_ratio := _pressure / maxf(maximum_pressure_mpa, 0.001)
var worst_ratio := maxf(depth_ratio, pressure_ratio)
var variants := ["Label", "InstrumentWarning", "InstrumentFault"]
%DepthValue.text = "%.2f m" % _depth if measured else "— m"
%PressureValue.text = "%.2f MPa" % _pressure if measured else "— MPa"
%TemperatureValue.text = "%.1f °C" % _temperature if measured else "— °C"
%DepthReference.text = "/ %s m" % String.num(maximum_depth_m, 2).trim_suffix(".0")
%PressureReference.text = "/ %s MPa" % String.num(maximum_pressure_mpa, 2).trim_suffix(".0")
%DepthTitle.theme_type_variation = variants[_severity(depth_ratio)] if measured else "Label"
%PressureTitle.theme_type_variation = variants[_severity(pressure_ratio)] if measured else "Label"
%State.text = "NO TELEMETRY" if not measured else ("STALE" if _stale else ("OVER LIMIT" if worst_ratio > 1 else ("NEAR LIMIT" if _severity(worst_ratio) > 0 else "")))
%State.theme_type_variation = "InstrumentMuted" if not measured else ("InstrumentWarning" if _stale else variants[_severity(worst_ratio)])
%DepthScale.depth_m = _depth
%DepthScale.maximum_depth_m = maxf(maximum_depth_m, 0.001)
%DepthScale.knee_m = maxf(shallow_scale_knee_m, 0.001)
%DepthScale.warning_fraction = warning_fraction
%DepthScale.fault_fraction = maxf(warning_fraction, fault_fraction)
%DepthScale.available = measured
%DepthScale.queue_redraw()