diff --git a/mission_rust/src/fsrc/datasets/mod.rs b/mission_rust/src/fsrc/datasets/mod.rs index 0485888..33fa489 100644 --- a/mission_rust/src/fsrc/datasets/mod.rs +++ b/mission_rust/src/fsrc/datasets/mod.rs @@ -1,21 +1,5 @@ -use core::any::Any; - -use crate::check_global_threading_available; - -use super::objectmanager::SystemObjectIF; use super::{mutex, objectmanager}; - -pub trait DatapoolOwnerIF { - fn get_set(&self, _type_id: core::any::TypeId) -> Option<&dyn DataSetIF> { - None - } -} - -pub trait DataSetIF { - fn get_type_id(&self) -> core::any::TypeId; // TODO can we get rid of this? Currently, it helps implementing DatapoolOwnerIF::get_set() but if we can optimize/generate that, this might be not needed any more - fn get_actual_data(&self) -> &dyn core::any::Any; - fn get_mutex(&self) -> mutex::RawMutex; -} +use crate::check_global_threading_available; pub struct OwnedDataset { actual_data: T, @@ -28,22 +12,6 @@ pub struct ReferencedDataset { mutex: Option, } -impl DataSetIF for OwnedDataset { - fn get_type_id(&self) -> core::any::TypeId { - core::any::TypeId::of::() - } - - fn get_actual_data(&self) -> &dyn core::any::Any { - // only return pointer when threading - check_global_threading_available!(); - &self.actual_data - } - - fn get_mutex(&self) -> mutex::RawMutex { - return self.mutex.clone(); - } -} - impl OwnedDataset { pub fn new() -> OwnedDataset { OwnedDataset:: { @@ -86,17 +54,10 @@ impl ReferencedDataset { } pub fn read(&mut self) -> Result { - let _mutex_guard = match &self.mutex { - None => return Err(()), - Some(mutex) => match mutex.take() { - Err(()) => return Err(()), - Ok(guard) => guard, - }, - }; - let pointer = match self.actual_data { - None => return Err(()), - Some(data) => data, - }; + let mutex = self.mutex.as_ref().ok_or(())?; + let _guard = mutex.take()?; + let pointer = self.actual_data.ok_or(())?; + // we are only allowed to use the pointer during threading check_global_threading_available!(); Ok(unsafe { (*pointer).clone() }) @@ -108,20 +69,21 @@ impl ReferencedDataset { owner_of_the_set: objectmanager::ObjectId, ) -> Result<(), ()> { let owner = object_manager.get_object(owner_of_the_set)?; - let type_id = core::any::TypeId::of::(); - let other_set = match owner.get_set(type_id) { - None => { - return Err(()); //TODO panic? -> should initialize just panic if failing? - } - Some(set) => set, - }; - // let's recheck that owner.get_set() did not lie about the type_id - if let Some(other_data) = other_set.get_actual_data().downcast_ref::() { - self.actual_data = Some(other_data); - } else { - return Err(()); - } - self.mutex = Some(other_set.get_mutex()); + owner.for_each_member_return(&mut |x, _| { + self.try_initialize_from(x.downcast_ref()?); + None + }); Ok(()) } + + fn try_initialize_from(&mut self, other: &OwnedDataset) { + // TODO check some id to allow the other to own multiple + // instances of . Otherwise, this will select the last + // one. + // if !self.id == other.id { + // return + // } + self.actual_data = Some(&other.actual_data); + self.mutex = Some(other.mutex.clone()); + } } diff --git a/mission_rust/src/fsrc/mod.rs b/mission_rust/src/fsrc/mod.rs index a892f6b..9cf4c32 100644 --- a/mission_rust/src/fsrc/mod.rs +++ b/mission_rust/src/fsrc/mod.rs @@ -7,4 +7,5 @@ pub mod tasks; pub mod objectmanager; pub mod datasets; pub mod store; -mod mutex; \ No newline at end of file +mod mutex; +pub mod introspection; \ No newline at end of file diff --git a/mission_rust/src/fsrc/objectmanager.rs b/mission_rust/src/fsrc/objectmanager.rs index 36e6cc7..b172776 100644 --- a/mission_rust/src/fsrc/objectmanager.rs +++ b/mission_rust/src/fsrc/objectmanager.rs @@ -5,7 +5,7 @@ pub trait ObjectManager<'a> { fn get_object(&self, id: ObjectId) -> Result<&'a dyn SystemObjectIF, ()>; } -pub trait SystemObjectIF: tasks::ExecutableObjectIF + datasets::DatapoolOwnerIF { +pub trait SystemObjectIF: tasks::ExecutableObjectIF + introspection::Introspection { fn get_id(&self) -> ObjectId; fn initialize(&mut self, object_manager: &dyn ObjectManager) -> Result<(), ()>; fn get_command_queue(&self) -> queues::MessageQueueSender; diff --git a/mission_rust/src/fsrc/store.rs b/mission_rust/src/fsrc/store.rs index 3950f6b..37cbd28 100644 --- a/mission_rust/src/fsrc/store.rs +++ b/mission_rust/src/fsrc/store.rs @@ -39,6 +39,7 @@ impl<'a> Store<'a> { } } +// TODO needs to be able to be uninitialized as it should be usable as member // A smart pointer to a Store protecting insane (static) pointer usage // only works during threading, panics otherwise struct StoreAccessor { diff --git a/mission_rust/src/lib.rs b/mission_rust/src/lib.rs index 65a341e..514ad7a 100644 --- a/mission_rust/src/lib.rs +++ b/mission_rust/src/lib.rs @@ -3,12 +3,11 @@ //TODO os errors in API calls //TODO look into a pattern for late initialized stuff, currently using Option (can we make it compile time safe?) -mod fsrc; +pub mod fsrc; use core::fmt::Write; use core::panic::PanicInfo; -use fsrc::datasets::{DataSetIF, DatapoolOwnerIF}; use fsrc::objectmanager::SystemObjectIF; use fsrc::*; @@ -49,16 +48,16 @@ extern "C" fn rust_main() { sifln!("Mission done"); } -#[derive (Copy, Clone, Default)] +#[derive(Copy, Clone, Default)] struct HandlerData { x: u32, - y: f32 + y: f32, } struct Handler { id: objectmanager::ObjectId, command_queue: queues::MessageQueue<10>, - data: datasets::OwnedDataset + data: datasets::OwnedDataset, } struct HandlerSender { @@ -66,10 +65,9 @@ struct HandlerSender { other_handler: objectmanager::ObjectId, cycle: u8, other_handler_queue: queues::MessageQueueSender, - other_data: datasets::ReferencedDataset + other_data: datasets::ReferencedDataset, } - impl Handler { fn handle_message(&self, message: queues::Message) { match message { @@ -132,17 +130,23 @@ impl SystemObjectIF for Handler { } } -impl datasets::DatapoolOwnerIF for Handler { - fn get_set(&self, type_id: core::any::TypeId) -> Option<&dyn datasets::DataSetIF>{ - if type_id == self.data.get_type_id(){ - Some(&self.data) - } else { - None - } - } +impl introspection::Introspection for HandlerSender { + fn for_each_member(&self, f: &mut dyn FnMut(&dyn core::any::Any, &str) -> ()) {} + + fn for_each_member_return(&self, f: &mut dyn FnMut(&dyn core::any::Any, &str) -> Option<()>) {} } -impl DatapoolOwnerIF for HandlerSender {} +impl introspection::Introspection for Handler { + fn for_each_member(&self, f: &mut dyn FnMut(&dyn core::any::Any, &str) -> ()) { + (*f)(&self.command_queue, "command_queue"); + (*f)(&self.data, "data"); + } + + fn for_each_member_return(&self, f: &mut dyn FnMut(&dyn core::any::Any, &str) -> Option<()>) { + (*f)(&self.command_queue, "command_queue"); + (*f)(&self.data, "data"); + } +} impl SystemObjectIF for HandlerSender { fn get_command_queue(&self) -> crate::fsrc::queues::MessageQueueSender { @@ -154,14 +158,14 @@ impl SystemObjectIF for HandlerSender { } fn initialize(&mut self, object_manager: &dyn objectmanager::ObjectManager) -> Result<(), ()> { let other_handler_maybe = object_manager.get_object(self.other_handler); - let other_handler = - match other_handler_maybe { + let other_handler = match other_handler_maybe { Ok(other) => other, Err(_) => return Err(()), }; self.other_handler_queue = other_handler.get_command_queue(); - self.other_data.initialize(object_manager, self.other_handler)?; + self.other_data + .initialize(object_manager, self.other_handler)?; Ok(()) } } @@ -172,14 +176,14 @@ fn mission() { let mut h1 = Handler { id: 1, command_queue: queues::MessageQueue::new(), - data: datasets::OwnedDataset::new() + data: datasets::OwnedDataset::new(), }; let mut h2 = HandlerSender { id: 2, other_handler: 3, cycle: 0, other_handler_queue: queues::MessageQueueSender::new(), - other_data: datasets::ReferencedDataset::new() + other_data: datasets::ReferencedDataset::new(), }; let array: &mut [&mut dyn objectmanager::SystemObjectIF] = &mut [&mut h1];