1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use std::io;
use mio::EventLoop;
use mio::util::Slab;
use void::{Void, unreachable};
use config::{create_slab, create_loop};
use handler::{Handler, create_handler, set_timeout_opt};
use scope::{early_scope, EarlyScope, scope, Scope};
use {Machine, Config, SpawnError, Timeout, Time, Response};
use SpawnError::NoSlabSpace;
use response::decompose;
pub struct LoopCreator<M: Machine> {
slab: Slab<(Option<(Timeout, Time)>, M)>,
mio: EventLoop<Handler<M>>,
}
pub struct LoopInstance<M: Machine> {
mio: EventLoop<Handler<M>>,
handler: Handler<M>,
}
impl<M: Machine> LoopCreator<M> {
pub fn new(cfg: &Config) -> Result<LoopCreator<M>, io::Error> {
let slab = create_slab(&cfg);
let eloop = try!(create_loop(&cfg));
Ok(LoopCreator {
slab: slab,
mio: eloop,
})
}
pub fn add_machine_with<F>(&mut self, fun: F) -> Result<(), SpawnError<()>>
where F: FnOnce(&mut EarlyScope) -> Response<M, Void>
{
let ref mut chan = self.mio.channel();
let ref mut mio = self.mio;
let res = self.slab.insert_with(|token| {
let ref mut scope = early_scope(token, chan, mio);
let (mach, void, timeout) = decompose(token, fun(scope));
void.map(|x| unreachable(x));
let m = mach.expect("You can't return Response::done() \
from Machine::create() until new release of slab crate. \
(requires insert_with_opt)");
let to = set_timeout_opt(timeout, scope);
(to, m)
});
if res.is_some() {
Ok(())
} else {
Err(NoSlabSpace(()))
}
}
pub fn instantiate(self, context: M::Context) -> LoopInstance<M> {
let LoopCreator { slab, mio } = self;
let handler = create_handler(slab, context, mio.channel());
LoopInstance { mio: mio, handler: handler }
}
pub fn run(self, context: M::Context) -> Result<(), io::Error> {
self.instantiate(context).run()
}
}
impl<M: Machine> LoopInstance<M> {
pub fn add_machine_with<F>(&mut self, fun: F) -> Result<(), SpawnError<()>>
where F: FnOnce(&mut Scope<M::Context>) -> Response<M, Void>
{
self.handler.add_machine_with(&mut self.mio, fun)
}
pub fn run(mut self) -> Result<(), io::Error> {
let ref mut handler = self.handler;
let ref mut mio = self.mio;
mio.run(handler)
}
}