Skip to content

Commit

Permalink
Added Link associated type to ShaderParam. Gfx builds but macros are …
Browse files Browse the repository at this point in the history
…not ported.
  • Loading branch information
sectopod committed Jan 26, 2015
1 parent cb47f60 commit 7de1690
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 37 deletions.
12 changes: 6 additions & 6 deletions src/gfx/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,12 @@ impl<D: device::Device> Graphics<D> {
}

/// Create a new ref batch.
pub fn make_batch<L, T: shade::ShaderParam<L>>(&mut self,
pub fn make_batch<T: shade::ShaderParam>(&mut self,
program: &ProgramHandle,
mesh: &Mesh,
slice: Slice,
state: &DrawState)
-> Result<batch::RefBatch<L, T>, batch::BatchError> {
-> Result<batch::RefBatch<T>, batch::BatchError> {
self.context.make_batch(program, mesh, slice, state)
}

Expand All @@ -87,14 +87,14 @@ impl<D: device::Device> Graphics<D> {
}

/// Draw a ref batch.
pub fn draw<'a, L, T: shade::ShaderParam<L>>(&'a mut self,
batch: &'a batch::RefBatch<L, T>, data: &'a T, frame: &Frame) {
pub fn draw<'a, T: shade::ShaderParam>(&'a mut self,
batch: &'a batch::RefBatch<T>, data: &'a T, frame: &Frame) {
self.renderer.draw(&(batch, data, &self.context), frame)
}

/// Draw a ref batch with instancing
pub fn draw_instanced<'a, L, T: shade::ShaderParam<L>>(&'a mut self,
batch: &'a batch::RefBatch<L, T>,
pub fn draw_instanced<'a, T: shade::ShaderParam>(&'a mut self,
batch: &'a batch::RefBatch<T>,
data: &'a T,
count: u32,
vertex_offset: u32,
Expand Down
6 changes: 3 additions & 3 deletions src/gfx_macros/shader_param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ impl ItemDecorator for ShaderParam {
let (base_def, link_def) = match item.node {
ast::ItemStruct(ref definition, ref generics) => {
if generics.lifetimes.len() > 0 {
context.bug("Generics are not allowed in ShaderParam struct");
context.bug("Lifetimes are not allowed in ShaderParam struct");
}
(definition, ast::StructDef {
fields: definition.fields.iter()
Expand Down Expand Up @@ -317,7 +317,7 @@ impl ItemDecorator for ShaderParam {
],
Vec::new(),
vec![
context.ty_ident(span, link_ident),
//context.ty_ident(span, link_ident), //TODO
context.ty_ident(span, item.ident)
],
Vec::new(),
Expand Down Expand Up @@ -345,7 +345,7 @@ impl ItemDecorator for ShaderParam {
as `#[shader_param(MyLightBatch, MyHeavyBatch)]`")
}
}
// #[derive ShaderParam
// #[derive ShaderParam]
let trait_def = generic::TraitDef {
span: span,
attributes: Vec::new(),
Expand Down
39 changes: 20 additions & 19 deletions src/render/batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,23 +75,23 @@ pub trait Batch {
}

/// Owned batch - self-contained, but has heap-allocated data
pub struct OwnedBatch<L, T> {
pub struct OwnedBatch<T: ShaderParam> {
mesh: mesh::Mesh,
mesh_link: mesh::Link,
/// Mesh slice
pub slice: mesh::Slice,
/// Parameter data.
pub param: T,
program: ProgramHandle,
param_link: L,
param_link: T::Link,
/// Draw state
pub state: DrawState,
}

impl<L, T: ShaderParam<L>> OwnedBatch<L, T> {
impl<T: ShaderParam> OwnedBatch<T> {
/// Create a new owned batch
pub fn new(mesh: mesh::Mesh, program: ProgramHandle, param: T)
-> Result<OwnedBatch<L, T>, BatchError> {
-> Result<OwnedBatch<T>, BatchError> {
let slice = mesh.to_slice(PrimitiveType::TriangleList);
let mesh_link = match link_mesh(&mesh, program.get_info()) {
Ok(l) => l,
Expand All @@ -113,7 +113,7 @@ impl<L, T: ShaderParam<L>> OwnedBatch<L, T> {
}
}

impl<L, T: ShaderParam<L>> Batch for OwnedBatch<L, T> {
impl<T: ShaderParam> Batch for OwnedBatch<T> {
fn get_data(&self) -> (&mesh::Mesh, &mesh::Link, &mesh::Slice, &ProgramHandle, &DrawState) {
(&self.mesh, &self.mesh_link, &self.slice, &self.program, &self.state)
}
Expand Down Expand Up @@ -201,42 +201,43 @@ impl<T: Clone + PartialEq> Array<T> {
/// Ref batch - copyable and smaller, but depends on the `Context`.
/// It has references to the resources (mesh, program, state), that are held
/// by the context that created the batch, so these have to be used together.
#[derive(Copy)]
pub struct RefBatch<L, T> {
pub struct RefBatch<T: ShaderParam> {
mesh_id: Id<mesh::Mesh>,
mesh_link: mesh::Link,
/// Mesh slice
pub slice: mesh::Slice,
program_id: Id<ProgramHandle>,
param_link: L,
param_link: T::Link,
state_id: Id<DrawState>,
}

impl<L, T> fmt::Debug for RefBatch<L, T> {
impl<T: ShaderParam> Copy for RefBatch<T> where T::Link: Copy {}

impl<T> fmt::Debug for RefBatch<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "RefBatch(mesh: {:?}, slice: {:?}, program: {:?}, state: {:?})",
self.mesh_id, self.slice, self.program_id, self.state_id)
}
}

impl<L, T> PartialEq for RefBatch<L, T> {
fn eq(&self, other: &RefBatch<L, T>) -> bool {
impl<T> PartialEq for RefBatch<T> {
fn eq(&self, other: &RefBatch<T>) -> bool {
self.program_id == other.program_id &&
self.state_id == other.state_id &&
self.mesh_id == other.mesh_id
}
}

impl<L, T> Eq for RefBatch<L, T> {}
impl<T> Eq for RefBatch<T> {}

impl<L, T> PartialOrd for RefBatch<L, T> {
fn partial_cmp(&self, other: &RefBatch<L, T>) -> Option<Ordering> {
impl<T> PartialOrd for RefBatch<T> {
fn partial_cmp(&self, other: &RefBatch<T>) -> Option<Ordering> {
Some(self.cmp(other))
}
}

impl<L, T> Ord for RefBatch<L, T> {
fn cmp(&self, other: &RefBatch<L, T>) -> Ordering {
impl<T> Ord for RefBatch<T> {
fn cmp(&self, other: &RefBatch<T>) -> Ordering {
(&self.program_id, &self.state_id, &self.mesh_id).cmp(
&(&other.program_id, &other.state_id, &other.mesh_id))
}
Expand All @@ -262,12 +263,12 @@ impl Context {

impl Context {
/// Produce a new ref batch
pub fn make_batch<L, T: ShaderParam<L>>(&mut self,
pub fn make_batch<T: ShaderParam>(&mut self,
program: &ProgramHandle,
mesh: &mesh::Mesh,
slice: mesh::Slice,
state: &DrawState)
-> Result<RefBatch<L, T>, BatchError> {
-> Result<RefBatch<T>, BatchError> {
let mesh_link = match link_mesh(mesh, program.get_info()) {
Ok(l) => l,
Err(e) => return Err(BatchError::Mesh(e)),
Expand Down Expand Up @@ -300,7 +301,7 @@ impl Context {
}
}

impl<'a, L, T: ShaderParam<L>> Batch for (&'a RefBatch<L, T>, &'a T, &'a Context) {
impl<'a, T: ShaderParam> Batch for (&'a RefBatch<T>, &'a T, &'a Context) {
fn get_data(&self) -> (&mesh::Mesh, &mesh::Link, &mesh::Slice, &ProgramHandle, &DrawState) {
let (b, _, ctx) = *self;
(ctx.meshes.get(b.mesh_id),
Expand Down
25 changes: 16 additions & 9 deletions src/render/shade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,18 @@ pub enum ParameterError {
}

/// Abstracts the shader parameter structure, generated by the `shader_param` attribute
pub trait ShaderParam<L> {
/// Creates a new link, self is passed as a workaround for Rust to not be lost in generics
fn create_link(Option<&Self>, &shade::ProgramInfo) -> Result<L, ParameterError>;
/// Get all the contained parameter values, using a given link.
fn fill_params(&self, &L, ParamValues);
pub trait ShaderParam {
/// A helper structure to contain variable indices inside the shader
type Link;
/// Create a new link to be used with a given program
fn create_link(Option<&Self>, &shade::ProgramInfo) -> Result<Self::Link, ParameterError>;
/// Get all the contained parameter values, using a given link
fn fill_params(&self, &Self::Link, ParamValues);
}

impl ShaderParam<()> for () {
impl ShaderParam for () {
type Link = ();

fn create_link(_: Option<&()>, info: &shade::ProgramInfo) -> Result<(), ParameterError> {
match info.uniforms[].first() {
Some(u) => return Err(ParameterError::MissingUniform(u.name.clone())),
Expand Down Expand Up @@ -136,15 +140,18 @@ pub struct ParamDictionary {
pub textures: Vec<NamedCell<TextureParam>>,
}

/// An associated link structure for `ParamDictionary` that redirects program
/// input to the relevant dictionary cell.
/// An associated parameter link for ParamDictionary
pub struct ParamDictionaryLink {
uniforms: Vec<usize>,
blocks: Vec<usize>,
textures: Vec<usize>,
}

impl ShaderParam<ParamDictionaryLink> for ParamDictionary {
/// An associated link structure for `ParamDictionary` that redirects program
/// input to the relevant dictionary cell.
impl ShaderParam for ParamDictionary {
type Link = ParamDictionaryLink;

fn create_link(this: Option<&ParamDictionary>, info: &shade::ProgramInfo)
-> Result<ParamDictionaryLink, ParameterError> {
let this = match this {
Expand Down

0 comments on commit 7de1690

Please sign in to comment.