Skip to content

Commit

Permalink
rust: added a loader, a Cargo.toml and an example.
Browse files Browse the repository at this point in the history
  • Loading branch information
Dav1dde committed Aug 24, 2018
1 parent 41e53b2 commit 864addb
Show file tree
Hide file tree
Showing 7 changed files with 249 additions and 151 deletions.
40 changes: 40 additions & 0 deletions example/rust/gl_glfw.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
extern crate glfw;
extern crate glad_gl;
use glfw::{Action, Context, Key};
use glad_gl::gl;


fn main() {
let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();

let (mut window, events) = glfw.create_window(300, 300, "[glad] Rust - OpenGL with GLFW", glfw::WindowMode::Windowed)
.expect("Failed to create GLFW window.");

window.set_key_polling(true);
window.make_current();

gl::load(|e| glfw.get_proc_address_raw(e) as *const std::os::raw::c_void);

while !window.should_close() {
glfw.poll_events();
for (_, event) in glfw::flush_messages(&events) {
handle_window_event(&mut window, event);
}

unsafe {
gl::ClearColor(0.7, 0.9, 0.1, 1.0);
gl::Clear(gl::GL_COLOR_BUFFER_BIT);
}

window.swap_buffers();
}
}

fn handle_window_event(window: &mut glfw::Window, event: glfw::WindowEvent) {
match event {
glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => {
window.set_should_close(true)
}
_ => {}
}
}
42 changes: 38 additions & 4 deletions glad/generator/rust/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import jinja2

import glad
from glad.config import Config
from glad.generator import JinjaGenerator

Expand All @@ -9,7 +12,7 @@ def enum_type(enum):
}.get(enum.type, 'GLenum')

if enum.value.startswith('0x'):
return 'GLuint64' if len(enum.value) > 8 else 'GLenum'
return 'GLuint64' if len(enum.value[2:]) > 8 else 'GLenum'

if enum.name in ('GL_TRUE', 'GL_FALSE'):
return 'GLubyte'
Expand Down Expand Up @@ -63,6 +66,26 @@ def pn(name):
raise ValueError('invalid mode: ' + mode)


@jinja2.contextfilter
def no_prefix(context, value):
spec = context['spec']

api_prefix = spec.name

# glFoo -> Foo
# GL_ARB_asd -> ARB_asd

name = value
if name.lower().startswith(api_prefix):
name = name[len(api_prefix):].lstrip('_')

# 3DFX_tbuffer -> _3DFX_tbuffer
if not name[0].isalpha():
name = '_' + name

return name


class RustConfig(Config):
pass

Expand All @@ -79,16 +102,27 @@ def __init__(self, *args, **kwargs):
self.environment.filters.update(
enum_type=enum_type,
type=to_rust_type,
params=to_rust_params
params=to_rust_params,
no_prefix=no_prefix
)

@property
def id(self):
return 'rust'

def get_template_arguments(self, spec, feature_set, config):
args = JinjaGenerator.get_template_arguments(self, spec, feature_set, config)

args.update(
version=glad.__version__
)

return args

def get_templates(self, spec, feature_set, config):
return [
('lib.rs', 'glad/src/lib.rs'),
('{}.rs'.format(feature_set.name), 'glad/src/{}.rs'.format(feature_set.name))
('Cargo.toml', 'glad-{}/Cargo.toml'.format(feature_set.name)),
('lib.rs', 'glad-{}/src/lib.rs'.format(feature_set.name)),
('impl.rs'.format(feature_set.name), 'glad-{0}/src/{0}.rs'.format(feature_set.name))
]

4 changes: 4 additions & 0 deletions glad/generator/rust/templates/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[package]
name = "glad-{{ feature_set.name }}"
version = "{{ version }}"
authors = ["David Herberth <[email protected]>"]
146 changes: 0 additions & 146 deletions glad/generator/rust/templates/gl.rs

This file was deleted.

70 changes: 70 additions & 0 deletions glad/generator/rust/templates/impl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
pub use self::types::*;
pub use self::enumerations::*;
pub use self::functions::*;

use std::os::raw;

pub struct FnPtr {
ptr: *const raw::c_void,
}

impl FnPtr {
pub fn empty() -> FnPtr {
FnPtr { ptr: FnPtr::not_initialized as *const raw::c_void }
}

pub fn load<F>(&mut self, loadfn: &mut F, name: &'static str) where F: FnMut(&'static str) -> *const raw::c_void {
let loaded = loadfn(name);
if !loaded.is_null() {
self.ptr = loaded;
};
}

#[inline(never)]
fn not_initialized() -> ! { panic!("{{ feature_set.name }}: function not initialized") }
}

pub mod types {
{% include 'types/' + spec.name + '.rs' %}
}

pub mod enumerations {
#![allow(dead_code, non_upper_case_globals)]

use super::types::*;

{% for enum in feature_set.enums %}
pub const {{ enum.name }}: {{ enum | enum_type }} = {{ enum.value }};
{% endfor %}
}

pub mod functions {
#![allow(non_snake_case, unused_variables, dead_code)]

use std::mem;
use super::storage;
use super::types::*;

{% for command in feature_set.commands %}
#[inline] pub unsafe fn {{ command.name|no_prefix }}({{ command|params }}) -> {{ command.proto.ret|type }} { mem::transmute::<_, extern "system" fn({{ command|params('types') }}) -> {{ command.proto.ret|type }}>(storage::{{ command.name|no_prefix }}.ptr)({{ command|params('names') }}) }
{% endfor %}
}

mod storage {
#![allow(non_snake_case, non_upper_case_globals)]

use super::FnPtr;
use std::os::raw;

{% for command in feature_set.commands %}
pub static mut {{ command.name|no_prefix }}: FnPtr = FnPtr { ptr: FnPtr::not_initialized as *const raw::c_void };
{% endfor %}
}

pub fn load<F>(mut loadfn: F) where F: FnMut(&'static str) -> *const raw::c_void {
unsafe {
{% for command in feature_set.commands %}
storage::{{ command.name | no_prefix }}.load(&mut loadfn, "{{ command.name }}");
{% endfor %}
}
}
2 changes: 1 addition & 1 deletion glad/generator/rust/templates/lib.rs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
pub mod gl;
pub mod {{ feature_set.name }};
Loading

0 comments on commit 864addb

Please sign in to comment.