Skip to content

Commit eade7b4

Browse files
committed
API improvements
- Use (u8, u8) for version number - Allow extension lists to be any types that implement AsRef<[&str]> - Separate parsing and generation stages in API
1 parent 86bf7d0 commit eade7b4

10 files changed

Lines changed: 192 additions & 106 deletions

File tree

gl/build.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
extern crate gl_generator;
1616

17-
use gl_generator::{Fallbacks, GlobalGenerator, Api, Profile};
17+
use gl_generator::{Registry, Fallbacks, GlobalGenerator, Api, Profile};
1818
use std::env;
1919
use std::fs::File;
2020
use std::path::Path;
@@ -23,6 +23,7 @@ fn main() {
2323
let out_dir = env::var("OUT_DIR").unwrap();
2424
let mut file = File::create(&Path::new(&out_dir).join("bindings.rs")).unwrap();
2525

26-
gl_generator::generate_bindings(GlobalGenerator, Api::Gl, Fallbacks::All,
27-
vec![], "4.5", Profile::Core, &mut file).unwrap();
26+
Registry::new(Api::Gl, (4, 5), Profile::Core, Fallbacks::All, [])
27+
.write_bindings(GlobalGenerator, &mut file)
28+
.unwrap();
2829
}

gl_generator/README.md

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -33,33 +33,34 @@ Create a `build.rs` to pull your specific version/API:
3333
```rust
3434
extern crate gl_generator;
3535

36-
use gl_generator::{Fallbacks, GlobalGenerator, Api, Profile};
36+
use gl_generator::{Registry, Api, Profile, Fallbacks, GlobalGenerator};
3737
use std::env;
3838
use std::fs::File;
3939
use std::path::Path;
4040

4141
fn main() {
4242
let dest = env::var("OUT_DIR").unwrap();
43-
let mut file = File::create(&Path::new(&dest).join("bindings.rs")).unwrap();
43+
let mut file = File::create(&Path::new(&dest).join("gl_bindings.rs")).unwrap();
4444

45-
gl_generator::generate_bindings(GlobalGenerator, Api::Gl, Fallbacks::All,
46-
vec![], "4.5", Profile::Core, &mut file).unwrap();
45+
Registry::new(Api::Gl, (4, 5), Profile::Core, Fallbacks::All, [])
46+
.write_bindings(GlobalGenerator, &mut file)
47+
.unwrap();
4748
}
4849
```
4950

5051
Then use it like this:
5152

5253
```rust
53-
mod gles {
54+
mod gl {
5455
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
5556
}
5657

57-
/*
58-
* Simple loading example
59-
*/
58+
/// Simple loading example
6059
fn main() {
61-
// Assuming window is GLFW, initialized, and made current
62-
gles::load_with(|s| window.get_proc_address(s));
60+
let window = ...;
61+
62+
// Assuming `window` is GLFW: initialize, and made current
63+
gl::load_with(|s| window.get_proc_address(s));
6364
}
6465
```
6566

@@ -105,11 +106,8 @@ OpenGL 1.1 on Windows, you will need to add
105106
### Custom Generators
106107

107108
The `gl_generator` crate is extensible. This is a niche feature useful only in
108-
very rare cases. To create a custom generator, [create a new plugin
109-
crate](http://doc.rust-lang.org/guide-plugin.html#syntax-extensions) which
110-
depends on `gl_generator`. Then, implement the `gl_generator::Generator` trait
111-
and in your plugin registrar, register a function which calls
112-
`gl_generator::generate_bindings` with your custom generator and its name.
109+
very rare cases. To create a custom generator, implement the
110+
`gl_generator::generators::Generator` trait.
113111

114112
## Extra features
115113

@@ -122,14 +120,16 @@ also attempt to load `glGenFramebuffersEXT` as a fallback.
122120
### vX.X.X
123121

124122
- Rename `Ns` to `API`, and expose at the top level
125-
- Use `Api` for `Extension::supported` and `Filter::api` fields
126-
- Remove `source` argument from `generate_bindings`, removing the need for
127-
clients to depend on the `khronos_api` crate
128-
- Add `Profile` enum for specifying the API profile, and change the `source`
129-
argument to use it instead of a string
130-
- Remove `features` and `extensions` fields from `Registry`
131-
- Hide `registry::{Feature, Filter, Require, Remove, Extension}` from the public API
132-
- Move `registry::{Fallbacks, Api, Profile}` to top level module
123+
- Remove the need for clients to depend on the `khronos_api` crate by
124+
determining the XML source based on the requested `API`
125+
- Use a `(u8, u8)` instead of a string for the target version number
126+
- Use a `Profile` enum instead of a string for the profile
127+
- Remove unused fields from `Registry`
128+
- Accept types satisfying `AsRef<[&str]>` for extension lists
129+
- Separate parsing and generation stages in API
130+
- Hide `registry::{Feature, Filter, Require, Remove, Extension}` types from the
131+
public API
132+
- Move `registry::{Fallbacks, Api, Profile}` types to top level module
133133

134134
### v0.4.2
135135

gl_generator/lib.rs

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
//! ```no_run
2424
//! extern crate gl_generator;
2525
//!
26-
//! use gl_generator::{Fallbacks, GlobalGenerator, Api, Profile};
26+
//! use gl_generator::{Registry, Api, Profile, Fallbacks, GlobalGenerator};
2727
//! use std::env;
2828
//! use std::fs::File;
2929
//! use std::path::Path;
@@ -32,8 +32,9 @@
3232
//! let dest = env::var("OUT_DIR").unwrap();
3333
//! let mut file = File::create(&Path::new(&dest).join("gl_bindings.rs")).unwrap();
3434
//!
35-
//! gl_generator::generate_bindings(GlobalGenerator, Api::Gl, Fallbacks::All,
36-
//! vec![], "4.5", Profile::Core, &mut file).unwrap();
35+
//! Registry::new(Api::Gl, (4, 5), Profile::Core, Fallbacks::All, [])
36+
//! .write_bindings(GlobalGenerator, &mut file)
37+
//! .unwrap();
3738
//! }
3839
//! ```
3940
//!
@@ -64,11 +65,11 @@
6465
extern crate log;
6566

6667
use generators::Generator;
67-
use registry::Registry;
6868

6969
use std::fmt;
7070
use std::io;
7171

72+
pub use registry::Registry;
7273
pub use generators::debug_struct_gen::DebugStructGenerator;
7374
pub use generators::global_gen::GlobalGenerator;
7475
pub use generators::static_gen::StaticGenerator;
@@ -102,23 +103,11 @@ pub enum Fallbacks { All, None }
102103
#[derive(Copy, Clone, PartialEq, Eq)]
103104
pub enum Profile { Core, Compatibility }
104105

105-
/// Generate OpenGL bindings using the specified generator
106-
///
107-
/// # Arguments
108-
///
109-
/// - `generator`: The type of loader to generate.
110-
/// - `api`: The API to generate.
111-
/// - `profile`: `Profile::Core` will only include all functions supported by the requested API
112-
/// version, while `Profile::Compatibility` will include all the functions from previous versions
113-
/// of the API as well.
114-
/// - `version`: The requested API version. This is usually in the form `"major.minor"`.
115-
/// - `extensions`: A list of extra extensions to include in the bindings.
116-
/// - `dest`: Where to write the generated rust source code to
117-
///
118-
pub fn generate_bindings<G, W>(generator: G, api: Api, fallbacks: Fallbacks,
119-
extensions: Vec<String>, version: &str, profile: Profile,
120-
dest: &mut W) -> io::Result<()> where G: Generator, W: io::Write
121-
{
122-
let registry = Registry::new(api, fallbacks, extensions, version, profile);
123-
generator.write(&registry, dest)
106+
impl Registry {
107+
pub fn write_bindings<W, G>(&self, generator: G, output: &mut W) -> io::Result<()> where
108+
G: Generator,
109+
W: io::Write,
110+
{
111+
generator.write(&self, output)
112+
}
124113
}

gl_generator/registry.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,15 @@ pub struct Registry {
9898
}
9999

100100
impl Registry {
101-
/// Generate a registry from the supplied XML string
102-
pub fn new(api: Api, fallbacks: Fallbacks, extensions: Vec<String>, version: &str, profile: Profile) -> Registry {
101+
pub fn new<'a, Exts>(api: Api, version: (u8, u8), profile: Profile, fallbacks: Fallbacks, extensions: Exts) -> Registry where
102+
Exts: AsRef<[&'a str]>,
103+
{
104+
let (major, minor) = version;
105+
103106
let filter = Filter {
104107
fallbacks: fallbacks,
105108
extensions: extensions,
106-
version: version.to_string(),
109+
version: format!("{}.{}", major, minor),
107110
profile: profile,
108111
};
109112

@@ -262,9 +265,9 @@ struct RegistryParser<R: io::Read> {
262265
reader: XmlEventReader<R>,
263266
}
264267

265-
struct Filter {
268+
struct Filter<Extensions> {
266269
fallbacks: Fallbacks,
267-
extensions: Vec<String>,
270+
extensions: Extensions,
268271
profile: Profile,
269272
version: String,
270273
}
@@ -319,7 +322,9 @@ impl<R: io::Read> RegistryParser<R> {
319322
}
320323
}
321324

322-
fn parse(src: R, api: Api, filter: Filter) -> Registry {
325+
fn parse<'a, Exts>(src: R, api: Api, filter: Filter<Exts>) -> Registry where
326+
Exts: AsRef<[&'a str]>,
327+
{
323328
let mut parser = RegistryParser {
324329
api: api,
325330
reader: XmlEventReader::new(src),
@@ -420,7 +425,7 @@ impl<R: io::Read> RegistryParser<R> {
420425
}
421426

422427
for extension in extensions.iter() {
423-
if filter.extensions.iter().any(|x| x == &extension.name) {
428+
if filter.extensions.as_ref().iter().any(|x| x == &extension.name) {
424429
if !extension.supported.iter().any(|x| x == &api) {
425430
panic!("Requested {}, which doesn't support the {} API", extension.name, api);
426431
}

gl_tests/test_gen_symbols/build.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,28 +25,33 @@ fn main() {
2525
let mut file = File::create(&Path::new(&dest).join("test_gen_symbols.rs")).unwrap();
2626

2727
writeln!(&mut file, "mod gl {{").unwrap();
28-
gl_generator::generate_bindings(GlobalGenerator, Api::Gl, Fallbacks::All,
29-
vec![], "4.5", Profile::Core, &mut file).unwrap();
28+
Registry::new(Api::Gl, (4, 5), Profile::Core, Fallbacks::All, [])
29+
.write_bindings(GlobalGenerator, &mut file)
30+
.unwrap();
3031
writeln!(&mut file, "}}").unwrap();
3132

3233
writeln!(&mut file, "mod gles {{").unwrap();
33-
gl_generator::generate_bindings(GlobalGenerator, Api::Gles2, Fallbacks::All,
34-
vec![], "3.1", Profile::Core, &mut file).unwrap();
34+
Registry::new(Api::Gles2, (3, 1), Profile::Core, Fallbacks::All, [])
35+
.write_bindings(GlobalGenerator, &mut file)
36+
.unwrap();
3537
writeln!(&mut file, "}}").unwrap();
3638

3739
writeln!(&mut file, "mod glx {{").unwrap();
38-
gl_generator::generate_bindings(GlobalGenerator, Api::Glx, Fallbacks::All,
39-
vec![], "1.4", Profile::Core, &mut file).unwrap();
40+
Registry::new(Api::Glx, (1, 4), Profile::Core, Fallbacks::All, [])
41+
.write_bindings(GlobalGenerator, &mut file)
42+
.unwrap();
4043
writeln!(&mut file, "}}").unwrap();
4144

4245
writeln!(&mut file, "mod wgl {{").unwrap();
43-
gl_generator::generate_bindings(GlobalGenerator, Api::Wgl, Fallbacks::All,
44-
vec![], "1.0", Profile::Core, &mut file).unwrap();
46+
Registry::new(Api::Wgl, (1, 0), Profile::Core, Fallbacks::All, [])
47+
.write_bindings(GlobalGenerator, &mut file)
48+
.unwrap();
4549
writeln!(&mut file, "}}").unwrap();
4650

4751
writeln!(&mut file, "mod egl {{ {}", build_egl_symbols()).unwrap();
48-
gl_generator::generate_bindings(GlobalGenerator, Api::Egl, Fallbacks::All,
49-
vec![], "1.5", Profile::Core, &mut file).unwrap();
52+
Registry::new(Api::Egl, (1, 5), Profile::Core, Fallbacks::All, [])
53+
.write_bindings(GlobalGenerator, &mut file)
54+
.unwrap();
5055
writeln!(&mut file, "}}").unwrap();
5156
}
5257

0 commit comments

Comments
 (0)