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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
use crate::ffi;

/// A unit used with the Gauge API.
pub trait Unit {
    /// Obtains a raw FFI identifer for this unit type
    fn as_raw_unit() -> ffi::RawUnit;
}

/// Produces a new unit type, used for communicating with the gauge API.
#[macro_export]
macro_rules! gauge_unit {
    ($ty:ident: $name:literal; $description:literal) => {
        #[doc = $description]
        #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
        pub struct $ty;

        impl $ty {
            const UNIT_NAME: &'static str = concat!($name, "\0");
        }

        impl $crate::Unit for $ty {
            #[inline]
            fn as_raw_unit() -> $crate::ffi::RawUnit {
                static RAW_UNIT_VALUE: $crate::once_cell::Lazy<$crate::ffi::RawUnit> = $crate::once_cell::Lazy::new(|| unsafe {
                    $crate::ffi::RawUnit::from_units_enum_str($ty::UNIT_NAME)
                });
                *RAW_UNIT_VALUE
            }
        }
    };
}

/// Identifies an aircraft variable that can be interacted with through the
/// Gauge API.
pub trait AircraftVariable {
    /// The Gauge API Unit
    type Unit: Unit;
    /// Obtains the raw FFI identifier for this aircraft variable
    fn as_raw_aircraft_variable() -> ffi::RawAircraftVariable;
}

/// Produces a base new aircraft variable
///
/// Generally you want to use `indexed_aircraft_variable` or
/// `unindexed_aircraft_variable` instead.
#[macro_export]
macro_rules! aircraft_variable {
    ($ty:ident ( $unit:ty ): $name:literal ; $description:literal) => {
        //#[doc = $description]
        #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
        pub struct $ty;

        impl $ty {
            const VARIABLE_NAME: &'static str = concat!($name, "\0");
        }

        impl $crate::AircraftVariable for $ty {
            type Unit = $unit;

            #[inline]
            fn as_raw_aircraft_variable() -> $crate::ffi::RawAircraftVariable {
                static RAW_UNIT_VALUE: $crate::once_cell::Lazy<$crate::ffi::RawAircraftVariable> =
                    $crate::once_cell::Lazy::new(|| unsafe {
                        $crate::ffi::RawAircraftVariable::from_aircraft_variable_enum_str(
                            $ty::VARIABLE_NAME,
                        )
                    });
                *RAW_UNIT_VALUE
            }
        }
    };
}

/// Provides access to an aircraft variable that is indexed
///
/// Many variables relating to aircraft engines will be indexed.
#[macro_export]
macro_rules! indexed_aircraft_variable {
    ($ty:ident ( $unit:ty ): $name:literal; $description:literal) => {
        $crate::aircraft_variable!($ty($unit): $name; $description);

        impl $ty {
            /// Reads the raw value from an indexed variable value for the index specified
            #[inline]
            fn read_raw_by_index(index: u32) -> f64 {
                $crate::ffi::RawAircraftVariable::read(<Self as $crate::AircraftVariable>::as_raw_aircraft_variable(), <<Self as $crate::AircraftVariable>::Unit as $crate::Unit>::as_raw_unit(), index)
            }
        }
    };
}

/// Provides access to variables that do not require indexing
#[macro_export]
macro_rules! unindexed_aircraft_variable {
    ($ty:ident ( $unit:ty ): $name:literal; $description:literal) => {
        $crate::aircraft_variable!($ty($unit): $name; $description);

        impl $ty {
            /// Reads the raw variable value
            #[inline]
            fn read_raw() -> f64 {
                $crate::ffi::RawAircraftVariable::read(<Self as $crate::AircraftVariable>::as_raw_aircraft_variable(), <<Self as $crate::AircraftVariable>::Unit as $crate::Unit>::as_raw_unit(), 0)
            }
        }
    };
}

/// A custom named variable that can be interacted with in the Gauge API
pub trait NamedVariable {
    /// The type of the variable
    type Value: Into<f64> + From<f64>;

    /// Obtains the raw FFI identifier for this named variable
    fn as_raw_named_variable() -> ffi::RawNamedVariable;
}

/// Constructs bindings for interacting with a named variable
#[macro_export]
macro_rules! named_variable {
    ($ty:ident ($val:ty): $name:literal; $description:literal) => {
        #[doc = $description]
        #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
        pub struct $ty;

        impl $ty {
            const VARIABLE_NAME: &'static str = concat!($name, "\0");

            /// Sets the variable as a raw value
            ///
            /// The value must be convertible into a raw 64-bit float
            #[inline]
            fn set_raw(value: <Self as $crate::NamedVariable>::Value)
            {
                $crate::ffi::RawNamedVariable::set(<Self as $crate::NamedVariable>::as_raw_named_variable(), value.into())
            }

            /// Reads the variable as a raw value
            ///
            /// The value must be convertible from a raw 64-bit float
            #[inline]
            fn read_raw() -> <Self as $crate::NamedVariable>::Value
            {
                $crate::ffi::RawNamedVariable::get(<Self as $crate::NamedVariable>::as_raw_named_variable()).into()
            }
        }

        impl $crate::NamedVariable for $ty {
            type Value = $val;

            #[inline]
            fn as_raw_named_variable() -> $crate::ffi::RawNamedVariable {
                static RAW_UNIT_VALUE: $crate::once_cell::Lazy<$crate::ffi::RawNamedVariable> = $crate::once_cell::Lazy::new(|| unsafe {
                    $crate::ffi::RawNamedVariable::register_new($ty::VARIABLE_NAME)
                });
                *RAW_UNIT_VALUE
            }
        }
    };
}