allow passing in task vectors now
This commit is contained in:
parent
529d2ff67d
commit
e4b5df8287
@ -1,5 +1,3 @@
|
|||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
pub enum OpResult {
|
pub enum OpResult {
|
||||||
Ok,
|
Ok,
|
||||||
}
|
}
|
||||||
@ -13,15 +11,13 @@ pub enum ExecutionType {
|
|||||||
pub trait Executable {
|
pub trait Executable {
|
||||||
type Error;
|
type Error;
|
||||||
const EXEC_TYPE: ExecutionType;
|
const EXEC_TYPE: ExecutionType;
|
||||||
const TASK_FREQ: Option<Duration>;
|
|
||||||
const TASK_NAME: &'static str;
|
const TASK_NAME: &'static str;
|
||||||
fn periodic_op(&mut self, op_code: u32) -> Result<OpResult, Self::Error>;
|
fn periodic_op(&mut self, op_code: i32) -> Result<OpResult, Self::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
trait ExecutableWithAssociatedFuncs {
|
trait ExecutableWithAssociatedFuncs {
|
||||||
type Error;
|
type Error;
|
||||||
fn exec_type(&self) -> ExecutionType;
|
fn exec_type(&self) -> ExecutionType;
|
||||||
fn task_freq(&self) -> Option<Duration>;
|
|
||||||
fn task_name(&self) -> &'static str;
|
fn task_name(&self) -> &'static str;
|
||||||
fn periodic_op(&mut self) -> Result<OpResult, Self::Error>;
|
fn periodic_op(&mut self) -> Result<OpResult, Self::Error>;
|
||||||
}
|
}
|
||||||
|
109
src/main.rs
109
src/main.rs
@ -5,7 +5,9 @@ use std::thread;
|
|||||||
use std::thread::JoinHandle;
|
use std::thread::JoinHandle;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
struct ExampleTask {}
|
struct OneShotTask {}
|
||||||
|
struct FixedCyclesTask {}
|
||||||
|
struct PeriodicTask {}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct ExampleError {
|
struct ExampleError {
|
||||||
@ -32,28 +34,63 @@ impl Error for ExampleError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Executable for ExampleTask {
|
impl Executable for OneShotTask {
|
||||||
type Error = ExampleError;
|
type Error = ExampleError;
|
||||||
const EXEC_TYPE: ExecutionType = ExecutionType::OneShot;
|
const EXEC_TYPE: ExecutionType = ExecutionType::OneShot;
|
||||||
const TASK_FREQ: Option<Duration> = Some(Duration::from_millis(500));
|
const TASK_NAME: &'static str = "One Shot Test Task";
|
||||||
const TASK_NAME: &'static str = "Test Task";
|
|
||||||
|
|
||||||
fn periodic_op(&mut self, op_code: u32) -> Result<OpResult, ExampleError> {
|
fn periodic_op(&mut self, op_code: i32) -> Result<OpResult, ExampleError> {
|
||||||
if op_code == 0 {
|
if op_code >= 0 {
|
||||||
println!("Periodic Operation OK!");
|
println!("One-shot operation with operation code {op_code} OK!");
|
||||||
Ok(OpResult::Ok)
|
Ok(OpResult::Ok)
|
||||||
} else {
|
} else {
|
||||||
println!("Periodic Operation Fail!");
|
println!("One-shot operation failure by passing op code {op_code}!");
|
||||||
|
Err(ExampleError::new("Example Task Failure"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Executable for FixedCyclesTask {
|
||||||
|
type Error = ExampleError;
|
||||||
|
const EXEC_TYPE: ExecutionType = ExecutionType::Cycles(5);
|
||||||
|
const TASK_NAME: &'static str = "Fixed Cycles Task";
|
||||||
|
|
||||||
|
fn periodic_op(&mut self, op_code: i32) -> Result<OpResult, ExampleError> {
|
||||||
|
if op_code >= 0 {
|
||||||
|
println!("Fixed-cycle operation with operation code {op_code} OK!");
|
||||||
|
Ok(OpResult::Ok)
|
||||||
|
} else {
|
||||||
|
println!("Fixed-cycle operation failure by passing op code {op_code}!");
|
||||||
|
Err(ExampleError::new("Example Task Failure"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Executable for PeriodicTask {
|
||||||
|
type Error = ExampleError;
|
||||||
|
const EXEC_TYPE: ExecutionType = ExecutionType::Cycles(5);
|
||||||
|
const TASK_NAME: &'static str = "Fixed Cycles Task";
|
||||||
|
|
||||||
|
fn periodic_op(&mut self, op_code: i32) -> Result<OpResult, ExampleError> {
|
||||||
|
if op_code >= 0 {
|
||||||
|
println!("Periodic operation with operation code {op_code} OK!");
|
||||||
|
Ok(OpResult::Ok)
|
||||||
|
} else {
|
||||||
|
println!("Periodic operation failure by passing op code {op_code}!");
|
||||||
Err(ExampleError::new("Example Task Failure"))
|
Err(ExampleError::new("Example Task Failure"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let exec_task = ExampleTask {};
|
let exec_task = OneShotTask {};
|
||||||
let jhandle = test_thread(exec_task, 0);
|
let mut task_vec = Vec::new();
|
||||||
let exec_task2 = ExampleTask {};
|
task_vec.push(exec_task);
|
||||||
let jhandle2 = test_thread(exec_task2, 1);
|
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 jhandle2 = test_thread(task_vec2, Some(Duration::from_millis(1000)), 1);
|
||||||
jhandle
|
jhandle
|
||||||
.join()
|
.join()
|
||||||
.expect("Joining thread failed")
|
.expect("Joining thread failed")
|
||||||
@ -65,26 +102,38 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn test_thread<T: Executable<Error = E> + Send + 'static, E: Error + Send + 'static>(
|
fn test_thread<T: Executable<Error = E> + Send + 'static, E: Error + Send + 'static>(
|
||||||
mut executable: T,
|
mut executable_vec: Vec<T>,
|
||||||
op_code: u32,
|
task_freq: Option<Duration>,
|
||||||
|
op_code: i32,
|
||||||
) -> JoinHandle<Result<OpResult, E>> {
|
) -> JoinHandle<Result<OpResult, E>> {
|
||||||
thread::spawn(move || match T::EXEC_TYPE {
|
let mut cycle_counts = vec![0; executable_vec.len()];
|
||||||
ExecutionType::OneShot => executable.periodic_op(op_code),
|
let mut removal_flags = vec![false; executable_vec.len()];
|
||||||
ExecutionType::Infinite => loop {
|
thread::spawn(move || loop {
|
||||||
executable.periodic_op(op_code)?;
|
for (idx, executable) in executable_vec.iter_mut().enumerate() {
|
||||||
let freq = T::TASK_FREQ
|
match T::EXEC_TYPE {
|
||||||
.unwrap_or_else(|| panic!("No task frequency specified for task {}", T::TASK_NAME));
|
ExecutionType::OneShot => {
|
||||||
thread::sleep(freq)
|
executable.periodic_op(op_code)?;
|
||||||
},
|
removal_flags[idx] = true;
|
||||||
ExecutionType::Cycles(cycles) => {
|
}
|
||||||
for _i in 0..cycles - 1 {
|
ExecutionType::Infinite => {
|
||||||
executable.periodic_op(op_code)?;
|
executable.periodic_op(op_code)?;
|
||||||
let freq = T::TASK_FREQ.unwrap_or_else(|| {
|
}
|
||||||
panic!("No task frequency specified for task {}", T::TASK_NAME)
|
ExecutionType::Cycles(cycles) => {
|
||||||
});
|
executable.periodic_op(op_code)?;
|
||||||
thread::sleep(freq)
|
cycle_counts[idx] += 1;
|
||||||
|
if cycle_counts[idx] == cycles {
|
||||||
|
removal_flags[idx] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(OpResult::Ok)
|
|
||||||
}
|
}
|
||||||
|
executable_vec.retain(|_| !*removal_flags.iter().next().unwrap());
|
||||||
|
removal_flags.retain(|&i| i == false);
|
||||||
|
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));
|
||||||
|
thread::sleep(freq);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user