this time, we won't reinvent the wheel

This commit is contained in:
Ulrich Mohr 2024-02-03 00:03:49 +01:00
parent 3155243ae9
commit 4460e470b2
3 changed files with 26 additions and 41 deletions

View File

@ -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<T: HasTypeId + Clone> {
pub struct OwnedDataset<T: Clone> {
actual_data: T,
mutex: mutex::RawMutex,
}
pub struct ReferencedDataset<T: HasTypeId + Clone> {
pub struct ReferencedDataset<T: Clone> {
//we use a pointer here to avoid lifetimes
actual_data: Option<*const T>,
mutex: Option<mutex::RawMutex>,
}
impl<T: HasTypeId + Clone + Default> DataSetIF for OwnedDataset<T> {
fn get_type_id(&self) -> TypeId {
self.actual_data.get_type_id()
impl<T: Clone + Default + 'static> DataSetIF for OwnedDataset<T> {
fn get_type_id(&self) -> core::any::TypeId {
core::any::TypeId::of::<T>()
}
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<T: HasTypeId + Clone + Default> DataSetIF for OwnedDataset<T> {
}
}
impl<T: HasTypeId + Clone + Default> OwnedDataset<T> {
impl<T: Clone + Default> OwnedDataset<T> {
pub fn new() -> OwnedDataset<T> {
OwnedDataset::<T> {
actual_data: T::default(),
@ -90,7 +77,7 @@ impl<T: HasTypeId + Clone + Default> OwnedDataset<T> {
}
}
impl<T: HasTypeId + Clone + Default> ReferencedDataset<T> {
impl<T: Clone + Default + 'static> ReferencedDataset<T> {
pub fn new() -> ReferencedDataset<T> {
ReferencedDataset::<T> {
actual_data: None,
@ -121,17 +108,19 @@ impl<T: HasTypeId + Clone + Default> ReferencedDataset<T> {
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::<T>();
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::<T>() {
self.actual_data = Some(other_data);
} else {
return Err(());
}
self.mutex = Some(other_set.get_mutex());
Ok(())
}

View File

@ -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)}
}
}

View File

@ -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 {