1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
//! `CSectorElement` — a reference to an element of the loaded sector file
//! (VOR, NDB, airport, runway, SID/STAR, etc.).
use std::marker::PhantomData;
use euroscope_sys::EsHandle;
use crate::{Position, utils::cstr};
/// A reference to a sector-file element.
///
/// A thin handle over EuroScope's `CSectorElement`, valid only for the
/// duration of the callback / query block that produced it (`'cb`).
#[derive(Clone, Copy)]
pub struct SectorElement<'cb> {
raw: EsHandle,
_marker: PhantomData<&'cb ()>,
}
impl SectorElement<'_> {
pub(crate) fn from_raw(raw: EsHandle) -> Self {
Self {
raw,
_marker: PhantomData,
}
}
/// The raw `CSectorElement*`. Escape hatch for `euroscope-sys` calls not
/// yet wrapped here.
pub(crate) fn as_ptr(&self) -> EsHandle {
self.raw
}
/// Whether this handle references a valid sector element.
pub fn is_valid(&self) -> bool {
// SAFETY: `raw` is the pointer EuroScope handed us for this callback.
unsafe { euroscope_sys::es_sectorelement_is_valid(self.raw) }
}
/// The element type code.
pub fn element_type(&self) -> i32 {
// SAFETY: `raw` is a live handle for this callback.
unsafe { euroscope_sys::es_sectorelement_element_type(self.raw) }
}
/// The element name. Borrows EuroScope-owned memory; valid for this
/// callback only.
pub fn name(&self) -> &str {
// SAFETY: the SDK returns a borrowed NUL-terminated ANSI string, or
// null (guarded).
unsafe { cstr(euroscope_sys::es_sectorelement_name(self.raw)) }
}
/// The position at `index` (starting from zero). Returns `None` if the
/// index is invalid for this element (not all elements have coordinates).
pub fn position(&self, index: i32) -> Option<Position> {
let mut lat = 0.0_f64;
let mut lon = 0.0_f64;
// SAFETY: `raw` is a live handle; the out-params are valid stack slots.
let ok = unsafe {
euroscope_sys::es_sectorelement_position(self.raw, index, &raw mut lat, &raw mut lon)
};
ok.then(|| Position::new(lat, lon))
}
/// The name of the switchable component at `index` (starting from zero).
/// Empty if the index is invalid. Borrows EuroScope-owned memory; valid
/// for this callback only.
pub fn component_name(&self, index: i32) -> &str {
// SAFETY: the SDK returns a borrowed NUL-terminated ANSI string, or
// null (guarded).
unsafe {
cstr(euroscope_sys::es_sectorelement_component_name(
self.raw, index,
))
}
}
/// The frequency of VOR/NDB/AIRPORT elements, or `0.0` for all others.
pub fn frequency(&self) -> f64 {
// SAFETY: `raw` is a live handle for this callback.
unsafe { euroscope_sys::es_sectorelement_frequency(self.raw) }
}
/// The name of the runway at `index` (0 or 1). Empty if the index is
/// invalid. Borrows EuroScope-owned memory; valid for this callback only.
pub fn runway_name(&self, index: i32) -> &str {
// SAFETY: the SDK returns a borrowed NUL-terminated ANSI string, or
// null (guarded).
unsafe { cstr(euroscope_sys::es_sectorelement_runway_name(self.raw, index)) }
}
/// The heading of the runway at `index` (0 or 1), or `-1` if the index is
/// invalid.
pub fn runway_heading(&self, index: i32) -> i32 {
// SAFETY: `raw` is a live handle for this callback.
unsafe { euroscope_sys::es_sectorelement_runway_heading(self.raw, index) }
}
/// The name of the airport this element belongs to. Empty if the type is
/// invalid. Borrows EuroScope-owned memory; valid for this callback only.
pub fn airport_name(&self) -> &str {
// SAFETY: the SDK returns a borrowed NUL-terminated ANSI string, or
// null (guarded).
unsafe { cstr(euroscope_sys::es_sectorelement_airport_name(self.raw)) }
}
/// Whether the element (airport or runway) is active for `departure`
/// (`true`) or arrival (`false`). `index` (0 or 1) selects the runway and
/// is ignored for non-runway elements.
pub fn is_element_active(&self, departure: bool, index: i32) -> bool {
// SAFETY: `raw` is a live handle for this callback.
unsafe { euroscope_sys::es_sectorelement_is_element_active(self.raw, departure, index) }
}
}