use device::{Device, InstanceCount, Resources, VertexCount};
use device::draw::CommandBuffer;
use device::target::{ClearData, Mask, Mirror, Rect};
use render::{DrawError, Renderer, RenderFactory};
use render::batch::Batch;
use render::target::Output;
pub trait Window<R: Resources>: Output<R> {
fn swap_buffers(&mut self);
}
pub trait Stream<R: Resources> {
type CommandBuffer: CommandBuffer<R>;
type Output: Output<R>;
fn get_output(&self) -> &Self::Output;
fn access(&mut self) -> (&mut Renderer<R, Self::CommandBuffer>, &Self::Output);
fn get_aspect_ratio(&self) -> f32 {
let (w, h) = self.get_output().get_size();
w as f32 / h as f32
}
fn clear(&mut self, data: ClearData) {
let (ren, out) = self.access();
let mask = out.get_mask();
ren.clear(data, mask, out);
}
fn blit_on<I: Output<R>>(&mut self,
source: &I, source_rect: Rect, dest_rect: Rect,
mirror: Mirror, mask: Mask) {
let (ren, out) = self.access();
ren.blit(source, source_rect, out, dest_rect, mirror, mask);
}
fn blit_to<O: Output<R>>(&mut self,
destination: &O, dest_rect: Rect, source_rect: Rect,
mirror: Mirror, mask: Mask) {
let (ren, out) = self.access();
ren.blit(out, source_rect, destination, dest_rect, mirror, mask);
}
fn draw<B: Batch<R>>(&mut self, batch: &B)
-> Result<(), DrawError<B::Error>> {
let (ren, out) = self.access();
ren.draw(batch, None, out)
}
fn draw_instanced<B: Batch<R>>(&mut self, batch: &B,
count: InstanceCount, base: VertexCount)
-> Result<(), DrawError<B::Error>> {
let (ren, out) = self.access();
ren.draw(batch, Some((count, base)), out)
}
fn flush<D>(&mut self, device: &mut D) where
D: Device<Resources = R, CommandBuffer = Self::CommandBuffer>,
{
let (ren, _) = self.access();
device.submit(ren.as_buffer());
ren.reset();
}
}
impl<'a, R: Resources, C: CommandBuffer<R>, O: Output<R>>
Stream<R> for (&'a mut Renderer<R, C>, &'a O) {
type CommandBuffer = C;
type Output = O;
fn get_output(&self) -> &O {
&self.1
}
fn access(&mut self) -> (&mut Renderer<R, C>, &O) {
(&mut self.0, &self.1)
}
}
pub struct OwnedStream<
R: Resources,
C: CommandBuffer<R>,
O: Output<R>,
>{
pub ren: Renderer<R, C>,
pub out: O,
}
impl<R: Resources, C: CommandBuffer<R>, O: Output<R>>
Stream<R> for OwnedStream<R, C, O> {
type CommandBuffer = C;
type Output = O;
fn get_output(&self) -> &O {
&self.out
}
fn access(&mut self) -> (&mut Renderer<R, C>, &O) {
(&mut self.ren, &self.out)
}
}
impl<D: Device, W: Window<D::Resources>> OwnedStream<D::Resources, D::CommandBuffer, W> {
pub fn present(&mut self, device: &mut D) {
self.flush(device);
self.out.swap_buffers();
device.cleanup();
}
}
pub trait StreamFactory<R: Resources, C: CommandBuffer<R>>: RenderFactory<R, C> {
fn create_stream<O: Output<R>>(&mut self, output: O) -> OwnedStream<R, C, O> {
OwnedStream {
ren: self.create_renderer(),
out: output,
}
}
}
impl<R: Resources, C: CommandBuffer<R>, F: RenderFactory<R, C>>
StreamFactory<R, C> for F {}