Dirty push

This commit is contained in:
Tim Visée
2017-12-30 12:45:22 +01:00
parent 4a28e20d2a
commit 00af76a472
3 changed files with 709 additions and 5 deletions

View File

@@ -6,6 +6,8 @@ use std::io::Error;
use std::io::prelude::*;
use std::net::TcpStream;
use std::path::Path;
use std::sync::mpsc;
use std::sync::mpsc::{Sender, Receiver};
use std::thread;
use std::thread::JoinHandle;
use std::time::Duration;
@@ -192,6 +194,7 @@ struct PixCanvas {
host: String,
painter_count: usize,
painters: Vec<JoinHandle<u32>>,
painter_handles: Vec<PainterHandle>,
image: DynamicImage,
size: (u32, u32),
offset: (u32, u32),
@@ -214,6 +217,7 @@ impl PixCanvas {
host: host.to_string(),
painter_count,
painters: Vec::with_capacity(painter_count),
painter_handles: Vec::with_capacity(painter_count),
image,
size,
offset,
@@ -259,12 +263,15 @@ impl PixCanvas {
area.x,
area.y,
area.w,
area.h
area.h,
);
// Redefine the offset to make it usable in the thread
let offset = (self.offset.0, self.offset.1);
// Create a channel to push new images
let (tx, rx): (Sender<DynamicImage>, Receiver<DynamicImage>) = mpsc::channel();
// Create the painter thread
let thread = thread::spawn(move || {
// Create a new stream
@@ -279,12 +286,69 @@ impl PixCanvas {
// Do some work
loop {
painter.work().expect("Painter failed to perform work");
// Work
painter.work()
.expect("Painter failed to perform work");
// Update the image to paint
if let Ok(image) = rx.try_recv() {
painter.set_image(image);
}
}
});
// Add the painter thread to the list
self.painters.push(thread);
// Create a new painter handle, pust it to the list
self.painter_handles.push(
PainterHandle::new(
thread,
area,
tx,
)
);
}
// Update the image that is being rendered for all painters.
pub fn update_image(&self, image: DynamicImage) {
// Update the image for each specific painter handle
for handle in self.painter_handles {
handle.update_image(&image);
}
}
}
/// A handle for a painter thread.
struct PainterHandle {
thread: JoinHandle<u32>,
area: Rect,
image_sender: Sender<DynamicImage>,
}
impl PainterHandle {
/// Create a new handle from the given properties.
pub fn new(thread: JoinHandle<u32>, area: Rect, image_sender: Sender<DynamicImage>) -> PainterHandle {
PainterHandle {
thread,
area,
image_sender,
}
}
/// Push an image update.
pub fn update_image(&self, full_image: &mut DynamicImage) {
// Crop the image to the area
let image = full_image.crop(
self.area.x,
self.area.y,
self.area.w,
self.area.h,
);
// Push a new image to the thread
// TODO: return this result
self.image_sender.send(image)
.expect("Failed to send image update to painter");
}
}
@@ -342,6 +406,11 @@ impl Painter {
// Everything seems to be ok
Ok(())
}
/// Update the image that should be painted
pub fn set_image(&mut self, image: DynamicImage) {
self.image = image;
}
}
@@ -436,6 +505,7 @@ impl Color {
/// Rectangle struct.
#[derive(Copy, Clone)]
pub struct Rect {
// TODO: Make these properties private
pub x: u32,