-
-
Save FranklinChen/c2d519d57fd5a844aec3 to your computer and use it in GitHub Desktop.
Shared via Rust Playground
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::thread::{spawn, sleep_ms}; | |
use std::sync::mpsc::channel; | |
fn main() { | |
// Names of attendees. | |
let names = vec![format!("A"), format!("B"), format!("C"), format!("D"), format!("E")]; | |
// Create a channel to communicate between attendees and the toaster. | |
let (toaster_tx, toaster_rx) = channel(); | |
// Iterate over attendees. | |
for name in names.into_iter() { | |
// Create a channel to send a bagel down. | |
let (tx, rx) = channel(); | |
// Clone the toaster channel's transmitter (multiple sender, single receiver) | |
// so each attendee can send bagels. | |
let toaster_tx = toaster_tx.clone(); | |
// Spawn a thread for each attendee. | |
spawn(move || { | |
// Create an attendee. | |
let mut a = Attendee::new(name); | |
// Receive a bagel. | |
let bagel = rx.recv().unwrap(); | |
// Create a channel to receiver the bagel back from the toaster. | |
let (ack, rx1) = channel(); | |
// Send the bagel to the toaster along with a way to get it back. | |
toaster_tx.send((bagel, ack)).unwrap(); | |
// Receive the bagel back from the toaster. | |
let toasted_bagel = rx1.recv().unwrap(); | |
// Pick up the bagel and eat it. | |
a.pick_up_bagel(toasted_bagel); | |
a.eat_breakfast(); | |
}); | |
// Send a bagel to the attendee. | |
tx.send(Bagel::Raisin).unwrap(); | |
} | |
// Start the toaster thread. | |
spawn(move || { | |
// For each message coming from the toaster... | |
for (mut bagel, ack) in toaster_rx { | |
// We get a bagel and one end of a channel. | |
println!("Toasting {:?}", bagel); | |
// Toast the bagel. | |
bagel.toast(); | |
println!("Toasted {:?}", bagel); | |
// And send it back. | |
ack.send(bagel).unwrap(); | |
} | |
}); | |
// Give all the attendees time to toast their bagels. | |
sleep_ms(1000); | |
} | |
struct Attendee { | |
name: String, | |
breakfast: Option<Bagel>, | |
} | |
#[derive(Debug)] | |
enum Bagel { | |
Plain(BagelColour), | |
Raisin, | |
} | |
#[derive(Debug)] | |
enum BagelColour { | |
PaleBrown, | |
DarkBrown, | |
} | |
impl Attendee { | |
fn new(name: String) -> Attendee { | |
Attendee { | |
name: name, | |
breakfast: None, | |
} | |
} | |
fn pick_up_bagel(&mut self, bagel: Bagel) { | |
self.breakfast = Some(bagel); | |
} | |
fn eat_breakfast(&mut self) { | |
match self.breakfast { | |
Some(_) => { | |
self.breakfast = None; | |
println!("Yum! ({})", self.name); | |
} | |
None => println!("I don't have any breakfast :-( ({})", self.name) | |
} | |
} | |
} | |
impl Bagel { | |
fn toast(&mut self) { | |
sleep_ms(10); | |
match *self { | |
Bagel::Plain(ref mut c) => { | |
*c = BagelColour::DarkBrown; | |
} | |
_ => {} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Solution to exercise 2 at http://ncameron.org/oopsla15.html