use mode::{Automaton, Family, Mode};
struct ActivityFamily;
impl Family for ActivityFamily {
type Base = dyn Activity;
type Mode = Box<dyn Activity>;
}
trait Activity : Mode<Family = ActivityFamily> {
fn update(self : Box<Self>) -> Box<dyn Activity>;
}
struct Working {
pub hours_worked : u32,
}
impl Mode for Working {
type Family = ActivityFamily;
}
impl Activity for Working {
fn update(mut self : Box<Self>) -> Box<dyn Activity> {
println!("Work, work, work...");
self.hours_worked += 1;
if self.hours_worked == 4 || self.hours_worked >= 8 {
println!("Time for {}!", if self.hours_worked == 4 { "lunch" } else { "dinner" });
Box::new(Eating { hours_worked: self.hours_worked, calories_consumed: 0 })
}
else { self } }
}
struct Eating {
pub hours_worked : u32,
pub calories_consumed : u32,
}
impl Mode for Eating {
type Family = ActivityFamily;
}
impl Activity for Eating {
fn update(mut self : Box<Self>) -> Box<dyn Activity> {
println!("Yum!");
self.calories_consumed += 100;
if self.calories_consumed >= 500 {
if self.hours_worked >= 8 {
println!("Time for bed!");
Box::new(Sleeping { hours_rested: 0 })
}
else {
println!("Time to go back to work!");
Box::new(Working { hours_worked: self.hours_worked })
}
}
else { self }
}
}
struct Sleeping {
pub hours_rested : u32,
}
impl Mode for Sleeping {
type Family = ActivityFamily;
}
impl Activity for Sleeping {
fn update(mut self : Box<Self>) -> Box<dyn Activity> {
println!("ZzZzZzZz...");
self.hours_rested += 1;
if self.hours_rested >= 8 {
println!("Time for breakfast!");
Box::new(Eating { hours_worked: 0, calories_consumed: 0 })
}
else { self }
}
}
fn main() {
let mut person = ActivityFamily::automaton_with_mode(Box::new(Working { hours_worked: 0 }));
for _age in 18..100 {
Automaton::next(&mut person, |current_mode| current_mode.update());
}
}