summaryrefslogtreecommitdiff
path: root/codegen/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'codegen/mod.rs')
-rw-r--r--codegen/mod.rs72
1 files changed, 72 insertions, 0 deletions
diff --git a/codegen/mod.rs b/codegen/mod.rs
new file mode 100644
index 0000000..42dc9dc
--- /dev/null
+++ b/codegen/mod.rs
@@ -0,0 +1,72 @@
+use std::error::Error;
+use std::fs::File;
+use std::io::Write;
+use std::path::Path;
+
+use opengl_registry::api_interface_definition::FeatureKind;
+use opengl_registry::Registry;
+use quote::quote;
+
+use crate::codegen::command::functions::create_command_functions;
+use crate::codegen::command::globals::create_command_globals;
+use crate::codegen::load_with::create_load_with_function;
+
+pub mod bindings;
+
+mod command;
+mod formatting;
+mod load_with;
+
+pub fn generate_using_registry(dest_file: &Path) -> Result<(), Box<dyn Error>>
+{
+ let registry = Registry::retrieve()?;
+
+ let removed_commands = registry
+ .api_interface_definitions()
+ .iter()
+ .flat_map(|api_interface_def| {
+ api_interface_def.removals().iter().flat_map(|removal| {
+ removal.features().iter().filter_map(|feature| {
+ if feature.kind() != FeatureKind::Command {
+ return None;
+ }
+
+ Some(feature.name())
+ })
+ })
+ })
+ .collect::<Vec<_>>();
+
+ let filtered_commands = registry
+ .commands()
+ .iter()
+ .filter(|command| !removed_commands.contains(&command.prototype().name()))
+ .cloned()
+ .collect::<Vec<_>>();
+
+ let command_globals = create_command_globals(&filtered_commands);
+ let command_functions = create_command_functions(&filtered_commands)?;
+ let load_with_function = create_load_with_function(&filtered_commands);
+
+ let tokens = quote! {
+ #(#command_functions)*
+
+ #load_with_function
+
+ mod functions
+ {
+ #(#command_globals)*
+
+ extern "C" fn function_not_loaded()
+ {
+ panic!("OpenGL function not loaded");
+ }
+ }
+ };
+
+ let mut file = File::create(dest_file)?;
+
+ file.write_all(tokens.to_string().as_bytes())?;
+
+ Ok(())
+}