M examples/grading-tests/professor.rs => examples/grading-tests/professor.rs +2 -11
@@ 69,21 69,12 @@ wrapped_event!(ProfessorOutputEvent, ProfessorOutputType);
async fn professor_event_handler(
mut context: ProfessorContext,
- mut event: ProfessorInputEvent,
+ event: ProfessorInputEvent,
) -> (ProfessorContext, Option<ProfessorOutputEvent>) {
- // Pull out the completion token, if there is any
- let token = event.token();
- // handle the event, adding the token back in
- let mut output = event
+ let output = event
.into_inner()
.operate(&mut context)
.map(ProfessorOutputEvent::from);
- // Reattach the token if we have one, and there is an event
- if let Some(token) = token {
- if let Some(event) = output.as_mut() {
- event.set_completion_token(token);
- }
- }
// Finish up
(context, output)
}
M examples/grading-tests/student.rs => examples/grading-tests/student.rs +2 -6
@@ 34,9 34,8 @@ wrapped_event!(StudentOutputEvent, StudentOutput);
async fn student_event_handler(
context: StudentContext,
- mut event: StudentInputEvent,
+ event: StudentInputEvent,
) -> (StudentContext, Option<StudentOutputEvent>) {
- let token = event.token();
let mut rng = nanorand::tls_rng();
let results = event
.into_inner()
@@ 46,14 45,11 @@ async fn student_event_handler(
.map(|x| -> bool { x > rng.generate_range(1_u32..=100) })
.collect::<Vec<_>>();
let name = context.name.clone();
- let mut new_event: StudentOutputEvent = StudentOutput {
+ let new_event: StudentOutputEvent = StudentOutput {
answers: Answers { answers: results },
name,
}
.into();
- if let Some(token) = token {
- new_event.set_completion_token(token);
- }
(context, Some(new_event))
}
M examples/grading-tests/university.rs => examples/grading-tests/university.rs +2 -8
@@ 2,8 2,6 @@ use std::collections::BTreeMap;
use actm::prelude::*;
-
-
// First we define the context type
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)]
@@ 30,9 28,8 @@ wrapped_event!(UniveristyInputEvent, UniversityInput);
async fn university_event_handler(
mut context: UniversityContext,
- mut event: UniveristyInputEvent,
+ event: UniveristyInputEvent,
) -> (UniversityContext, Option<UniversityOutputEvent>) {
- let token = event.token();
match event.into_inner() {
UniversityInput::Grade(student, grade) => {
let grades = context.students.entry(student).or_default();
@@ 40,10 37,7 @@ async fn university_event_handler(
(context, None)
}
UniversityInput::Get => {
- let mut event = UniversityOutputEvent::from(UniversityOutput(context.students.clone()));
- if let Some(token) = token {
- event.set_completion_token(token);
- }
+ let event = UniversityOutputEvent::from(UniversityOutput(context.students.clone()));
(context, Some(event))
}
}
M src/testing_util.rs => src/testing_util.rs +29 -55
@@ 58,33 58,22 @@ wrapped_event!(OutputEvent, Output);
// Async actor definition
#[allow(clippy::unused_async)]
-async fn async_math_event_handler(
- mut value: i64,
- mut math: MathEvent,
-) -> (i64, Option<OutputEvent>) {
- // Pull out the completion token, if there is any
- let token = math.token();
+async fn async_math_event_handler(mut value: i64, math: MathEvent) -> (i64, Option<OutputEvent>) {
// Perform the operation
let old_value = value;
let math = math.into_inner();
value = math.operate(value);
// Check to see if there was a completion token, if so, send back an Output
- if let Some(token) = token {
- // Make our output
- let output = Output {
- before: old_value,
- after: value,
- input: math,
- };
- // Wrap it up
- let mut output = OutputEvent::from(output);
- // Attach the token
- output.set_completion_token(token);
- // Send it up
- (value, Some(output))
- } else {
- (value, None)
- }
+ // Make our output
+ let output = Output {
+ before: old_value,
+ after: value,
+ input: math,
+ };
+ // Wrap it up
+ let output = OutputEvent::from(output);
+ // Send it up
+ (value, Some(output))
}
async_actor!(
@@ 97,30 86,23 @@ async_actor!(
// Sync Actor Definition
-fn math_event_handler(value: &mut i64, mut math: MathEvent) -> Option<OutputEvent> {
- // Pull out the completion token, if there is any
- let token = math.token();
+#[allow(clippy::unnecessary_wraps)]
+fn math_event_handler(value: &mut i64, math: MathEvent) -> Option<OutputEvent> {
// Perform the operation
let old_value = *value;
let math = math.into_inner();
*value = math.operate(*value);
// Check to see if there was a completion token, if so, send back an Output
- if let Some(token) = token {
- // Make our output
- let output = Output {
- before: old_value,
- after: *value,
- input: math,
- };
- // Wrap it up
- let mut output = OutputEvent::from(output);
- // Attach the token
- output.set_completion_token(token);
- // Send it up
- Some(output)
- } else {
- None
- }
+ // Make our output
+ let output = Output {
+ before: old_value,
+ after: *value,
+ input: math,
+ };
+ // Wrap it up
+ let output = OutputEvent::from(output);
+ // Send it up
+ Some(output)
}
sync_actor!(
@@ 150,11 132,7 @@ mod tests {
assert!(actor.catchup().wait().await);
// Add some numbers to our internal count
for i in 1..=10 {
- let mut event: MathEvent = MathEventType::Add(Add(i)).into();
- if i % 2 == 0 {
- // Tokenize the even events for testing the event sending behavior
- let _token = event.tokenize();
- }
+ let event: MathEvent = MathEventType::Add(Add(i)).into();
actor.inbox().accept(event).await.unwrap();
}
// Make sure we have the correct count
@@ 169,13 147,13 @@ mod tests {
// Make sure our events are as expected
let output_events = output
.stream()
- .take(6)
+ .take(11)
.map(|x| x.into_inner().input)
.collect::<Vec<_>>()
.await;
println!("Events in output: {:?}", output_events);
assert_eq!(
- [2, 4, 6, 8, 10, 0]
+ [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0]
.into_iter()
.map(|x| MathEventType::Add(Add(x)))
.collect::<Vec<_>>(),
@@ 200,11 178,7 @@ mod tests {
// Add some numbers to our internal count
for i in 1..=10 {
println!("Sending event {i}");
- let mut event: MathEvent = MathEventType::Add(Add(i)).into();
- if i % 2 == 0 {
- // Tokenize the even events for testing the event sending behavior
- let _token = event.tokenize();
- }
+ let event: MathEvent = MathEventType::Add(Add(i)).into();
actor.inbox().accept_sync(event).unwrap();
println!("Sent event {i}");
}
@@ 221,12 195,12 @@ mod tests {
// Make sure our events are as expected
let output_events = output
.iter()
- .take(6)
+ .take(11)
.map(|x| x.into_inner().input)
.collect::<Vec<_>>();
println!("Events in output: {:?}", output_events);
assert_eq!(
- [2, 4, 6, 8, 10, 0]
+ [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0]
.into_iter()
.map(|x| MathEventType::Add(Add(x)))
.collect::<Vec<_>>(),
M src/util/async_actor/newtype_macro.rs => src/util/async_actor/newtype_macro.rs +16 -1
@@ 12,7 12,22 @@ macro_rules! async_actor {
}
impl<X: Executor> $type_name<X> {
pub fn new(initial_context: $context_type, bound: Option<usize>) -> Self {
- let actor = AsyncActor::spawn_async($event_method, initial_context, bound);
+ let actor = AsyncActor::spawn_async(
+ |value: $context_type, mut event: $input_type| async move {
+ // Withdraw the completion token
+ let token = event.token();
+ let mut result = $event_method(value, event).await;
+ // slot the token back in if we have it
+ if let Some(token) = token {
+ if let Some(event) = result.1.as_mut() {
+ event.set_completion_token(token);
+ }
+ }
+ result
+ },
+ initial_context,
+ bound,
+ );
Self(actor)
}
}
M src/util/sync_actor/newtype_macro.rs => src/util/sync_actor/newtype_macro.rs +14 -1
@@ 7,7 7,20 @@ macro_rules! sync_actor {
pub struct $type_name<X: Executor>(SyncActor<$input_type, $output_type, X>);
impl<X: Executor> $type_name<X> {
pub fn new(initial_context: $context_type, bound: Option<usize>) -> Self {
- let actor = SyncActor::spawn($event_method, initial_context, bound);
+ let actor = SyncActor::spawn(
+ |value: &mut $context_type, mut event: $input_type| {
+ let token = event.token();
+ let mut result = $event_method(value, event);
+ if let Some(token) = token {
+ if let Some(event) = result.as_mut() {
+ event.set_completion_token(token);
+ }
+ }
+ result
+ },
+ initial_context,
+ bound,
+ );
Self(actor)
}
}