1pub mod chip;
2mod rack;
3use std::ops::Index;
4
5use concat_idents::concat_idents;
6use convert_case::Case;
7use convert_case::Casing;
8use enum_dispatch::enum_dispatch;
9
10use self::chip::CodeRunner;
11pub use self::rack::Rack;
12use crate::deserializer::Deserializer;
13use crate::field::Field;
14use crate::value::YololValue;
15
16#[enum_dispatch]
19pub trait DeviceTrait {
20 fn get_field(&self, field: &str) -> Option<&YololValue>;
21 fn get_field_mut(&mut self, field: &str) -> Option<&mut YololValue>;
22 fn get_device_name(&self) -> String;
23 fn deserialize<D>(&mut self, deserializer: &D)
24 where
25 D: Deserializer<D, Output = D> + Index<String>;
26}
27
28#[allow(clippy::large_enum_variant)]
29#[enum_dispatch(DeviceTrait)]
30#[derive(Debug)]
31pub enum Device<R: CodeRunner + Default> {
32 Button(Button),
33 CargoBeam(CargoBeam),
34 CargoLockFrame(CargoLockFrame),
35 ChipSocket(ChipSocket),
36 FixedMount(FixedMount),
37 FlightControlUnit(FlightControlUnit),
38 Generator(Generator),
39 Hinge(Hinge),
40 InformationScreen(InformationScreen),
41 Lamp(Lamp),
42 Lever(Lever),
43 MainFlightComputer(MainFlightComputer),
44 MiningLaser(MiningLaser),
45 ModularDisplay(ModularDisplay),
46 Rack(Rack<R>),
47 RadioReceiver(RadioReceiver),
48 RadioTransmitter(RadioTransmitter),
49 RailRelay(RailRelay),
50 RailSensorStrip(RailSensorStrip),
51 RailTrigger(RailTrigger),
52 RangeFinder(RangeFinder),
53 Relay(Relay),
54 Tank(Tank),
55 Thruster(Thruster),
56 Turntable(Turntable),
57}
58
59impl<R: CodeRunner + Default> Device<R> {
60 pub fn deserialize<D>(deserializer: &D) -> Option<Self>
61 where
62 D: Deserializer<D, Output = D> + Index<String>,
63 {
64 let device_type = deserializer
65 .get_type()
66 .expect("Need a type for deserializing");
67 println!("trying to deserialize {}", device_type);
68
69 let device: Option<Device<R>> = match device_type.as_str() {
70 "!button" => Some(Button::default().into()),
71 "!cargo_beam" => Some(CargoBeam::default().into()),
72 "!cargo_lock_frame" => Some(CargoLockFrame::default().into()),
73 "!chip_socket" => Some(ChipSocket::default().into()),
74 "!fixed_mount" => Some(FixedMount::default().into()),
75 "!flight_control_unit" => Some(FlightControlUnit::default().into()),
76 "!generator" => Some(Generator::default().into()),
77 "!hinge" => Some(Hinge::default().into()),
78 "!information_screen" => Some(InformationScreen::default().into()),
79 "!lamp" => Some(Lamp::default().into()),
80 "!lever" => Some(Lever::default().into()),
81 "!main_flight_computer" => Some(MainFlightComputer::default().into()),
82 "!mining_laser" => Some(MiningLaser::default().into()),
83 "!modular_display" => Some(ModularDisplay::default().into()),
84 "!rack" => Some(Rack::default().into()),
85 "!radio_receiver" => Some(RadioReceiver::default().into()),
86 "!radio_transmitter" => Some(RadioTransmitter::default().into()),
87 "!rail_relay" => Some(RailRelay::default().into()),
88 "!rail_sensor_strip" => Some(RailSensorStrip::default().into()),
89 "!rail_trigger" => Some(RailTrigger::default().into()),
90 "!range_finder" => Some(RangeFinder::default().into()),
91 "!relay" => Some(RailRelay::default().into()),
92 "!tank" => Some(Tank::default().into()),
93 "!thruster" => Some(Thruster::default().into()),
94 "!turntable" => Some(Turntable::default().into()),
95 _ => None,
96 };
97
98 if let Some(mut device) = device {
99 device.deserialize(deserializer);
100 Some(device)
101 } else {
102 None
103 }
104 }
105}
106
107#[macro_export]
108macro_rules! deserialize_field_name {
109 ($device:ident, $name:ident, $deserializer:ident) => {{
110 use convert_case::Case;
111 use convert_case::Casing;
112 let name = stringify!($name).to_case(Case::Pascal);
113 $device.$name.set_name(
114 $deserializer[name.to_string()]
115 .as_str()
116 .unwrap_or(name.as_str())
117 .to_string(),
118 );
119 }};
120}
121
122macro_rules! make_device {
123 ($name:ident $(, $field:ident)+ $(,)?) => {
124 #[derive(Debug, Default)]
125 pub struct $name {
126 $($field:Field,)+
127 }
128
129 impl $name{
130 $(
131 pub fn $field(& self)->&Field{
132 &self.$field
133 }
134 concat_idents!(fn_name = $field,_mut{
135 pub fn fn_name (&mut self)->&mut Field{
136 &mut self.$field
137 }
138 });
139 )+
140 }
141
142 impl DeviceTrait for $name{
143 fn deserialize<D>(&mut self, deserializer: &D)
144 where
145 D: Deserializer<D, Output = D> + Index<String>,
146 <D as Index<String>>::Output: Deserializer<D, Output = D> + Index<String>,
147 {
148 $(deserialize_field_name!(self, $field, deserializer);)+
149 }
150
151 fn get_device_name(&self) -> String {
152 stringify!($name).to_string().to_case(Case::Snake)
153 }
154
155 fn get_field(&self, field: &str) -> Option<&YololValue>{
156 $(
157 if self.$field.name() == field {
158 return Some(&self.$field)
159 }
160 )+
161 None
162 }
163
164 fn get_field_mut(&mut self, field: &str) -> Option<&mut YololValue>{
165 $(
166 if self.$field.name() == field {
167 return Some(&mut self.$field)
168 }
169 )+
170 None
171 }
172 }
173 };
174}
175
176make_device!(
177 Button,
178 button_state,
179 button_on_state_value,
180 button_off_state_value,
181 button_style
182);
183make_device!(CargoBeam, cargo_beam_on_state, cargo_beam_search_length);
184make_device!(CargoLockFrame, cargo_frame_state);
185make_device!(
186 ChipSocket,
187 button_state,
188 button_on_state_value,
189 button_off_state_value,
190 button_style
191);
192make_device!(FixedMount, current_state, on_state, off_state, button_style);
193make_device!(
194 FlightControlUnit,
195 fcu_mfc_io,
196 fcu_general_multiplier,
197 fcu_forward,
198 fcu_backward,
199 fcu_rotational_pitch,
200 fcu_rotational_yaw,
201 fcu_rotational_roll,
202 fcu_up_down,
203 fcu_right_left,
204 fcu_fwd_bwd_pitch,
205 fcu_fwd_bwd_yaw,
206 fcu_fwd_bwd_roll
207);
208make_device!(
209 Generator,
210 fuel_chamber_fuel,
211 fuel_chamber_max_fuel,
212 fuel_chamber_unit_rate_limit,
213 fuel_chamber_unit_rate,
214 generator_unit_rate_limit,
215 generator_unit_rate,
216 stored_coolant,
217 max_coolant,
218 cooler_unit_rate_limit,
219 cooler_unit_rate,
220 socket_unit_rate_limit,
221 socket_unit_rate
222);
223make_device!(
224 Hinge,
225 door_open_state,
226 door_current_state,
227 end_rotation,
228 start_rotation,
229 target_velocity
230);
231make_device!(InformationScreen, info_screen_content);
232make_device!(
233 Lamp,
234 lamp_on,
235 lamp_lumens,
236 lamp_color_hue,
237 lamp_color_saturation,
238 lamp_color_value,
239 lamp_range
240);
241make_device!(
242 Lever,
243 lever_state,
244 lever_min_output,
245 lever_max_output,
246 lever_center_output,
247 lever_center_dead_zone,
248 lever_centering_speed,
249 lever_binds_move_speed
250);
251make_device!(
252 MainFlightComputer,
253 fcu_mfc_io1,
254 fcu_mfc_io2,
255 thruster_power_level01,
256 thruster_power_level02,
257 thruster_power_level03,
258 thruster_power_level04,
259 thruster_power_level05,
260 thruster_power_level06,
261 thruster_power_level07,
262 thruster_power_level08,
263 thruster_power_level09,
264 thruster_power_level10,
265 thruster_power_level11,
266 thruster_power_level12,
267 thruster_power_level13,
268 thruster_power_level14,
269 thruster_power_level15,
270 thruster_power_level16,
271 thruster_power_level17,
272 thruster_power_level18,
273 thruster_power_level19,
274 thruster_power_level20,
275 thruster_power_level21,
276 thruster_power_level22,
277 thruster_power_level23,
278 thruster_power_level24,
279 thruster_power_level25,
280 thruster_power_level26,
281 thruster_power_level27,
282 thruster_power_level28,
283 thruster_power_level29,
284 thruster_power_level30,
285 thruster_power_level31,
286 thruster_power_level32,
287 thruster_power_level33,
288 thruster_power_level34,
289 thruster_power_level35,
290 thruster_power_level36,
291 thruster_power_level37,
292 thruster_power_level38,
293 thruster_power_level39,
294 thruster_power_level40,
295 thruster_power_level41,
296 thruster_power_level42,
297 thruster_power_level43,
298 thruster_power_level44,
299 thruster_power_level45,
300 thruster_power_level46,
301 thruster_power_level47,
302 thruster_power_level48,
303 thruster_power_level49,
304 thruster_power_level50,
305);
306make_device!(MiningLaser, mining_laser_on, mining_laser_beam_length);
307make_device!(ModularDisplay, panel_value);
308make_device!(
309 RadioReceiver,
310 message,
311 signal_strength,
312 listen_angle,
313 target_message,
314 target_frequency,
315 frequency,
316 receiver_pitch,
317 receiver_current_pitch,
318 max_rotation,
319 min_rotation,
320 target_velocity
321);
322make_device!(
323 RadioTransmitter,
324 transmit_message,
325 transmit_range,
326 frequency
327);
328make_device!(RailRelay, is_enabled);
329make_device!(
330 RailSensorStrip,
331 rail_sensor_output,
332 rail_sensor_delta,
333 rail_sensor_mover_filter
334);
335make_device!(
336 RailTrigger,
337 rail_trigger_output,
338 rail_trigger_value,
339 rail_trigger_read_mover
340);
341make_device!(
342 RangeFinder,
343 range_finder_on_state,
344 range_finder_search_length,
345 range_finder_distance
346);
347make_device!(Relay, is_enabled);
348make_device!(
349 Tank,
350 gas_container_stored_resource,
351 gas_container_max_resource,
352 is_open_id,
353 flow_id
354);
355make_device!(Thruster, thruster_state, thruster_current_thrust);
356make_device!(
357 Turntable,
358 turret_rotation,
359 turret_current_rotation,
360 max_rotation,
361 min_rotation,
362 target_velocity
363);