From 59f4a82da9b72bcee28fd84da41ce7f85e26324c Mon Sep 17 00:00:00 2001 From: Ulrich Mohr Date: Fri, 8 Dec 2023 22:21:49 +0100 Subject: [PATCH] working on datasets, stopped by "trait upcasting coercion is experimental" --- mission_rust/src/fsrc/datasets/mod.rs | 95 ++++++++++++++++++++++++++ mission_rust/src/fsrc/mod.rs | 3 +- mission_rust/src/fsrc/objectmanager.rs | 2 +- mission_rust/src/lib.rs | 37 ++++++++-- 4 files changed, 131 insertions(+), 6 deletions(-) create mode 100644 mission_rust/src/fsrc/datasets/mod.rs diff --git a/mission_rust/src/fsrc/datasets/mod.rs b/mission_rust/src/fsrc/datasets/mod.rs new file mode 100644 index 0000000..dea8b6c --- /dev/null +++ b/mission_rust/src/fsrc/datasets/mod.rs @@ -0,0 +1,95 @@ +#[derive(Copy, Clone, PartialEq)] +pub struct TypeId { + id: usize, +} + +// inspired by https://github.com/jswrenn/deflect/ +pub trait Reflection { + #[inline(never)] + fn get_type_id(&self) -> TypeId { + TypeId { + id: ::get_type_id as usize, + } + } +} + +pub trait DatapoolOwnerIF { + fn get_set(&self, type_id: TypeId) -> Option<&dyn DataSetIF> { + None + } +} + +pub trait DataSetIF { + fn get_type_id(&self) -> TypeId; + fn get_actual_data(&self) -> &dyn Reflection; + //fn get_mutex_handle(&self) -> TODO +} + +pub struct OwnedDataset { + actual_data: T, +} + +pub struct ReferencedDataset { + //we use a pointer here to avoid lifetimes + actual_data: Option<*const T>, +} + +impl DataSetIF for OwnedDataset { + fn get_type_id(&self) -> TypeId { + self.actual_data.get_type_id() + } + + fn get_actual_data(&self) -> &dyn Reflection { + &self.actual_data + } +} + +impl OwnedDataset { + pub fn new() -> OwnedDataset { + OwnedDataset:: { + actual_data: T::default(), + } + } + + pub fn read(&mut self) -> T { + //mutex + self.actual_data + } + + pub fn commit(&mut self, data: T) { + //mutex + self.actual_data = data; + } +} + +impl ReferencedDataset { + pub fn new() -> ReferencedDataset { + ReferencedDataset:: { actual_data: None } + } + + pub fn read(&mut self) -> Result { + //mutex + match self.actual_data { + None => Err(()), + Some(data) => Ok(unsafe { *data }), + } + } + + pub fn initialize(&mut self, owner: &dyn DatapoolOwnerIF) -> Result<(), ()> { + let temp: T = T::default(); //TODO find nicer solution whithout local instance and trait bound to Default + let type_id = temp.get_type_id(); + let other_set: &dyn DataSetIF; + match owner.get_set(type_id) { + None => { + return Err(()); + } + Some(set) => { + other_set = set; + } + } + //pointer cast is safe because we checked the type_id + self.actual_data = Some(other_set.get_actual_data() as *const dyn Reflection as *const T); + //self.mutex = other.mutex + Ok(()) + } +} diff --git a/mission_rust/src/fsrc/mod.rs b/mission_rust/src/fsrc/mod.rs index 22b2765..cc5c015 100644 --- a/mission_rust/src/fsrc/mod.rs +++ b/mission_rust/src/fsrc/mod.rs @@ -2,4 +2,5 @@ pub mod sif; pub mod queues; pub mod osal; pub mod tasks; -pub mod objectmanager; \ No newline at end of file +pub mod objectmanager; +pub mod datasets; \ No newline at end of file diff --git a/mission_rust/src/fsrc/objectmanager.rs b/mission_rust/src/fsrc/objectmanager.rs index 2071a96..36e6cc7 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 { +pub trait SystemObjectIF: tasks::ExecutableObjectIF + datasets::DatapoolOwnerIF { 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/lib.rs b/mission_rust/src/lib.rs index 0a537a7..5a8054f 100644 --- a/mission_rust/src/lib.rs +++ b/mission_rust/src/lib.rs @@ -9,6 +9,7 @@ mod fsrc; use core::fmt::Write; use core::panic::PanicInfo; +use fsrc::datasets::{DataSetIF, DatapoolOwnerIF}; use fsrc::objectmanager::SystemObjectIF; use fsrc::*; @@ -49,9 +50,18 @@ extern "C" fn rust_main() { sifln!("Mission done"); } +#[derive (Copy, Clone, Default)] +struct HandlerData { + x: u32, + y: f32 +} + +impl datasets::Reflection for HandlerData {} + struct Handler { id: objectmanager::ObjectId, command_queue: queues::MessageQueue, + data: datasets::OwnedDataset } struct HandlerSender { @@ -59,8 +69,10 @@ struct HandlerSender { other_handler: objectmanager::ObjectId, cycle: u8, other_handler_queue: queues::MessageQueueSender, + other_data: datasets::ReferencedDataset } + impl Handler { fn handle_message(&self, message: queues::Message) { match message { @@ -123,6 +135,18 @@ impl SystemObjectIF for Handler { } } +impl datasets::DatapoolOwnerIF for Handler { + fn get_set(&self, type_id: datasets::TypeId) -> Option<&dyn datasets::DataSetIF>{ + if type_id == self.data.get_type_id(){ + Some(&self.data) + } else { + None + } + } +} + +impl DatapoolOwnerIF for HandlerSender {} + impl SystemObjectIF for HandlerSender { fn get_command_queue(&self) -> crate::fsrc::queues::MessageQueueSender { queues::MessageQueueSender::new() @@ -131,11 +155,14 @@ impl SystemObjectIF for HandlerSender { self.id } fn initialize(&mut self, object_manager: &dyn objectmanager::ObjectManager) -> Result<(), ()> { - let other_handler = object_manager.get_object(self.other_handler); - match other_handler { - Ok(other) => self.other_handler_queue = other.get_command_queue(), + let other_handler_maybe = object_manager.get_object(self.other_handler); + let other_handler = + match other_handler_maybe { + Ok(other) => other, Err(_) => return Err(()), - } + }; + self.other_handler_queue = other_handler.get_command_queue(); + //TODO self.other_data.initialize(other_handler); // oh come on :/ Ok(()) } } @@ -146,12 +173,14 @@ fn mission() { let mut h1 = Handler { id: 1, command_queue: queues::MessageQueue::new(5), + 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() }; let array: &mut [&mut dyn objectmanager::SystemObjectIF] = &mut [&mut h1];