This commit is contained in:
Robin Müller 2022-05-26 18:53:07 +02:00
parent e4b5df8287
commit be2a4ac3a2
No known key found for this signature in database
GPG Key ID: 11D4952C8CCEF814
2 changed files with 56 additions and 26 deletions

View File

@ -8,16 +8,16 @@ pub enum ExecutionType {
OneShot,
}
pub trait Executable {
pub trait Executable: Send {
type Error;
const EXEC_TYPE: ExecutionType;
const TASK_NAME: &'static str;
//const EXEC_TYPE: ExecutionType;
//const TASK_NAME: &'static str;
fn exec_type(&self) -> ExecutionType;// {
// return Self::EXEC_TYPE;
//}
fn task_name(&self) -> &'static str;//{
// return Self::TASK_NAME;
//}
fn periodic_op(&mut self, op_code: i32) -> Result<OpResult, Self::Error>;
}
trait ExecutableWithAssociatedFuncs {
type Error;
fn exec_type(&self) -> ExecutionType;
fn task_name(&self) -> &'static str;
fn periodic_op(&mut self) -> Result<OpResult, Self::Error>;
}

View File

@ -36,8 +36,14 @@ impl Error for ExampleError {
impl Executable for OneShotTask {
type Error = ExampleError;
const EXEC_TYPE: ExecutionType = ExecutionType::OneShot;
const TASK_NAME: &'static str = "One Shot Test Task";
fn exec_type(&self) -> ExecutionType {
ExecutionType::OneShot
}
fn task_name(&self) -> &'static str {
"One Shot Task"
}
fn periodic_op(&mut self, op_code: i32) -> Result<OpResult, ExampleError> {
if op_code >= 0 {
@ -52,8 +58,14 @@ impl Executable for OneShotTask {
impl Executable for FixedCyclesTask {
type Error = ExampleError;
const EXEC_TYPE: ExecutionType = ExecutionType::Cycles(5);
const TASK_NAME: &'static str = "Fixed Cycles Task";
fn exec_type(&self) -> ExecutionType {
ExecutionType::Cycles(5)
}
fn task_name(&self) -> &'static str {
"Fixed Cycles Task"
}
fn periodic_op(&mut self, op_code: i32) -> Result<OpResult, ExampleError> {
if op_code >= 0 {
@ -68,8 +80,14 @@ impl Executable for FixedCyclesTask {
impl Executable for PeriodicTask {
type Error = ExampleError;
const EXEC_TYPE: ExecutionType = ExecutionType::Cycles(5);
const TASK_NAME: &'static str = "Fixed Cycles Task";
fn exec_type(&self) -> ExecutionType {
ExecutionType::Infinite
}
fn task_name(&self) -> &'static str {
"Periodic Task"
}
fn periodic_op(&mut self, op_code: i32) -> Result<OpResult, ExampleError> {
if op_code >= 0 {
@ -82,15 +100,14 @@ impl Executable for PeriodicTask {
}
}
fn main() {
fn test0() {
let exec_task = OneShotTask {};
let mut task_vec = Vec::new();
task_vec.push(exec_task);
let task_vec = vec![Box::new(exec_task)];
let jhandle = test_thread(task_vec, Some(Duration::from_millis(500)), 0);
let exec_task2 = FixedCyclesTask {};
let mut task_vec2 = Vec::new();
task_vec2.push(exec_task2);
let task_vec2 = vec![Box::new(exec_task2)];
let jhandle2 = test_thread(task_vec2, Some(Duration::from_millis(1000)), 1);
jhandle
.join()
.expect("Joining thread failed")
@ -100,9 +117,22 @@ fn main() {
.expect("Joining thread 2 failed")
.expect("Task 2 failed");
}
fn main() {
fn test_thread<T: Executable<Error = E> + Send + 'static, E: Error + Send + 'static>(
mut executable_vec: Vec<T>,
thread::sleep(Duration::from_millis(1000));
let one_shot_in_vec = OneShotTask {};
let cycles_in_vec = FixedCyclesTask {};
let test_vec: Vec<Box<dyn Executable<Error=ExampleError>>> = vec![Box::new(one_shot_in_vec), Box::new(cycles_in_vec)];
let jhandle3 = test_thread(test_vec, Some(Duration::from_millis(500)), 3);
jhandle3
.join()
.expect("Joining thread 3 failed")
.expect("Task 3 failed");
}
fn test_thread<T: Executable<Error = E> + Send + 'static + ?Sized, E: Error + Send + 'static>(
mut executable_vec: Vec<Box<T>>,
task_freq: Option<Duration>,
op_code: i32,
) -> JoinHandle<Result<OpResult, E>> {
@ -110,7 +140,7 @@ fn test_thread<T: Executable<Error = E> + Send + 'static, E: Error + Send + 'sta
let mut removal_flags = vec![false; executable_vec.len()];
thread::spawn(move || loop {
for (idx, executable) in executable_vec.iter_mut().enumerate() {
match T::EXEC_TYPE {
match executable.exec_type() {
ExecutionType::OneShot => {
executable.periodic_op(op_code)?;
removal_flags[idx] = true;
@ -128,12 +158,12 @@ fn test_thread<T: Executable<Error = E> + Send + 'static, E: Error + Send + 'sta
}
}
executable_vec.retain(|_| !*removal_flags.iter().next().unwrap());
removal_flags.retain(|&i| i == false);
removal_flags.retain(|&i| !i);
if executable_vec.is_empty() {
return Ok(OpResult::Ok);
}
let freq = task_freq
.unwrap_or_else(|| panic!("No task frequency specified for task {}", T::TASK_NAME));
.unwrap_or_else(|| panic!("No task frequency specified"));
thread::sleep(freq);
})
}