1use std::io::prelude::*;
2use image::RgbImage;
3
4use message::*;
5
6#[derive(Debug)]
7pub struct Server<S: Read + Write> {
8 messenger: Messenger<S>,
9 dimensions: (u32, u32)
10}
11
12impl<S: Read + Write> Server<S> {
13 pub fn new(stream: S, dimensions: (u32, u32)) -> Result<Server<S>, String> {
14 let messenger = Messenger::new(stream);
15
16 match messenger.send(&Message::Dimensions(dimensions)) {
17 Err(e) => return Err(e),
18 Ok(len) => println!("sent {} bytes", len)
19 };
20
21 Ok(Server {
22 messenger,
23 dimensions
24 })
25 }
26
27 pub fn recv(&self) -> Result<RgbImage, String> {
28 let message = match self.messenger.recv() {
29 Ok(m) => m,
30 Err(e) => return Err(e)
31 };
32
33
34 match message {
35 Message::RgbImage(raw) => {
36 let (width, height) = self.dimensions;
37 match RgbImage::from_raw(width, height, raw) {
38 Some(image) => Ok(image),
39 None => Err("Couldn't deserialize RgbImage: Mismatched dimensions".to_string())
40 }
41 },
42 _ => Err("Unexpected Message, expected ImageData".to_string())
43 }
44 }
45}
46
47
48#[cfg(test)]
49mod tests {
50 use std::net::{TcpStream, TcpListener};
51 use std::time;
52 use image::Rgb;
53 use rand::random;
54
55 use super::*;
56 use client::Client;
57
58 fn server_client(dimensions: (u32, u32)) -> (Server<TcpStream>, Client<TcpStream>) {
59 let server_addr = "127.0.0.1:31415";
60 let listener = TcpListener::bind(server_addr).unwrap();
61 let client_stream = TcpStream::connect(server_addr).unwrap();
62 let (server_stream, _client_addr) = listener.accept().unwrap();
63
64 let server = Server::new(server_stream, dimensions.clone()).unwrap();
65 let client = Client::new(client_stream).unwrap();
66
67 (server, client)
68 }
69
70 #[test]
71 fn dimensions() {
72 let dimensions = (64, 32);
73 let (_server, client) = server_client(dimensions);
74 assert_eq!(dimensions, client.dimensions());
75
76 let (_server, client) = server_client(dimensions);
77 let dimensions = (65, 32);
78 assert_ne!(dimensions, client.dimensions());
79 }
80
81 #[test]
82 fn simple_image() {
83 let (width, height) = (64, 32);
84 let (server, client) = server_client((width, height));
85 let image = RgbImage::from_fn(width, height, |x, y| {
86 let (x, y) = (x as u8, y as u8);
87 if x.wrapping_mul(y) % 5 == 0 {
88 Rgb([x, y, x.wrapping_add(y)])
89 }
90 else {
91 Rgb([255u8.wrapping_sub(y), 255u8.wrapping_sub(x.wrapping_mul(y)), x.wrapping_add(y)])
92 }
93 });
94 client.send(image.clone()).unwrap();
95 let recieved_image = server.recv().unwrap();
96 assert_eq!(image.into_raw(), recieved_image.into_raw());
97 }
98
99 fn framerate(minimum: u8) {
100 let (width, height) = (64, 32);
101 let (server, client) = server_client((width, height));
102 let test_duration = time::Duration::new(2, 0);
103 let start = time::Instant::now();
104 let mut frames = 0;
105
106 let image = RgbImage::from_fn(width, height, |_, _| {
107 Rgb([random::<u8>(), random::<u8>(), random::<u8>()])
108 });
109 let image_raw = image.clone().into_raw();
110
111 while time::Instant::now() - start < test_duration {
112 let t0 = time::Instant::now();
113 for _ in 0..10 {
114 client.send(image.clone()).unwrap();
115 }
116 let t1 = time::Instant::now();
117 for _ in 0..10 {
118 let recieved_image = server.recv().unwrap();
119 assert_eq!(image_raw, recieved_image.into_raw());
120 }
121 let t2 = time::Instant::now();
122 frames += 10;
123 println!("send: {:?}", t1 - t0);
124 println!("recv: {:?}", t2 - t1);
125 println!("total : {:?}", t2 - t0);
126 println!("===============");
127 }
128
129 let rate = (frames / test_duration.as_secs()) as u8;
130 println!("Framerate: {}, minimum: {}", rate, minimum);
131 assert!(rate >= minimum);
132 }
133
134 #[test]
135 fn framerate_20() {
136 framerate(20);
137 }
138
139 #[test]
140 fn framerate_40() {
141 framerate(40);
142 }
143
144 #[test]
145 fn framerate_60() {
146 framerate(60);
147 }
148}