~saiko/game

f8119d8638b8789c1fa0adfb2b7f0a9609e6804b — 2xsaiko 1 year, 14 days ago 714607e
UI progress
M src/testui.rs => src/testui.rs +27 -38
@@ 1,30 1,14 @@
use crate::ui::panel::Container;
use crate::ui::element::Button;
use crate::ui::layout::{LayoutManager, BorderLayout};
use crate::ui::controller::UiController;
use crate::ui::graphics::Graphics;
use crate::ui::panel::Container;

pub struct TestUi {
  elements: TestUiElements,
  controller: TestUiController,
}

impl TestUi {
  fn new(controller: TestUiController) -> Self {
    let elements = controller.create_elements();
    TestUi { elements, controller }
  }
}

impl Ui for TestUi {
  fn update(&mut self) {
    unimplemented!()
  }

  fn draw(&mut self, g: &mut Graphics) {
    unimplemented!()
  }
use crate::ui::rescap::ResizeCapabilities;

  fn resize(&mut self, width: u32, height: u32) {
    unimplemented!()
ui_def! {
  impl TestUi, TestUiElements, TestUiController, TestUiAccess {
    Button => button,
    Button1 => button1,
  }
}



@@ 35,6 19,19 @@ struct TestUiElements {

struct TestUiController;

impl TestUiController {
  fn get_layout(&self) -> impl LayoutManager<TestUiElements> {
    use TestUiAccess::*;
    BorderLayout::of(
      Button,
      Button,
      Button,
      Button,
      Button1,
    )
  }
}

impl UiController for TestUiController {
  type Elements = TestUiElements;



@@ 46,20 43,12 @@ impl UiController for TestUiController {
  }

  fn update(&mut self, elements: &mut TestUiElements) {}
}

pub trait UiController {
  type Elements;

  fn create_elements(&self) -> Self::Elements;

  fn update(&mut self, elements: &mut Self::Elements);
}

pub trait Ui {
  fn update(&mut self);

  fn draw(&mut self, g: &mut Graphics);
  fn resize(&mut self, elements: &mut Self::Elements, g: &Graphics, width: u32, height: u32) {
    self.get_layout().relayout(elements, g, width, height);
  }

  fn resize(&mut self, width: u32, height: u32);
  fn get_resize_capabilities(&self, elements: &Self::Elements, g: &Graphics) -> ResizeCapabilities {
    self.get_layout().get_resize_capabilities(elements, g)
  }
}

M src/ui/access.rs => src/ui/access.rs +4 -55
@@ 1,57 1,6 @@
use crate::ui::panel::ContainerAny;
use crate::ui::element::Positionable;

#[macro_export]
macro_rules! ui_def {
    (impl for $ui_struct:ty as $ui_access:ident {
      $($variant:ident => $field:ident),* $(,)?
    }) => {
      #[derive(Copy, Clone, Eq, PartialEq, Debug)]
      pub enum $ui_access {
        $($variant),*
      }

      impl $crate::ui::access::Values for $ui_access {
        fn values() -> &'static [Self] {
          &[$(Self::$variant),*]
        }
      }

      impl $crate::ui::access::UiAccess for $ui_struct {
        type Access = $ui_access;

        fn by_name(name: &str) -> Option<Self::Access> {
          match name {
            $(stringify!($field) => Some(Self::Access::$variant),)+
            _ => None
          }
        }

        fn get_element(&self, ident: Self::Access) -> &dyn $crate::ui::panel::ContainerAny {
          match ident {
            $(Self::Access::$variant => &self.$field,)+
          }
        }

        fn get_element_mut(&mut self, ident: Self::Access) -> &mut dyn $crate::ui::panel::ContainerAny {
          match ident {
            $(Self::Access::$variant => &mut self.$field,)+
          }
        }
      }

      impl $crate::ui::layout::LayoutManager<$ui_struct> for $ui_access {
        fn relayout_at(&self, ui: &mut $ui_struct, g: &crate::ui::graphics::Graphics, x: i32, y: i32, width: u32, height: u32) {
          $crate::ui::access::UiAccess::get_element_mut(ui, *self).set_dimensions(x, y, width, height)
        }

        fn get_resize_capabilities(&self, ui: & $ui_struct, g: & $crate::ui::graphics::Graphics) -> $crate::ui::rescap::ResizeCapabilities {
          $crate::ui::access::UiAccess::get_element(ui, *self).drawable().get_resize_capabilities(g)
        }
      }
    };
}

pub trait Values {
pub trait Values: Sized + Copy {
  fn values() -> &'static [Self];
}



@@ 60,7 9,7 @@ pub trait UiAccess {

  fn by_name(name: &str) -> Option<Self::Access>;

  fn get_element(&self, access: Self::Access) -> &dyn ContainerAny;
  fn get_element(&self, access: Self::Access) -> &dyn Positionable;

  fn get_element_mut(&mut self, access: Self::Access) -> &mut dyn ContainerAny;
  fn get_element_mut(&mut self, access: Self::Access) -> &mut dyn Positionable;
}

A src/ui/controller.rs => src/ui/controller.rs +30 -0
@@ 0,0 1,30 @@
use crate::ui::access::UiAccess;
use crate::ui::graphics::Graphics;
use crate::ui::rescap::ResizeCapabilities;

pub trait UiController {
  type Elements: UiAccess + 'static;

  fn create_elements(&self) -> Self::Elements;

  fn update(&mut self, elements: &mut Self::Elements);

  fn resize(&mut self, elements: &mut Self::Elements, g: &Graphics, width: u32, height: u32);

  fn get_resize_capabilities(&self, elements: &Self::Elements, g: &Graphics) -> ResizeCapabilities;

  fn draw(&mut self, elements: &mut Self::Elements, g: &mut Graphics) {
    use crate::ui::access::Values;

    let all = <Self::Elements as UiAccess>::Access::values();
    for el in all {
      elements.get_element_mut(*el).draw(g);
    }
  }

  fn click(&mut self, x: i32, y: i32) -> bool { true }

  fn open(&mut self) {}

  fn close(&mut self) {}
}

M src/ui/element/button.rs => src/ui/element/button.rs +10 -9
@@ 11,8 11,8 @@ pub enum ButtonEvent {

pub struct Button {
  text: String,
  width: i32,
  height: i32,
  width: u32,
  height: u32,
  queue: EventQueue<ButtonEvent>,
}



@@ 33,8 33,9 @@ impl Button {

impl Element for Button {
  fn draw(&mut self, g: &mut Graphics) {
    g.draw_rect(1, 1, self.width - 2, self.height - 2, Color::from_packed_rgb(0x00ccff));
    g.draw_string(&self.text, self.width / 2, self.height / 2 - (g.font_renderer().get_height() / 2.0) as i32, StringDrawProps::default().with_alignment(Alignment::Center).with_color(Color::from_packed_rgb(0x7f7f7f)));
    g.draw_rect(1, 1, self.width as i32 - 2, self.height as i32 - 2, Color::from_packed_rgb(0x00ccff));
    g.draw_string(&self.text, self.width as i32 / 2, self.height as i32 / 2 - (g.font_renderer().get_height() / 2.0) as i32,
                  StringDrawProps::default().with_alignment(Alignment::Center).with_color(Color::from_packed_rgb(0x7f7f7f)));
  }

  fn get_resize_capabilities(&self, g: &Graphics) -> ResizeCapabilities {


@@ 49,13 50,13 @@ impl Element for Button {
    )
  }

  fn resize(&mut self, width: u32, height: u32) {
    self.width = width as i32;
    self.height = height as i32;
  }

  fn click(&mut self, mouse_x: i32, mouse_y: i32) -> bool {
    self.queue.push(ButtonEvent::Pressed);
    true
  }

  fn set_size(&mut self, width: u32, height: u32) {
    self.width = width;
    self.height = height;
  }
}
\ No newline at end of file

M src/ui/element/mod.rs => src/ui/element/mod.rs +20 -44
@@ 1,70 1,46 @@
use std::ops::DerefMut;

pub use button::*;
pub use spacer::*;
pub use viewport::*;

use crate::ui::graphics::Graphics;
use crate::ui::rescap::ResizeCapabilities;
use crate::ui::UiController;

mod button;
mod spacer;
mod viewport;

pub trait Element {
  fn draw(&mut self, g: &mut Graphics);
  fn update(&mut self) {}

  fn get_resize_capabilities(&self, g: &Graphics) -> ResizeCapabilities;
  fn draw(&mut self, g: &mut Graphics);

  /// Resize this drawable. Behavior is undefined if dimensions are out of range.
  fn resize(&mut self, width: u32, height: u32);
  fn set_size(&mut self, width: u32, height: u32);

  fn click(&mut self, mouse_x: i32, mouse_y: i32) -> bool { true }
}

impl Element for () {
  fn draw(&mut self, g: &mut Graphics) {}

  fn get_resize_capabilities(&self, g: &Graphics) -> ResizeCapabilities {
    ResizeCapabilities::zero_size()
  }

  fn resize(&mut self, width: u32, height: u32) {}
  fn get_resize_capabilities(&self, g: &Graphics) -> ResizeCapabilities;
}

impl Element for &mut dyn Element {
  fn draw(&mut self, g: &mut Graphics) {
    self.draw(g);
  }

  fn get_resize_capabilities(&self, g: &Graphics) -> ResizeCapabilities {
    self.get_resize_capabilities(g)
  }
pub trait Positionable: Element {
  fn x(&self) -> i32;

  fn resize(&mut self, width: u32, height: u32) {
    self.resize(width, height);
  }

  fn click(&mut self, mouse_x: i32, mouse_y: i32) -> bool {
    self.click(mouse_x, mouse_y)
  }
}
  fn y(&self) -> i32;

impl Element for Box<dyn Element> {
  fn draw(&mut self, g: &mut Graphics) {
    (**self).draw(g);
  }
  fn width(&self) -> u32;

  fn get_resize_capabilities(&self, g: &Graphics) -> ResizeCapabilities {
    (**self).get_resize_capabilities(g)
  }
  fn height(&self) -> u32;

  fn resize(&mut self, width: u32, height: u32) {
    (**self).resize(width, height);
  }
  fn set_position(&mut self, x: i32, y: i32);

  fn click(&mut self, mouse_x: i32, mouse_y: i32) -> bool {
    (**self).click(mouse_x, mouse_y)
  fn set_dimensions(&mut self, x: i32, y: i32, width: u32, height: u32) {
    self.set_position(x, y);
    self.set_size(width, height);
  }
}

pub fn draw_at_pos<T: Positionable>(el: &mut T, g: &mut Graphics) {
  g.push_matrix(|g| {
    g.translatei(el.x(), el.y(), -1);
    el.draw(g);
  });
}
\ No newline at end of file

M src/ui/element/spacer.rs => src/ui/element/spacer.rs +2 -2
@@ 7,9 7,9 @@ pub struct Spacer;
impl Element for Spacer {
  fn draw(&mut self, g: &mut Graphics) {}

  fn set_size(&mut self, width: u32, height: u32) {}

  fn get_resize_capabilities(&self, g: &Graphics) -> ResizeCapabilities {
    ResizeCapabilities::default()
  }

  fn resize(&mut self, width: u32, height: u32) {}
}
\ No newline at end of file

M src/ui/element/viewport.rs => src/ui/element/viewport.rs +1 -1
@@ 63,7 63,7 @@ impl Element for Viewport {
    }
  }

  fn resize(&mut self, width: u32, height: u32) {
  fn set_size(&mut self, width: u32, height: u32) {
    self.width = width;
    self.height = height;
    self.fb = None;

A src/ui/host.rs => src/ui/host.rs +48 -0
@@ 0,0 1,48 @@
use crate::ui::element::Element;
use crate::ui::graphics::Graphics;

pub struct UiHost {
  current_controller: Option<Box<dyn Element>>,
  width: u32,
  height: u32,
}

impl UiHost {
  pub fn new() -> Self {
    UiHost {
      current_controller: None,
      width: 0,
      height: 0,
    }
  }

  pub fn close_ui(&mut self) -> Option<Box<dyn Element>> {
    let mut r = self.current_controller.take();
    // if let Some(ref mut r) = r {
    //   r.close();
    // }
    r
  }

  pub fn open_ui(&mut self, mut element: impl Element + 'static) -> Option<Box<dyn Element>> {
    let r = self.close_ui();
    // element.open();
    element.set_size(self.width, self.height);
    self.current_controller = Some(box element);
    r
  }

  pub fn resize(&mut self, width: u32, height: u32) {
    self.width = width;
    self.height = height;
    if let Some(ref mut c) = self.current_controller {
      c.set_size(self.width, self.height);
    }
  }

  pub fn draw(&mut self, g: &mut Graphics) {
    if let Some(ref mut c) = self.current_controller {
      c.draw(g)
    }
  }
}
\ No newline at end of file

M src/ui/layout/border.rs => src/ui/layout/border.rs +4 -4
@@ 1,11 1,11 @@
use std::cmp::max;
use std::marker::PhantomData;

use crate::ui::element::Element;
use crate::ui::graphics::Graphics;
use crate::ui::layout::LayoutManager;
use crate::ui::layout::util::layout_stack;
use crate::ui::rescap::ResizeCapabilities;
use crate::ui::access::UiAccess;

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Position {


@@ 30,7 30,7 @@ pub enum Position {
/// |                 Bottom                 |
/// +----------------------------------------+
/// ```
pub struct BorderLayout<X, T, B, L, R, C>
pub struct BorderLayout<X: UiAccess, T, B, L, R, C>
  where T: LayoutManager<X>, B: LayoutManager<X>, L: LayoutManager<X>, R: LayoutManager<X>, C: LayoutManager<X>
{
  top: T,


@@ 41,7 41,7 @@ pub struct BorderLayout<X, T, B, L, R, C>
  _phantom_data: PhantomData<X>,
}

impl<X, T, B, L, R, C> BorderLayout<X, T, B, L, R, C>
impl<X: UiAccess, T, B, L, R, C> BorderLayout<X, T, B, L, R, C>
  where T: LayoutManager<X>, B: LayoutManager<X>, L: LayoutManager<X>, R: LayoutManager<X>, C: LayoutManager<X>
{
  pub fn of(top: T, bottom: B, left: L, right: R, center: C) -> Self {


@@ 56,7 56,7 @@ impl<X, T, B, L, R, C> BorderLayout<X, T, B, L, R, C>
  }
}

impl<X, T, B, L, R, C> LayoutManager<X> for BorderLayout<X, T, B, L, R, C>
impl<X: UiAccess, T, B, L, R, C> LayoutManager<X> for BorderLayout<X, T, B, L, R, C>
  where T: LayoutManager<X>, B: LayoutManager<X>, L: LayoutManager<X>, R: LayoutManager<X>, C: LayoutManager<X>
{
  fn relayout_at(&self, ui: &mut X, g: &Graphics, x: i32, y: i32, width: u32, height: u32) {

M src/ui/layout/mod.rs => src/ui/layout/mod.rs +3 -2
@@ 4,13 4,14 @@ pub use stack::*;

use crate::ui::graphics::Graphics;
use crate::ui::rescap::ResizeCapabilities;
use crate::ui::access::UiAccess;

mod border;
mod grid;
mod stack;
mod util;

pub trait LayoutManager<T> {
pub trait LayoutManager<T: UiAccess> {
  fn relayout(&self, ui: &mut T, g: &Graphics, width: u32, height: u32) {
    self.relayout_at(ui, g, 0, 0, width, height);
  }


@@ 20,7 21,7 @@ pub trait LayoutManager<T> {
  fn get_resize_capabilities(&self, ui: &T, g: &Graphics) -> ResizeCapabilities;
}

impl<T> LayoutManager<T> for () {
impl<T: UiAccess> LayoutManager<T> for () {
  fn relayout_at(&self, ui: &mut T, g: &Graphics, x: i32, y: i32, width: u32, height: u32) {}

  fn get_resize_capabilities(&self, ui: &T, g: &Graphics) -> ResizeCapabilities {

M src/ui/mod.rs => src/ui/mod.rs +83 -54
@@ 1,8 1,9 @@
use crate::ui::access::UiAccess;
use crate::ui::controller::UiController;
use crate::ui::element::Element;
use crate::ui::graphics::Graphics;
use crate::ui::rescap::ResizeCapabilities;

#[macro_use]
pub mod access;
pub mod console;
pub mod layout;


@@ 11,87 12,115 @@ pub mod panel;
pub mod rescap;
pub mod graphics;
pub mod event;
pub mod host;
pub mod controller;

pub trait UiController {
  fn update(&mut self);
#[macro_export]
macro_rules! ui_def {
  (impl $ui_struct:ident, $el_struct:ty, $ctrl_struct:ty, $acc_struct:ident {
      $($variant:ident => $field:ident),* $(,)?
    }) => {
      _ui_def_inner!(
        $ui_struct,
        $el_struct,
        $ctrl_struct,
        $acc_struct,
        $($variant => $field),*
      );
    }
}

  fn draw(&mut self, g: &mut Graphics) {
    Self::Access::values()
  }
macro_rules! _ui_def_inner {
  ($ui_struct:ident, $el_struct:ty, $ctrl_struct:ty, $acc_struct:ident, $($variant:ident => $field:ident),* $(,)?) => {
    type $ui_struct = $crate::ui::GenUi<$el_struct,$ctrl_struct>;

  fn resize(&mut self, g: &Graphics, width: u32, height: u32);
    #[derive(Copy, Clone, Eq, PartialEq, Debug)]
    pub enum $acc_struct {
      $($variant),*
    }

  fn get_resize_capabilities(&self, g: &Graphics) -> ResizeCapabilities;
    impl $crate::ui::layout::LayoutManager<$el_struct> for $acc_struct {
      fn relayout_at(&self, ui: &mut $el_struct, g: &$crate::ui::graphics::Graphics, x: i32, y: i32, width: u32, height: u32) {
        $crate::ui::access::UiAccess::get_element_mut(ui, *self).set_dimensions(x, y, width, height);
      }

  fn click(&mut self, x: i32, y: i32) -> bool;
      fn get_resize_capabilities(&self, ui: &$el_struct, g: &$crate::ui::graphics::Graphics) -> $crate::ui::rescap::ResizeCapabilities {
        $crate::ui::access::UiAccess::get_element(ui, *self).get_resize_capabilities(g)
      }
    }

  fn open(&mut self) {}
    impl $crate::ui::access::Values for $acc_struct {
      fn values() -> &'static [Self] {
        &[$acc_struct::Button, $acc_struct::Button1]
      }
    }

  fn close(&mut self) {}
}
    impl $crate::ui::access::UiAccess for $el_struct {
      type Access = $acc_struct;

#[macro_export]
macro_rules! ui_impl {
  ($prop:ident) => {
    fn click(&mut self, x: i32, y: i32) {
      self.$prop.click(self, x, y);
    }
      fn by_name(name: &str) -> Option<Self::Access> {
        match name {
          $(stringify!($field) => Some(Self::Access::$variant),)+
          _ => None
        }
      }

    fn draw(&mut self, g: &mut Graphics) {
      self.$prop.draw(g);
    }
      fn get_element(&self, access: Self::Access) -> &dyn $crate::ui::element::Positionable {
        match access {
          $(Self::Access::$variant => &self.$field,)+
        }
      }

    fn resize(&mut self, width: u32, height: u32) {
      self.$prop.resize(width, height);
      fn get_element_mut(&mut self, access: Self::Access) -> &mut dyn $crate::ui::element::Positionable {
        match access {
          $(Self::Access::$variant => &mut self.$field,)+
        }
      }
    }
  }
  };
}

pub struct UiHost {
  current_controller: Option<Box<dyn UiController>>,
pub struct GenUi<E: UiAccess, C: UiController> {
  elements: E,
  controller: C,
  width: u32,
  height: u32,
  needs_resize: bool,
  is_dirty: bool,
}

impl UiHost {
  pub fn new() -> Self {
    UiHost {
      current_controller: None,
impl<E: UiAccess + 'static, C: UiController<Elements=E>> GenUi<E, C> {
  fn new(controller: C) -> Self {
    let elements = controller.create_elements();
    Self {
      elements,
      controller,
      width: 0,
      height: 0,
      needs_resize: false,
      is_dirty: true,
    }
  }
}

  pub fn close_ui(&mut self) -> Option<Box<dyn UiController>> {
    let mut r = self.current_controller.take();
    if let Some(ref mut r) = r {
      r.close();
    }
    r
impl<E: UiAccess + 'static, C: UiController<Elements=E>> Element for GenUi<E, C> {
  fn update(&mut self) {
    self.controller.update(&mut self.elements);
  }

  pub fn open_ui(&mut self, mut element: impl UiController + 'static) -> Option<Box<dyn UiController>> {
    let r = self.close_ui();
    element.open();
    self.current_controller = Some(box element);
    self.needs_resize = true;
    r
  fn draw(&mut self, g: &mut Graphics) {
    if self.is_dirty {
      self.controller.resize(&mut self.elements, g, self.width, self.height);
      self.is_dirty = false;
    }
    self.controller.draw(&mut self.elements, g);
  }

  pub fn resize(&mut self, width: u32, height: u32) {
  fn set_size(&mut self, width: u32, height: u32) {
    self.width = width;
    self.height = height;
    self.needs_resize = true;
    self.is_dirty = true;
  }

  pub fn draw(&mut self, g: &mut Graphics) {
    if let Some(ref mut c) = self.current_controller {
      if self.needs_resize {
        c.resize(g, self.width, self.height);
      }
      c.draw(g)
    }
  fn get_resize_capabilities(&self, g: &Graphics) -> ResizeCapabilities {
    self.controller.get_resize_capabilities(&self.elements, g)
  }
}
\ No newline at end of file
}

M src/ui/panel.rs => src/ui/panel.rs +18 -32
@@ 1,7 1,8 @@
use std::ops::{Deref, DerefMut};

use crate::ui::element::Element;
use crate::ui::element::{Element, Positionable};
use crate::ui::graphics::Graphics;
use crate::ui::rescap::ResizeCapabilities;

pub struct Container<T: Element> {
  drawable: T,


@@ 26,14 27,6 @@ impl<T: Element> Container<T> {

  pub fn drawable_mut(&mut self) -> &mut T { &mut self.drawable }

  pub fn set_dimensions(&mut self, x: i32, y: i32, width: u32, height: u32) {
    self.x = x;
    self.y = y;
    self.width = width;
    self.height = height;
    self.drawable.resize(width, height);
  }

  pub fn x(&self) -> i32 { self.x }

  pub fn y(&self) -> i32 { self.y }


@@ 74,35 67,23 @@ impl<T: Element> DerefMut for Container<T> {
  fn deref_mut(&mut self) -> &mut Self::Target { &mut self.drawable }
}

pub trait ContainerAny {
  fn drawable(&self) -> &dyn Element;

  fn drawable_mut(&mut self) -> &mut dyn Element;

  fn set_dimensions(&mut self, x: i32, y: i32, width: u32, height: u32);

  fn x(&self) -> i32;

  fn y(&self) -> i32;

  fn width(&self) -> u32;

  fn height(&self) -> u32;
}

impl<T: Element> ContainerAny for Container<T> {
  fn drawable(&self) -> &dyn Element {
    self.drawable()
impl<T: Element> Element for Container<T> {
  fn draw(&mut self, g: &mut Graphics) {
    self.draw(g)
  }

  fn drawable_mut(&mut self) -> &mut dyn Element {
    self.drawable_mut()
  fn set_size(&mut self, width: u32, height: u32) {
    self.width = width;
    self.height = height;
    self.drawable_mut().set_size(width, height);
  }

  fn set_dimensions(&mut self, x: i32, y: i32, width: u32, height: u32) {
    self.set_dimensions(x, y, width, height)
  fn get_resize_capabilities(&self, g: &Graphics) -> ResizeCapabilities {
    unimplemented!()
  }
}

impl<T: Element> Positionable for Container<T> {
  fn x(&self) -> i32 {
    self.x()
  }


@@ 118,4 99,9 @@ impl<T: Element> ContainerAny for Container<T> {
  fn height(&self) -> u32 {
    self.height()
  }

  fn set_position(&mut self, x: i32, y: i32) {
    self.x = x;
    self.y = y;
  }
}
\ No newline at end of file

M src/util/anysurface.rs => src/util/anysurface.rs +3 -3
@@ 9,7 9,7 @@ pub enum AnySurface<'a> {
  Fb(&'a mut SimpleFrameBuffer<'a>),
}

impl<'a> Surface for AnySurface<'a> {
impl Surface for AnySurface<'_> {
  fn clear(&mut self, rect: Option<&Rect>, color: Option<(f32, f32, f32, f32)>, color_srgb: bool, depth: Option<f32>, stencil: Option<i32>) {
    match self {
      AnySurface::Frame(s) => s.clear(rect, color, color_srgb, depth, stencil),


@@ 38,8 38,8 @@ impl<'a> Surface for AnySurface<'a> {
    }
  }

  fn draw<'b, 'c, V, I, U>(&mut self, vb: V, ib: I, program: &Program, uniforms: &U, draw_parameters: &DrawParameters) -> Result<(), DrawError> where
    V: MultiVerticesSource<'c>, I: Into<IndicesSource<'b>>,
  fn draw<'a, 'c, V, I, U>(&mut self, vb: V, ib: I, program: &Program, uniforms: &U, draw_parameters: &DrawParameters) -> Result<(), DrawError> where
    V: MultiVerticesSource<'c>, I: Into<IndicesSource<'a>>,
    U: Uniforms {
    match self {
      AnySurface::Frame(s) => s.draw(vb, ib, program, uniforms, draw_parameters),