Sketch out a very simple actor API

This commit is contained in:
Brian Anderson 2012-10-20 21:10:38 -07:00
parent 73ea922d6b
commit 5b0925033e
2 changed files with 110 additions and 0 deletions

View file

@ -130,6 +130,7 @@ pub mod util {
pub mod url;
pub mod vec;
pub mod range;
pub mod actor;
}
pub mod opts;

109
src/servo/util/actor.rs Normal file
View file

@ -0,0 +1,109 @@
/*!
An actor type
*/
use pipes::{Port, Chan, SharedChan, stream};
/**
The client reference to an actor
Actors are only referred to by opaque handles parameterized
over the actor's message type, which can be considered the
actor's interface.
*/
struct ActorRef<M: Send> {
chan: Chan<M>,
}
impl<M: Send> ActorRef<M> {
fn send(msg: M) {
self.chan.send(move msg);
}
}
/// The local actor interface
trait Actor<M> {
fn handle(msg: M) -> bool;
}
/// A helper function used by actor constructors
fn spawn<A: Actor<M>, M: Send>(f: ~fn() -> A) -> ActorRef<M> {
let (chan, port) = stream();
do task::spawn |move f, move port| {
let actor = f();
loop {
let msg = port.recv();
if !actor.handle(move msg) {
break;
}
}
}
return ActorRef {
chan: move chan
}
}
struct SharedActorRef<M: Send> {
chan: SharedChan<M>
}
impl<M: Send> SharedActorRef<M> {
fn send(msg: M) {
self.chan.send(move msg);
}
}
fn SharedActorRef<M: Send>(actor: ActorRef<M>) -> SharedActorRef<M> {
let chan = match move actor {
ActorRef {
chan: move chan
} => {
move chan
}
};
SharedActorRef {
chan: SharedChan(move chan)
}
}
#[cfg(test)]
mod test {
enum HelloMsg {
Exit(Chan<()>)
}
struct HelloActor {
name: ~str
}
impl HelloActor: Actor<HelloMsg> {
fn handle(msg: HelloMsg) -> bool {
match msg {
Exit(chan) => {
chan.send(());
return false;
}
}
}
}
fn HelloActor(name: ~str) -> ActorRef<HelloMsg> {
do spawn |move name| {
HelloActor {
name: copy name
}
}
}
#[test]
fn test_exit() {
let actor = HelloActor(~"bob");
let (chan, port) = stream();
actor.send(Exit(move chan));
port.recv();
}
}