[oden] Some perhaps unadvised factoring
Traits for fun and profit. I was nervous about the amount of magic "you have to get this right" coupling between runtime structures (the draw mode) and types (the various instance types) and I didn't want to get them wrong. So now some things are more generic than they were before, and maybe that's good? Who can say in the end.
This commit is contained in:
parent
40992f840f
commit
df49143885
1 changed files with 45 additions and 33 deletions
78
src/lib.rs
78
src/lib.rs
|
|
@ -692,6 +692,34 @@ enum DrawMode {
|
|||
Circles,
|
||||
}
|
||||
|
||||
trait DrawModeInstance: Sized {
|
||||
const MODE: DrawMode;
|
||||
fn get_vertex_buffer<'a>(
|
||||
state: &'a mut State,
|
||||
vb: &VertexBufferHandle,
|
||||
) -> &'a mut VertexBuffer<Self>;
|
||||
}
|
||||
|
||||
impl DrawModeInstance for SpriteInstance {
|
||||
const MODE: DrawMode = DrawMode::Sprites;
|
||||
fn get_vertex_buffer<'a>(
|
||||
state: &'a mut State,
|
||||
vb: &VertexBufferHandle,
|
||||
) -> &'a mut VertexBuffer<Self> {
|
||||
state.sprite_instance_buffers.get_mut(&vb)
|
||||
}
|
||||
}
|
||||
|
||||
impl DrawModeInstance for CircleInstance {
|
||||
const MODE: DrawMode = DrawMode::Circles;
|
||||
fn get_vertex_buffer<'a>(
|
||||
state: &'a mut State,
|
||||
vb: &VertexBufferHandle,
|
||||
) -> &'a mut VertexBuffer<Self> {
|
||||
state.circle_instance_buffers.get_mut(&vb)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct DrawCall {
|
||||
mode: DrawMode,
|
||||
|
|
@ -891,7 +919,16 @@ impl<'a> FrameBuilder<'a> {
|
|||
}
|
||||
|
||||
fn start_pass(&mut self, color: Option<[f64; 4]>, target: Rc<wgpu::TextureView>) {
|
||||
// NOTE: We're not changing drawing modes here which means we can preserve the
|
||||
// buffer tail if we want to.
|
||||
let first_call = match self.draw_calls.last() {
|
||||
Some(call) => call.new_at_buffer_tail(),
|
||||
None => DrawCall::new(self.mode, self.new_instance_buffer(), 0),
|
||||
};
|
||||
|
||||
self.flush();
|
||||
|
||||
self.draw_calls.push(first_call);
|
||||
self.color = color;
|
||||
self.target = target;
|
||||
}
|
||||
|
|
@ -935,19 +972,15 @@ impl<'a> FrameBuilder<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn switch_mode(&mut self, mode: DrawMode) {
|
||||
if self.mode != mode {
|
||||
fn get_instance_buffer<T: DrawModeInstance>(&mut self) -> &mut VertexBuffer<T> {
|
||||
if self.mode != T::MODE {
|
||||
self.flush();
|
||||
self.draw_calls.clear();
|
||||
self.mode = mode;
|
||||
self.mode = T::MODE;
|
||||
}
|
||||
}
|
||||
|
||||
fn get_sprite_instance_buffer(&mut self) -> &mut VertexBuffer<SpriteInstance> {
|
||||
self.switch_mode(DrawMode::Sprites);
|
||||
match self.draw_calls.last_mut() {
|
||||
Some(call) => match call.allocate_capacity(1) {
|
||||
Some(vb) => return self.state.sprite_instance_buffers.get_mut(&vb),
|
||||
Some(vb) => return T::get_vertex_buffer(self.state, &vb),
|
||||
None => {}
|
||||
},
|
||||
None => {}
|
||||
|
|
@ -956,34 +989,19 @@ impl<'a> FrameBuilder<'a> {
|
|||
let mut call = DrawCall::new(self.mode, self.new_instance_buffer(), 0);
|
||||
let vb = call.allocate_capacity(1).unwrap();
|
||||
self.draw_calls.push(call);
|
||||
self.state.sprite_instance_buffers.get_mut(&vb)
|
||||
T::get_vertex_buffer(self.state, &vb)
|
||||
}
|
||||
|
||||
fn push_sprite(&mut self, si: SpriteInstance) {
|
||||
let vertex_buffer = self.get_sprite_instance_buffer();
|
||||
let vertex_buffer = self.get_instance_buffer();
|
||||
vertex_buffer.vec.push(si);
|
||||
}
|
||||
|
||||
fn get_circle_instance_buffer(&mut self) -> &mut VertexBuffer<CircleInstance> {
|
||||
self.switch_mode(DrawMode::Circles);
|
||||
match self.draw_calls.last_mut() {
|
||||
Some(call) => match call.allocate_capacity(1) {
|
||||
Some(vb) => return self.state.circle_instance_buffers.get_mut(&vb),
|
||||
None => {}
|
||||
},
|
||||
None => {}
|
||||
};
|
||||
|
||||
let mut call = DrawCall::new(self.mode, self.new_instance_buffer(), 0);
|
||||
let vb = call.allocate_capacity(1).unwrap();
|
||||
self.draw_calls.push(call);
|
||||
self.state.circle_instance_buffers.get_mut(&vb)
|
||||
}
|
||||
|
||||
fn push_circle(&mut self, cc: script::graphics::CircleCommand) {
|
||||
let stroke_color = self.stroke_color.clone();
|
||||
let fill_color = self.fill_color.clone();
|
||||
let vertex_buffer = self.get_circle_instance_buffer();
|
||||
|
||||
let vertex_buffer = self.get_instance_buffer();
|
||||
vertex_buffer.vec.push(CircleInstance {
|
||||
center: cc.center,
|
||||
radius: cc.radius,
|
||||
|
|
@ -994,11 +1012,6 @@ impl<'a> FrameBuilder<'a> {
|
|||
}
|
||||
|
||||
fn flush(&mut self) {
|
||||
let first_call = match self.draw_calls.last() {
|
||||
Some(call) => call.new_at_buffer_tail(),
|
||||
None => DrawCall::new(self.mode, self.new_instance_buffer(), 0),
|
||||
};
|
||||
|
||||
if self.draw_calls.len() > 0 {
|
||||
let mut pass = self.encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
label: Some("Render Pass"),
|
||||
|
|
@ -1034,7 +1047,6 @@ impl<'a> FrameBuilder<'a> {
|
|||
|
||||
self.color = None;
|
||||
self.draw_calls.clear();
|
||||
self.draw_calls.push(first_call);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue