forked from ROMEO/obsw
working on datasets, stopped by "trait upcasting coercion is experimental"
This commit is contained in:
parent
efc752637e
commit
59f4a82da9
95
mission_rust/src/fsrc/datasets/mod.rs
Normal file
95
mission_rust/src/fsrc/datasets/mod.rs
Normal file
@ -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: <Self as Reflection>::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<T: Reflection + Copy> {
|
||||||
|
actual_data: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ReferencedDataset<T: Reflection + Copy> {
|
||||||
|
//we use a pointer here to avoid lifetimes
|
||||||
|
actual_data: Option<*const T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Reflection + Copy> DataSetIF for OwnedDataset<T> {
|
||||||
|
fn get_type_id(&self) -> TypeId {
|
||||||
|
self.actual_data.get_type_id()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_actual_data(&self) -> &dyn Reflection {
|
||||||
|
&self.actual_data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Reflection + Copy + Default> OwnedDataset<T> {
|
||||||
|
pub fn new() -> OwnedDataset<T> {
|
||||||
|
OwnedDataset::<T> {
|
||||||
|
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<T: Reflection + Copy + Default> ReferencedDataset<T> {
|
||||||
|
pub fn new() -> ReferencedDataset<T> {
|
||||||
|
ReferencedDataset::<T> { actual_data: None }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read(&mut self) -> Result<T, ()> {
|
||||||
|
//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(())
|
||||||
|
}
|
||||||
|
}
|
@ -2,4 +2,5 @@ pub mod sif;
|
|||||||
pub mod queues;
|
pub mod queues;
|
||||||
pub mod osal;
|
pub mod osal;
|
||||||
pub mod tasks;
|
pub mod tasks;
|
||||||
pub mod objectmanager;
|
pub mod objectmanager;
|
||||||
|
pub mod datasets;
|
@ -5,7 +5,7 @@ pub trait ObjectManager<'a> {
|
|||||||
fn get_object(&self, id: ObjectId) -> Result<&'a dyn SystemObjectIF, ()>;
|
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 get_id(&self) -> ObjectId;
|
||||||
fn initialize(&mut self, object_manager: &dyn ObjectManager) -> Result<(), ()>;
|
fn initialize(&mut self, object_manager: &dyn ObjectManager) -> Result<(), ()>;
|
||||||
fn get_command_queue(&self) -> queues::MessageQueueSender;
|
fn get_command_queue(&self) -> queues::MessageQueueSender;
|
||||||
|
@ -9,6 +9,7 @@ mod fsrc;
|
|||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
use core::panic::PanicInfo;
|
use core::panic::PanicInfo;
|
||||||
|
|
||||||
|
use fsrc::datasets::{DataSetIF, DatapoolOwnerIF};
|
||||||
use fsrc::objectmanager::SystemObjectIF;
|
use fsrc::objectmanager::SystemObjectIF;
|
||||||
use fsrc::*;
|
use fsrc::*;
|
||||||
|
|
||||||
@ -49,9 +50,18 @@ extern "C" fn rust_main() {
|
|||||||
sifln!("Mission done");
|
sifln!("Mission done");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive (Copy, Clone, Default)]
|
||||||
|
struct HandlerData {
|
||||||
|
x: u32,
|
||||||
|
y: f32
|
||||||
|
}
|
||||||
|
|
||||||
|
impl datasets::Reflection for HandlerData {}
|
||||||
|
|
||||||
struct Handler {
|
struct Handler {
|
||||||
id: objectmanager::ObjectId,
|
id: objectmanager::ObjectId,
|
||||||
command_queue: queues::MessageQueue,
|
command_queue: queues::MessageQueue,
|
||||||
|
data: datasets::OwnedDataset<HandlerData>
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HandlerSender {
|
struct HandlerSender {
|
||||||
@ -59,8 +69,10 @@ struct HandlerSender {
|
|||||||
other_handler: objectmanager::ObjectId,
|
other_handler: objectmanager::ObjectId,
|
||||||
cycle: u8,
|
cycle: u8,
|
||||||
other_handler_queue: queues::MessageQueueSender,
|
other_handler_queue: queues::MessageQueueSender,
|
||||||
|
other_data: datasets::ReferencedDataset<HandlerData>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Handler {
|
impl Handler {
|
||||||
fn handle_message(&self, message: queues::Message) {
|
fn handle_message(&self, message: queues::Message) {
|
||||||
match 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 {
|
impl SystemObjectIF for HandlerSender {
|
||||||
fn get_command_queue(&self) -> crate::fsrc::queues::MessageQueueSender {
|
fn get_command_queue(&self) -> crate::fsrc::queues::MessageQueueSender {
|
||||||
queues::MessageQueueSender::new()
|
queues::MessageQueueSender::new()
|
||||||
@ -131,11 +155,14 @@ impl SystemObjectIF for HandlerSender {
|
|||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
fn initialize(&mut self, object_manager: &dyn objectmanager::ObjectManager) -> Result<(), ()> {
|
fn initialize(&mut self, object_manager: &dyn objectmanager::ObjectManager) -> Result<(), ()> {
|
||||||
let other_handler = object_manager.get_object(self.other_handler);
|
let other_handler_maybe = object_manager.get_object(self.other_handler);
|
||||||
match other_handler {
|
let other_handler =
|
||||||
Ok(other) => self.other_handler_queue = other.get_command_queue(),
|
match other_handler_maybe {
|
||||||
|
Ok(other) => other,
|
||||||
Err(_) => return Err(()),
|
Err(_) => return Err(()),
|
||||||
}
|
};
|
||||||
|
self.other_handler_queue = other_handler.get_command_queue();
|
||||||
|
//TODO self.other_data.initialize(other_handler); // oh come on :/
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,12 +173,14 @@ fn mission() {
|
|||||||
let mut h1 = Handler {
|
let mut h1 = Handler {
|
||||||
id: 1,
|
id: 1,
|
||||||
command_queue: queues::MessageQueue::new(5),
|
command_queue: queues::MessageQueue::new(5),
|
||||||
|
data: datasets::OwnedDataset::new()
|
||||||
};
|
};
|
||||||
let mut h2 = HandlerSender {
|
let mut h2 = HandlerSender {
|
||||||
id: 2,
|
id: 2,
|
||||||
other_handler: 3,
|
other_handler: 3,
|
||||||
cycle: 0,
|
cycle: 0,
|
||||||
other_handler_queue: queues::MessageQueueSender::new(),
|
other_handler_queue: queues::MessageQueueSender::new(),
|
||||||
|
other_data: datasets::ReferencedDataset::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
let array: &mut [&mut dyn objectmanager::SystemObjectIF] = &mut [&mut h1];
|
let array: &mut [&mut dyn objectmanager::SystemObjectIF] = &mut [&mut h1];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user