Skip to content

Commit

Permalink
Merge pull request #447 from Diggsey/webgl-gen
Browse files Browse the repository at this point in the history
Implement IDL based generators
  • Loading branch information
brendanzab authored Apr 1, 2018
2 parents 414f6c1 + 136122f commit 4f081d2
Show file tree
Hide file tree
Showing 32 changed files with 2,658 additions and 315 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@
members = [
"gl",
"gl_generator",
"webgl_stdweb",
"webgl_generator",
"tests/test_add_registries",
"tests/test_gen_symbols",
"tests/test_no_warnings",
"tests/test_symbols",
"tests/test_unstable_api",
"tests/test_with_extensions",
"tests/test_webgl_stdweb",
"khronos_api",
]
2 changes: 1 addition & 1 deletion gl/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

extern crate gl_generator;

use gl_generator::{Registry, Fallbacks, GlobalGenerator, Api, Profile};
use gl_generator::{Api, Fallbacks, GlobalGenerator, Profile, Registry};
use std::env;
use std::fs::File;
use std::path::Path;
Expand Down
126 changes: 75 additions & 51 deletions gl_generator/generators/debug_struct_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ pub struct DebugStructGenerator;

impl super::Generator for DebugStructGenerator {
fn write<W>(&self, registry: &Registry, dest: &mut W) -> io::Result<()>
where W: io::Write
where
W: io::Write,
{
try!(write_header(dest));
try!(write_type_aliases(registry, dest));
Expand All @@ -36,29 +37,35 @@ impl super::Generator for DebugStructGenerator {
/// Creates a `__gl_imports` module which contains all the external symbols that we need for the
/// bindings.
fn write_header<W>(dest: &mut W) -> io::Result<()>
where W: io::Write
where
W: io::Write,
{
writeln!(dest,
r#"
writeln!(
dest,
r#"
mod __gl_imports {{
pub use std::mem;
pub use std::marker::Send;
pub use std::os::raw;
}}
"#)
"#
)
}

/// Creates a `types` module which contains all the type aliases.
///
/// See also `generators::gen_types`.
fn write_type_aliases<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
where W: io::Write
where
W: io::Write,
{
try!(writeln!(dest,
r#"
try!(writeln!(
dest,
r#"
pub mod types {{
#![allow(non_camel_case_types, non_snake_case, dead_code, missing_copy_implementations)]
"#));
"#
));

try!(super::gen_types(registry.api, dest));

Expand All @@ -67,7 +74,8 @@ fn write_type_aliases<W>(registry: &Registry, dest: &mut W) -> io::Result<()>

/// Creates all the `<enum>` elements at the root of the bindings.
fn write_enums<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
where W: io::Write
where
W: io::Write,
{
for enm in &registry.enums {
try!(super::gen_enum_item(enm, "types::", dest));
Expand All @@ -78,10 +86,12 @@ fn write_enums<W>(registry: &Registry, dest: &mut W) -> io::Result<()>

/// Creates a `FnPtr` structure which contains the store for a single binding.
fn write_fnptr_struct_def<W>(dest: &mut W) -> io::Result<()>
where W: io::Write
where
W: io::Write,
{
writeln!(dest,
"
writeln!(
dest,
"
#[allow(dead_code, missing_copy_implementations)]
#[derive(Clone)]
pub struct FnPtr {{
Expand Down Expand Up @@ -113,35 +123,42 @@ fn write_fnptr_struct_def<W>(dest: &mut W) -> io::Result<()>
self.is_loaded
}}
}}
")
"
)
}

/// Creates a `panicking` module which contains one function per GL command.
///
/// These functions are the mocks that are called if the real function could not be loaded.
fn write_panicking_fns<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
where W: io::Write
where
W: io::Write,
{
writeln!(dest,
"#[inline(never)]
writeln!(
dest,
"#[inline(never)]
fn missing_fn_panic() -> ! {{
panic!(\"{api} function was not loaded\")
}}",
api = registry.api)
api = registry.api
)
}

/// Creates a structure which stores all the `FnPtr` of the bindings.
///
/// The name of the struct corresponds to the namespace.
fn write_struct<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
where W: io::Write
where
W: io::Write,
{
try!(writeln!(dest,
"
try!(writeln!(
dest,
"
#[allow(non_camel_case_types, non_snake_case, dead_code)]
#[derive(Clone)]
pub struct {api} {{",
api = super::gen_struct_name(registry.api)));
api = super::gen_struct_name(registry.api)
));

for cmd in &registry.cmds {
if let Some(v) = registry.aliases.get(&cmd.proto.ident) {
Expand All @@ -156,7 +173,8 @@ fn write_struct<W>(registry: &Registry, dest: &mut W) -> io::Result<()>

/// Creates the `impl` of the structure created by `write_struct`.
fn write_impl<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
where W: io::Write
where
W: io::Write,
{
try!(writeln!(dest,
"impl {api} {{
Expand Down Expand Up @@ -189,45 +207,49 @@ fn write_impl<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
api = super::gen_struct_name(registry.api)));

for cmd in &registry.cmds {
try!(writeln!(dest,
try!(writeln!(
dest,
"{name}: FnPtr::new(metaloadfn(\"{symbol}\", &[{fallbacks}])),",
name = cmd.proto.ident,
symbol = super::gen_symbol_name(registry.api, &cmd.proto.ident),
fallbacks = match registry.aliases.get(&cmd.proto.ident) {
Some(fbs) => {
fbs.iter()
.map(|name| format!("\"{}\"", super::gen_symbol_name(registry.api, &name)))
.collect::<Vec<_>>().join(", ")
},
Some(fbs) => fbs.iter()
.map(|name| format!("\"{}\"", super::gen_symbol_name(registry.api, &name)))
.collect::<Vec<_>>()
.join(", "),
None => format!(""),
},
))
}
try!(writeln!(dest, "_priv: ()"));

try!(writeln!(dest,
"}}
}}"));
try!(writeln!(
dest,
"}}
}}"
));

for cmd in &registry.cmds {
let idents = super::gen_parameters(cmd, true, false);
let typed_params = super::gen_parameters(cmd, false, true);
let println = format!("println!(\"[OpenGL] {}({})\" {});",
cmd.proto.ident,
(0..idents.len())
.map(|_| "{:?}".to_string())
.collect::<Vec<_>>()
.join(", "),
idents
.iter()
.zip(typed_params.iter())
.map(|(name, ty)| if ty.contains("GLDEBUGPROC") {
format!(", \"<callback>\"")
} else {
format!(", {}", name)
})
.collect::<Vec<_>>()
.concat());
let println = format!(
"println!(\"[OpenGL] {}({})\" {});",
cmd.proto.ident,
(0..idents.len())
.map(|_| "{:?}".to_string())
.collect::<Vec<_>>()
.join(", "),
idents
.iter()
.zip(typed_params.iter())
.map(|(name, ty)| if ty.contains("GLDEBUGPROC") {
format!(", \"<callback>\"")
} else {
format!(", {}", name)
})
.collect::<Vec<_>>()
.concat()
);

try!(writeln!(dest,
"#[allow(non_snake_case, unused_variables, dead_code)]
Expand Down Expand Up @@ -257,9 +279,11 @@ fn write_impl<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
}))
}

writeln!(dest,
"}}
writeln!(
dest,
"}}
unsafe impl __gl_imports::Send for {api} {{}}",
api = super::gen_struct_name(registry.api))
api = super::gen_struct_name(registry.api)
)
}
Loading

0 comments on commit 4f081d2

Please sign in to comment.