forked from ROMEO/obsw
this time, we won't reinvent the wheel
This commit is contained in:
@ -1,52 +1,39 @@
|
|||||||
|
use core::any::Any;
|
||||||
|
|
||||||
use crate::check_global_threading_available;
|
use crate::check_global_threading_available;
|
||||||
|
|
||||||
use super::objectmanager::SystemObjectIF;
|
use super::objectmanager::SystemObjectIF;
|
||||||
use super::{mutex, objectmanager};
|
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 {
|
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
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait DataSetIF {
|
pub trait DataSetIF {
|
||||||
fn get_type_id(&self) -> TypeId;
|
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 HasTypeId;
|
fn get_actual_data(&self) -> &dyn core::any::Any;
|
||||||
fn get_mutex(&self) -> mutex::RawMutex;
|
fn get_mutex(&self) -> mutex::RawMutex;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct OwnedDataset<T: HasTypeId + Clone> {
|
pub struct OwnedDataset<T: Clone> {
|
||||||
actual_data: T,
|
actual_data: T,
|
||||||
mutex: mutex::RawMutex,
|
mutex: mutex::RawMutex,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ReferencedDataset<T: HasTypeId + Clone> {
|
pub struct ReferencedDataset<T: Clone> {
|
||||||
//we use a pointer here to avoid lifetimes
|
//we use a pointer here to avoid lifetimes
|
||||||
actual_data: Option<*const T>,
|
actual_data: Option<*const T>,
|
||||||
mutex: Option<mutex::RawMutex>,
|
mutex: Option<mutex::RawMutex>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: HasTypeId + Clone + Default> DataSetIF for OwnedDataset<T> {
|
impl<T: Clone + Default + 'static> DataSetIF for OwnedDataset<T> {
|
||||||
fn get_type_id(&self) -> TypeId {
|
fn get_type_id(&self) -> core::any::TypeId {
|
||||||
self.actual_data.get_type_id()
|
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
|
// only return pointer when threading
|
||||||
check_global_threading_available!();
|
check_global_threading_available!();
|
||||||
&self.actual_data
|
&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> {
|
pub fn new() -> OwnedDataset<T> {
|
||||||
OwnedDataset::<T> {
|
OwnedDataset::<T> {
|
||||||
actual_data: T::default(),
|
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> {
|
pub fn new() -> ReferencedDataset<T> {
|
||||||
ReferencedDataset::<T> {
|
ReferencedDataset::<T> {
|
||||||
actual_data: None,
|
actual_data: None,
|
||||||
@ -121,17 +108,19 @@ impl<T: HasTypeId + Clone + Default> ReferencedDataset<T> {
|
|||||||
owner_of_the_set: objectmanager::ObjectId,
|
owner_of_the_set: objectmanager::ObjectId,
|
||||||
) -> Result<(), ()> {
|
) -> Result<(), ()> {
|
||||||
let owner = object_manager.get_object(owner_of_the_set)?;
|
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 = core::any::TypeId::of::<T>();
|
||||||
let type_id = temp.get_type_id();
|
|
||||||
let other_set = match owner.get_set(type_id) {
|
let other_set = match owner.get_set(type_id) {
|
||||||
None => {
|
None => {
|
||||||
return Err(());
|
return Err(()); //TODO panic? -> should initialize just panic if failing?
|
||||||
}
|
}
|
||||||
Some(set) => set,
|
Some(set) => set,
|
||||||
};
|
};
|
||||||
//pointer cast is safe because we checked the type_id
|
// let's recheck that owner.get_set did not lie about the type_id
|
||||||
//getting pointer to avoid lifetime check
|
if let Some(other_data) = other_set.get_actual_data().downcast_ref::<T>() {
|
||||||
self.actual_data = Some(other_set.get_actual_data() as *const dyn HasTypeId as *const T);
|
self.actual_data = Some(other_data);
|
||||||
|
} else {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
self.mutex = Some(other_set.get_mutex());
|
self.mutex = Some(other_set.get_mutex());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -24,15 +24,13 @@ struct StoreSlot{
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl StoreSlot {
|
impl StoreSlot {
|
||||||
pub fn get_data(&self) -> &[u8] {
|
pub fn get_data(&self) -> &mut [u8] {
|
||||||
check_global_threading_available!();
|
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!();
|
check_global_threading_available!();
|
||||||
unsafe{&(*self.data)}
|
unsafe{&mut (*self.data)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -55,8 +55,6 @@ struct HandlerData {
|
|||||||
y: f32
|
y: f32
|
||||||
}
|
}
|
||||||
|
|
||||||
impl datasets::HasTypeId for HandlerData {}
|
|
||||||
|
|
||||||
struct Handler {
|
struct Handler {
|
||||||
id: objectmanager::ObjectId,
|
id: objectmanager::ObjectId,
|
||||||
command_queue: queues::MessageQueue<10>,
|
command_queue: queues::MessageQueue<10>,
|
||||||
@ -135,7 +133,7 @@ impl SystemObjectIF for Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl datasets::DatapoolOwnerIF 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(){
|
if type_id == self.data.get_type_id(){
|
||||||
Some(&self.data)
|
Some(&self.data)
|
||||||
} else {
|
} else {
|
||||||
|
Reference in New Issue
Block a user