Skip to main content

lotus_script/
var.rs

1//! Lesen und Schreiben von Script-Variablen.
2//!
3//! Reading and writing script variables.
4
5use lotus_script_sys::{FfiObject, FromFfi};
6use lotus_shared::content::ContentId;
7
8/// Typ, der an Script-Variablen gebunden werden kann.
9///
10/// Type that can be bound to script variables.
11pub trait VariableType {
12    /// Rückgabetyp beim Lesen der Variable.
13    ///
14    /// Return type when reading the variable.
15    type Output;
16
17    /// Liest die Variable mit dem angegebenen Namen.
18    ///
19    /// Reads the variable with the given name.
20    fn get_var(name: &str) -> Self::Output;
21    /// Schreibt die Variable mit dem angegebenen Namen.
22    ///
23    /// Writes the variable with the given name.
24    fn set_var(name: &str, var: Self);
25}
26
27#[doc(hidden)]
28pub enum Persistence {
29    Session,
30    Permanent,
31}
32
33macro_rules! impl_variable_type {
34    ($type:ty, $get:ident, $set:ident) => {
35        impl VariableType for $type {
36            type Output = $type;
37
38            fn get_var(name: &str) -> Self::Output {
39                let name = FfiObject::new(&name);
40                unsafe { lotus_script_sys::var::$get(name.packed()) as _ }
41            }
42
43            fn set_var(name: &str, var: Self) {
44                let name = FfiObject::new(&name);
45                unsafe { lotus_script_sys::var::$set(name.packed(), var as _) }
46            }
47        }
48    };
49}
50
51impl_variable_type!(i8, get_i64, set_i64);
52impl_variable_type!(i16, get_i64, set_i64);
53impl_variable_type!(i32, get_i64, set_i64);
54impl_variable_type!(i64, get_i64, set_i64);
55
56impl_variable_type!(u8, get_i64, set_i64);
57impl_variable_type!(u16, get_i64, set_i64);
58impl_variable_type!(u32, get_i64, set_i64);
59impl_variable_type!(u64, get_i64, set_i64);
60
61impl_variable_type!(f32, get_f64, set_f64);
62impl_variable_type!(f64, get_f64, set_f64);
63
64impl VariableType for bool {
65    type Output = bool;
66
67    fn get_var(name: &str) -> Self::Output {
68        let name = FfiObject::new(&name);
69        unsafe { lotus_script_sys::var::get_bool(name.packed()) != 0 }
70    }
71
72    fn set_var(name: &str, var: Self) {
73        let name = FfiObject::new(&name);
74        unsafe {
75            lotus_script_sys::var::set_bool(
76                name.packed(),
77                match var {
78                    true => 1,
79                    false => 0,
80                },
81            )
82        }
83    }
84}
85
86impl VariableType for String {
87    type Output = String;
88
89    fn get_var(name: &str) -> Self::Output {
90        let name = FfiObject::new(&name);
91        let ptr = unsafe { lotus_script_sys::var::get_string(name.packed()) };
92        String::from_ffi(ptr)
93    }
94
95    fn set_var(name: &str, var: Self) {
96        let name = FfiObject::new(&name);
97        let value = FfiObject::new(&var);
98        unsafe { lotus_script_sys::var::set_string(name.packed(), value.packed()) }
99    }
100}
101
102impl VariableType for &str {
103    type Output = String;
104
105    fn get_var(name: &str) -> Self::Output {
106        let name = FfiObject::new(&name);
107        let ptr = unsafe { lotus_script_sys::var::get_string(name.packed()) };
108        String::from_ffi(ptr)
109    }
110
111    fn set_var(name: &str, var: Self) {
112        let name = FfiObject::new(&name);
113        let value = FfiObject::new(&var.to_string());
114        unsafe { lotus_script_sys::var::set_string(name.packed(), value.packed()) }
115    }
116}
117
118impl VariableType for ContentId {
119    type Output = ContentId;
120
121    fn get_var(name: &str) -> Self {
122        let name = FfiObject::new(&name);
123        let ptr = unsafe { lotus_script_sys::var::get_content_id(name.packed()) };
124        FfiObject::from_packed(ptr).deserialize()
125    }
126
127    fn set_var(name: &str, var: Self) {
128        let name = FfiObject::new(&name);
129        let value = FfiObject::new(&var);
130        unsafe { lotus_script_sys::var::set_content_id(name.packed(), value.packed()) }
131    }
132}
133
134/// Typisierte Referenz auf eine Script-Variable nach Namen.
135///
136/// Typed reference to a script variable by name.
137pub struct Variable<T> {
138    name: String,
139    _phantom: std::marker::PhantomData<T>,
140}
141
142impl<T> Variable<T> {
143    /// Erstellt eine Variable-Referenz für den angegebenen Namen.
144    ///
145    /// Creates a variable reference for the given name.
146    pub fn new(name: &str) -> Self {
147        Self {
148            name: name.to_string(),
149            _phantom: std::marker::PhantomData,
150        }
151    }
152}
153
154impl<T: VariableType> Variable<T> {
155    /// Liest den aktuellen Wert der Variable.
156    ///
157    /// Reads the current value of the variable.
158    pub fn get(&self) -> T::Output {
159        T::get_var(&self.name)
160    }
161
162    /// Schreibt einen neuen Wert in die Variable.
163    ///
164    /// Writes a new value to the variable.
165    pub fn set(&self, value: T) {
166        T::set_var(&self.name, value);
167    }
168}
169
170/// Liest eine Script-Variable nach Namen.
171///
172/// Reads a script variable by name.
173pub fn get_var<T: VariableType>(name: &str) -> T::Output {
174    T::get_var(name)
175}
176
177/// Schreibt eine Script-Variable nach Namen.
178///
179/// Writes a script variable by name.
180pub fn set_var<T: VariableType>(name: &str, var: T) {
181    T::set_var(name, var);
182}