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 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, 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_instanced(batch, 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 Renderer<R, C>, pub 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.1
}
fn access(&mut self) -> (&mut Renderer<R, C>, &O) {
(&mut self.0, &self.1)
}
}
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(self.create_renderer(), output)
}
}
impl<R: Resources, C: CommandBuffer<R>>
StreamFactory<R, C> for RenderFactory<R, C> {}