use gfx;
use std::sync::mpsc;

#[derive(Debug)]
pub struct EncoderQueue<D: gfx::Device> {
  pub sender: mpsc::Sender<gfx::Encoder<D::Resources, D::CommandBuffer>>,
  pub receiver: mpsc::Receiver<gfx::Encoder<D::Resources, D::CommandBuffer>>,
}

pub struct DeviceRenderer<D: gfx::Device> {
  queue: EncoderQueue<D>,
}

impl<D: gfx::Device> DeviceRenderer<D> {
  pub fn new(buffers: Vec<D::CommandBuffer>) -> (DeviceRenderer<D>, EncoderQueue<D>) {
    let (a_send, b_recv) = mpsc::channel();
    let (b_send, a_recv) = mpsc::channel();

    for cb in buffers {
      let encoder = gfx::Encoder::from(cb);
      a_send
        .send(encoder)
        .expect("command buffers send failed");
    }

    (DeviceRenderer {
      queue: EncoderQueue {
        sender: a_send,
        receiver: a_recv,
      },
    },
     EncoderQueue {
       sender: b_send,
       receiver: b_recv,
     })
  }

  pub fn draw(&mut self, device: &mut D) {
    match self.queue.receiver.recv() {
      Ok(mut encoder) => {
        encoder.flush(device);
        match self.queue.sender.send(encoder) {
          Ok(_) => {}
          Err(e) => {
            panic!("Unable to send {}", e);
          }
        }
      }
      Err(e) => {
        panic!("Unable to receive {}", e);
      }
    }
  }
}

use gfx;
use std::sync::mpsc;

#[derive(Debug)]
pub struct EncoderQueue<D: gfx::Device> {
  pub sender: mpsc::Sender<gfx::Encoder<D::Resources, D::CommandBuffer>>,
  pub receiver: mpsc::Receiver<gfx::Encoder<D::Resources, D::CommandBuffer>>,
}

pub struct DeviceRenderer<D: gfx::Device> {
  queue: EncoderQueue<D>,
}

impl<D: gfx::Device> DeviceRenderer<D> {
  pub fn new(buffers: Vec<D::CommandBuffer>) -> (DeviceRenderer<D>, EncoderQueue<D>) {
    let (a_send, b_recv) = mpsc::channel();
    let (b_send, a_recv) = mpsc::channel();

    for cb in buffers {
      let encoder = gfx::Encoder::from(cb);
      a_send
        .send(encoder)
        .expect("command buffers send failed");
    }

    (DeviceRenderer {
      queue: EncoderQueue {
        sender: a_send,
        receiver: a_recv,
      },
    },
     EncoderQueue {
       sender: b_send,
       receiver: b_recv,
     })
  }

  pub fn draw(&mut self, device: &mut D) {
    let _ = self.queue.receiver.recv()
                .map(|mut encoder| {
                  encoder.flush(device);
                  let _ = self.queue.sender
                              .send(encoder)
                              .map_err(|e| {
                                panic!("Unable to send {}", e)
                              });
                })
                .map_err(|e| {
                  panic!("Unable to receive {}", e);
                });
  }
}

Refactor "draw" function to use function combinators
Refactor "draw" function to use function combinators