From 4460e470b2ce95bc2b9c30fb542c81035854235b Mon Sep 17 00:00:00 2001 From: Ulrich Mohr Date: Sat, 3 Feb 2024 00:03:49 +0100 Subject: [PATCH] this time, we won't reinvent the wheel --- mission_rust/src/fsrc/datasets/mod.rs | 53 +++++++++++---------------- mission_rust/src/fsrc/store.rs | 10 ++--- mission_rust/src/lib.rs | 4 +- 3 files changed, 26 insertions(+), 41 deletions(-) diff --git a/mission_rust/src/fsrc/datasets/mod.rs b/mission_rust/src/fsrc/datasets/mod.rs index 911d2a3..771fbe4 100644 --- a/mission_rust/src/fsrc/datasets/mod.rs +++ b/mission_rust/src/fsrc/datasets/mod.rs @@ -1,52 +1,39 @@ +use core::any::Any; + use crate::check_global_threading_available; use super::objectmanager::SystemObjectIF; use super::{mutex, objectmanager}; -#[derive(Copy, Clone, PartialEq)] -pub struct TypeId { - id: usize, -} - -// inspired by Jack Wrenn at https://github.com/jswrenn/deflect/ -pub trait HasTypeId { - #[inline(never)] - fn get_type_id(&self) -> TypeId { - TypeId { - id: Self::get_type_id as usize, - } - } -} - pub trait DatapoolOwnerIF { - fn get_set(&self, _type_id: TypeId) -> Option<&dyn DataSetIF> { + fn get_set(&self, _type_id: core::any::TypeId) -> Option<&dyn DataSetIF> { None } } pub trait DataSetIF { - fn get_type_id(&self) -> TypeId; - fn get_actual_data(&self) -> &dyn HasTypeId; + 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; } -pub struct OwnedDataset { +pub struct OwnedDataset { actual_data: T, mutex: mutex::RawMutex, } -pub struct ReferencedDataset { +pub struct ReferencedDataset { //we use a pointer here to avoid lifetimes actual_data: Option<*const T>, mutex: Option, } -impl DataSetIF for OwnedDataset { - fn get_type_id(&self) -> TypeId { - self.actual_data.get_type_id() +impl DataSetIF for OwnedDataset { + fn get_type_id(&self) -> core::any::TypeId { + core::any::TypeId::of::() } - fn get_actual_data(&self) -> &dyn HasTypeId { + fn get_actual_data(&self) -> &dyn core::any::Any { // only return pointer when threading check_global_threading_available!(); &self.actual_data @@ -57,7 +44,7 @@ impl DataSetIF for OwnedDataset { } } -impl OwnedDataset { +impl OwnedDataset { pub fn new() -> OwnedDataset { OwnedDataset:: { actual_data: T::default(), @@ -90,7 +77,7 @@ impl OwnedDataset { } } -impl ReferencedDataset { +impl ReferencedDataset { pub fn new() -> ReferencedDataset { ReferencedDataset:: { actual_data: None, @@ -121,17 +108,19 @@ impl ReferencedDataset { owner_of_the_set: objectmanager::ObjectId, ) -> Result<(), ()> { let owner = object_manager.get_object(owner_of_the_set)?; - 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 type_id = core::any::TypeId::of::(); let other_set = match owner.get_set(type_id) { None => { - return Err(()); + return Err(()); //TODO panic? -> should initialize just panic if failing? } Some(set) => set, }; - //pointer cast is safe because we checked the type_id - //getting pointer to avoid lifetime check - self.actual_data = Some(other_set.get_actual_data() as *const dyn HasTypeId as *const T); + // 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()); Ok(()) } diff --git a/mission_rust/src/fsrc/store.rs b/mission_rust/src/fsrc/store.rs index 2355c72..d3d999d 100644 --- a/mission_rust/src/fsrc/store.rs +++ b/mission_rust/src/fsrc/store.rs @@ -24,15 +24,13 @@ struct StoreSlot{ } impl StoreSlot { - pub fn get_data(&self) -> &[u8] { + pub fn get_data(&self) -> &mut [u8] { check_global_threading_available!(); - unsafe{&(*self.data)} + unsafe{&mut (*self.data)} } - pub fn get_all_data(&self) -> &[u8] { + pub fn get_all_data(&self) -> &mut [u8] { check_global_threading_available!(); - unsafe{&(*self.data)} + unsafe{&mut (*self.data)} } - - } \ No newline at end of file diff --git a/mission_rust/src/lib.rs b/mission_rust/src/lib.rs index 75bbf24..65a341e 100644 --- a/mission_rust/src/lib.rs +++ b/mission_rust/src/lib.rs @@ -55,8 +55,6 @@ struct HandlerData { y: f32 } -impl datasets::HasTypeId for HandlerData {} - struct Handler { id: objectmanager::ObjectId, command_queue: queues::MessageQueue<10>, @@ -135,7 +133,7 @@ impl SystemObjectIF for Handler { } impl datasets::DatapoolOwnerIF for Handler { - fn get_set(&self, type_id: datasets::TypeId) -> Option<&dyn datasets::DataSetIF>{ + 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 {