Skip to content
This repository has been archived by the owner on Jun 19, 2024. It is now read-only.

Commit

Permalink
feat: seperate async and sync robot traits
Browse files Browse the repository at this point in the history
  • Loading branch information
Gavin-Niederman committed Oct 22, 2023
1 parent e589833 commit 54ee3d2
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 29 deletions.
1 change: 0 additions & 1 deletion pros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ futures = { version = "0.3.28", default-features = false, features = ["alloc"] }
slab = { version = "0.4.9", default-features = false }
hashbrown = { version = "0.14.1", default-features = true }
async-trait = "0.1.73"
cfg-if = "1.0.0"
async-task = { version = "4.5.0", default-features = false }
waker-fn = "1.1.1"

Expand Down
4 changes: 2 additions & 2 deletions pros/examples/accessories.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use pros::prelude::*;
#[derive(Debug, Default)]
struct ExampleRobot;
#[async_trait]
impl Robot for ExampleRobot {
impl AsyncRobot for ExampleRobot {
async fn opcontrol(&mut self) -> pros::Result {
let handle = pros::async_runtime::spawn(async {
for _ in 0..5 {
Expand Down Expand Up @@ -54,7 +54,7 @@ impl Robot for ExampleRobot {
}
}
}
robot!(ExampleRobot);
async_robot!(ExampleRobot);

fn left_button_callback() {
println!("Left button pressed!");
Expand Down
4 changes: 2 additions & 2 deletions pros/examples/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ use pros::prelude::*;
#[derive(Default)]
pub struct Robot;
#[async_trait]
impl pros::Robot for Robot {
impl AsyncRobot for Robot {
async fn opcontrol(&mut self) -> pros::Result {
println!("basic exasmple");

Ok(())
}
}
robot!(Robot);
async_robot!(Robot);
6 changes: 3 additions & 3 deletions pros/src/async_runtime/executor.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use core::{
cell::{Cell, RefCell},
cell::RefCell,
future::Future,
pin::{pin, Pin},
pin::Pin,
sync::atomic::{AtomicBool, Ordering},
task::{Context, Poll, Waker},
task::{Context, Poll},
};

use alloc::{collections::VecDeque, sync::Arc};
Expand Down
4 changes: 2 additions & 2 deletions pros/src/async_runtime/reactor.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use core::{cell::RefCell, cmp::Reverse, task::Waker};
use core::task::Waker;

use alloc::{collections::BTreeMap, vec::Vec};
use alloc::collections::BTreeMap;

pub struct Sleepers {
sleepers: BTreeMap<u32, Waker>,
Expand Down
167 changes: 149 additions & 18 deletions pros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub type Result<T = ()> = core::result::Result<T, alloc::boxed::Box<dyn core::er

use alloc::boxed::Box;
#[async_trait::async_trait]
pub trait Robot {
pub trait AsyncRobot {
async fn opcontrol(&mut self) -> Result {
Ok(())
}
Expand All @@ -54,16 +54,83 @@ pub trait Robot {
}
}

pub trait SyncRobot {
fn opcontrol(&mut self) -> Result {
Ok(())
}
fn auto(&mut self) -> Result {
Ok(())
}
fn disabled(&mut self) -> Result {
Ok(())
}
fn comp_init(&mut self) -> Result {
Ok(())
}
}

#[doc(hidden)]
#[macro_export]
macro_rules! __gen_sync_exports {
($rbt:ty) => {
pub static mut ROBOT: Option<$rbt> = None;

#[doc(hidden)]
#[no_mangle]
extern "C" fn opcontrol() {
<$rbt as $crate::SyncRobot>::opcontrol(unsafe {
ROBOT
.as_mut()
.expect("Expected initialize to run before opcontrol")
})
.unwrap();
}

#[doc(hidden)]
#[no_mangle]
extern "C" fn autonomous() {
<$rbt as $crate::SyncRobot>::auto(unsafe {
ROBOT
.as_mut()
.expect("Expected initialize to run before opcontrol")
})
.unwrap();
}

#[doc(hidden)]
#[no_mangle]
extern "C" fn disabled() {
<$rbt as $crate::SyncRobot>::disabled(unsafe {
ROBOT
.as_mut()
.expect("Expected initialize to run before opcontrol")
})
.unwrap();
}

#[doc(hidden)]
#[no_mangle]
extern "C" fn competition_initialize() {
<$rbt as $crate::SyncRobot>::comp_init(unsafe {
ROBOT
.as_mut()
.expect("Expected initialize to run before opcontrol")
})
.unwrap();
}
};
}

#[doc(hidden)]
#[macro_export]
macro_rules! __gen_exports {
macro_rules! __gen_async_exports {
($rbt:ty) => {
pub static mut ROBOT: Option<$rbt> = None;

#[doc(hidden)]
#[no_mangle]
extern "C" fn opcontrol() {
$crate::async_runtime::block_on(<$rbt as $crate::Robot>::opcontrol(unsafe {
$crate::async_runtime::block_on(<$rbt as $crate::AsyncRobot>::opcontrol(unsafe {
ROBOT
.as_mut()
.expect("Expected initialize to run before opcontrol")
Expand All @@ -74,7 +141,7 @@ macro_rules! __gen_exports {
#[doc(hidden)]
#[no_mangle]
extern "C" fn autonomous() {
$crate::async_runtime::block_on(<$rbt as $crate::Robot>::opcontrol(unsafe {
$crate::async_runtime::block_on(<$rbt as $crate::AsyncRobot>::opcontrol(unsafe {
ROBOT
.as_mut()
.expect("Expected initialize to run before auto")
Expand All @@ -85,7 +152,7 @@ macro_rules! __gen_exports {
#[doc(hidden)]
#[no_mangle]
extern "C" fn disabled() {
$crate::async_runtime::block_on(<$rbt as $crate::Robot>::opcontrol(unsafe {
$crate::async_runtime::block_on(<$rbt as $crate::AsyncRobot>::opcontrol(unsafe {
ROBOT
.as_mut()
.expect("Expected initialize to run before disabled")
Expand All @@ -96,7 +163,7 @@ macro_rules! __gen_exports {
#[doc(hidden)]
#[no_mangle]
extern "C" fn competition_initialize() {
$crate::async_runtime::block_on(<$rbt as $crate::Robot>::opcontrol(unsafe {
$crate::async_runtime::block_on(<$rbt as $crate::AsyncRobot>::opcontrol(unsafe {
ROBOT
.as_mut()
.expect("Expected initialize to run before comp_init")
Expand All @@ -106,7 +173,71 @@ macro_rules! __gen_exports {
};
}

/// Allows your robot code to be executed by the pros kernel.
/// Allows your async robot code to be executed by the pros kernel.
/// If your robot struct implements Default then you can just supply this macro with its type.
/// If not, you can supply an expression that returns your robot type to initialize your robot struct.
///
/// Example of using the macro with a struct that implements Default:
/// ```rust
/// use pros::prelude::*;
/// #[derive(Default)]
/// struct ExampleRobot;
/// #[async_trait]
/// impl AsyncRobot for ExampleRobot {
/// asnyc fn opcontrol(&mut self) -> pros::Result {
/// println!("Hello, world!");
/// Ok(())
/// }
/// }
/// async_robot!(ExampleRobot);
/// ```
///
/// Example of using the macro with a struct that does not implement Default:
/// ```rust
/// use pros::prelude::*;
/// struct ExampleRobot {
/// x: i32,
/// }
/// #[async_trait]
/// impl AsyncRobot for ExampleRobot {
/// async fn opcontrol(&mut self) -> pros::Result {
/// println!("Hello, world! {}", self.x);
/// Ok(())
/// }
/// }
/// impl ExampleRobot {
/// pub fn new() -> Self {
/// Self { x: 5 }
/// }
/// }
/// async_robot!(ExampleRobot, ExampleRobot::new());
#[macro_export]
macro_rules! async_robot {
($rbt:ty) => {
$crate::__gen_async_exports!($rbt);

#[no_mangle]
extern "C" fn initialize() {
::pros::task::__init_main();
unsafe {
ROBOT = Some(Default::default());
}
}
};
($rbt:ty, $init:expr) => {
$crate::__gen_async_exports!($rbt);

#[no_mangle]
extern "C" fn initialize() {
::pros::task::__init_main();
unsafe {
ROBOT = Some($init);
}
}
};
}

/// Allows your sync robot code to be executed by the pros kernel.
/// If your robot struct implements Default then you can just supply this macro with its type.
/// If not, you can supply an expression that returns your robot type to initialize your robot struct.
///
Expand All @@ -115,13 +246,13 @@ macro_rules! __gen_exports {
/// use pros::prelude::*;
/// #[derive(Default)]
/// struct ExampleRobot;
/// impl Robot for ExampleRobot {
/// fn opcontrol(&mut self) -> Result {
/// impl SyncRobot for ExampleRobot {
/// asnyc fn opcontrol(&mut self) -> pros::Result {
/// println!("Hello, world!");
/// Ok(())
/// }
/// }
/// robot!(ExampleRobot);
/// sync_robot!(ExampleRobot);
/// ```
///
/// Example of using the macro with a struct that does not implement Default:
Expand All @@ -130,8 +261,8 @@ macro_rules! __gen_exports {
/// struct ExampleRobot {
/// x: i32,
/// }
/// impl Robot for ExampleRobot {
/// fn opcontrol(&mut self) -> Result {
/// impl SyncRobot for ExampleRobot {
/// async fn opcontrol(&mut self) -> pros::Result {
/// println!("Hello, world! {}", self.x);
/// Ok(())
/// }
Expand All @@ -141,11 +272,11 @@ macro_rules! __gen_exports {
/// Self { x: 5 }
/// }
/// }
/// robot!(ExampleRobot, ExampleRobot::new());
/// sync_robot!(ExampleRobot, ExampleRobot::new());
#[macro_export]
macro_rules! robot {
macro_rules! sync_robot {
($rbt:ty) => {
$crate::__gen_exports!($rbt);
$crate::__gen_sync_exports!($rbt);

#[no_mangle]
extern "C" fn initialize() {
Expand All @@ -156,7 +287,7 @@ macro_rules! robot {
}
};
($rbt:ty, $init:expr) => {
$crate::__gen_exports!($rbt);
$crate::__gen_sync_exports!($rbt);

#[no_mangle]
extern "C" fn initialize() {
Expand All @@ -169,8 +300,8 @@ macro_rules! robot {
}

pub mod prelude {
pub use crate::robot;
pub use crate::Robot;
pub use crate::{ async_robot, sync_robot };
pub use crate::{ AsyncRobot, SyncRobot };

// Import Box from alloc so that it can be used in async_trait!
pub use crate::{async_trait, os_task_local, print, println};
Expand Down
1 change: 0 additions & 1 deletion pros/src/task.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use core::{cell::RefCell, future::Future, hash::Hash, panic, ptr::NonNull, task::Poll};

use alloc::boxed::Box;
use cfg_if::cfg_if;
use hashbrown::HashMap;
use slab::Slab;
use snafu::Snafu;
Expand Down

0 comments on commit 54ee3d2

Please sign in to comment.