feagi_sensorimotor/
connector_cache.rs1use crate::caching::MotorDeviceCache;
2use crate::caching::SensorDeviceCache;
3use crate::configuration::jsonable::JSONInputOutputDefinition;
4use crate::feedbacks::{FeedBackRegistration, FeedbackRegistrar, FeedbackRegistrationTargets};
5use feagi_structures::FeagiDataError;
6use std::fmt;
7use std::sync::{Arc, Mutex, MutexGuard};
8
9fn lock_recover<'a, T>(mutex: &'a Mutex<T>) -> MutexGuard<'a, T> {
12 match mutex.lock() {
13 Ok(guard) => guard,
14 Err(poisoned) => {
15 mutex.clear_poison();
16 poisoned.into_inner()
17 }
18 }
19}
20
21#[derive(Debug)]
22pub struct ConnectorCache {
23 sensor_cache: Arc<Mutex<SensorDeviceCache>>,
24 motor_cache: Arc<Mutex<MotorDeviceCache>>,
25 feedback_registrar: FeedbackRegistrar,
26}
27
28impl Default for ConnectorCache {
29 fn default() -> Self {
30 Self::new()
31 }
32}
33
34impl ConnectorCache {
35 pub fn new() -> Self {
36 ConnectorCache {
37 sensor_cache: Arc::new(Mutex::new(SensorDeviceCache::new())),
38 motor_cache: Arc::new(Mutex::new(MotorDeviceCache::new())),
39 feedback_registrar: FeedbackRegistrar::new(),
40 }
41 }
42
43 pub fn get_sensor_cache(&self) -> MutexGuard<'_, SensorDeviceCache> {
44 lock_recover(&self.sensor_cache)
45 }
46
47 pub fn get_sensor_cache_ref(&self) -> Arc<Mutex<SensorDeviceCache>> {
48 self.sensor_cache.clone()
49 }
50
51 pub fn get_motor_cache(&self) -> MutexGuard<'_, MotorDeviceCache> {
52 lock_recover(&self.motor_cache)
53 }
54
55 pub fn get_motor_cache_ref(&self) -> Arc<Mutex<MotorDeviceCache>> {
56 self.motor_cache.clone()
57 }
58
59 pub fn register_feedback(
60 &mut self,
61 feedback: FeedBackRegistration,
62 target: FeedbackRegistrationTargets,
63 ) -> Result<(), FeagiDataError> {
64 let sensors = self.get_sensor_cache_ref();
65 let motors = self.get_motor_cache_ref();
66
67 feedback.try_registering_feedback_and_save(
68 &mut self.feedback_registrar,
69 sensors,
70 motors,
71 target,
72 )?;
73 Ok(())
74 }
75
76 pub fn export_device_registrations_as_config_json(
77 &self,
78 ) -> Result<serde_json::Value, FeagiDataError> {
79 let mut output = JSONInputOutputDefinition::new();
80 self.get_sensor_cache()
81 .export_to_input_definition(&mut output)?;
82 self.get_motor_cache()
83 .export_to_output_definition(&mut output)?;
84 output.set_feedbacks(self.feedback_registrar.clone());
85 serde_json::to_value(output)
86 .map_err(|err| FeagiDataError::SerializationError(err.to_string()))
87 }
88
89 pub fn import_device_registrations_as_config_json(
90 &mut self,
91 json: serde_json::Value,
92 ) -> Result<(), FeagiDataError> {
93 let definition: JSONInputOutputDefinition = serde_json::from_value(json)
95 .map_err(|err| FeagiDataError::DeserializationError(err.to_string()))?;
96 self.get_motor_cache()
97 .import_from_output_definition(&definition)?;
98 self.get_sensor_cache()
99 .import_from_input_definition(&definition)?;
100 self.feedback_registrar = definition.get_feedbacks().clone();
101 self.feedback_registrar
104 .reload_all_from_self(self.get_sensor_cache_ref(), self.get_motor_cache_ref())?;
105 Ok(())
106 }
107}
108
109impl fmt::Display for ConnectorCache {
110 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111 write!(f, "ConnectorAgent")
112 }
113}