Skip to content

Commit 8a4ae6c

Browse files
authored
Remove OneTimeCallback and add interface builder methods in C. (#51)
* Remove OneTimeCallback and added interface builder methods in C. Fix #48 * Fix linting errors introduced in Rust 1.52 beta.
1 parent b5511fd commit 8a4ae6c

File tree

32 files changed

+173
-1212
lines changed

32 files changed

+173
-1212
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ jobs:
1515
rust:
1616
- stable
1717
- beta
18-
- nightly
1918
runs-on: ${{ matrix.os }}
2019
steps:
2120
- name: Checkout
@@ -100,7 +99,7 @@ jobs:
10099
- name: Build
101100
uses: actions-rs/cargo@v1
102101
with:
103-
command: test
102+
command: build
104103
args: --release
105104
- name: C bindings
106105
uses: actions-rs/cargo@v1

generators/c-oo-bindgen/src/doc.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -124,18 +124,6 @@ fn reference_print(
124124
callback_name.to_snake_case()
125125
))?;
126126
}
127-
DocReference::OneTimeCallback(interface_name) => {
128-
let handle = lib.find_one_time_callback(interface_name).unwrap();
129-
f.write(&format!("@ref {}", handle.to_c_type()))?;
130-
}
131-
DocReference::OneTimeCallbackMethod(interface_name, callback_name) => {
132-
let handle = &lib.find_one_time_callback(interface_name).unwrap();
133-
f.write(&format!(
134-
"@ref {}.{}",
135-
handle.to_c_type(),
136-
callback_name.to_snake_case()
137-
))?;
138-
}
139127
}
140128

141129
Ok(())

generators/c-oo-bindgen/src/lib.rs

Lines changed: 85 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,6 @@ impl CFormatting for Interface {
100100
}
101101
}
102102

103-
impl CFormatting for OneTimeCallbackHandle {
104-
fn to_c_type(&self) -> String {
105-
format!("{}_t", self.name.to_snake_case())
106-
}
107-
}
108-
109103
impl CFormatting for Symbol {
110104
fn to_c_type(&self) -> String {
111105
match self {
@@ -115,7 +109,6 @@ impl CFormatting for Symbol {
115109
Symbol::Class(handle) => handle.declaration().to_c_type(),
116110
Symbol::StaticClass(_) => panic!("static classes cannot be referenced in C"),
117111
Symbol::Interface(handle) => handle.to_c_type(),
118-
Symbol::OneTimeCallback(handle) => handle.to_c_type(),
119112
Symbol::Iterator(handle) => handle.iter_type.to_c_type(),
120113
Symbol::Collection(handle) => handle.collection_type.to_c_type(),
121114
}
@@ -181,6 +174,7 @@ pub fn generate_doxygen(lib: &Library, config: &CBindgenConfig) -> FormattingRes
181174
.unwrap();
182175
stdin.write_all(b"HTML_OUTPUT = doc\n").unwrap();
183176
stdin.write_all(b"GENERATE_LATEX = NO\n").unwrap();
177+
stdin.write_all(b"EXTRACT_STATIC = YES\n").unwrap();
184178
stdin.write_all(b"INPUT = include\n").unwrap();
185179
}
186180

@@ -260,9 +254,6 @@ fn generate_c_header<P: AsRef<Path>>(lib: &Library, path: P) -> FormattingResult
260254
Statement::ClassDeclaration(handle) => write_class_declaration(f, handle, lib)?,
261255
Statement::NativeFunctionDeclaration(handle) => write_function(f, handle, lib)?,
262256
Statement::InterfaceDefinition(handle) => write_interface(f, handle, lib)?,
263-
Statement::OneTimeCallbackDefinition(handle) => {
264-
write_one_time_callback(f, handle, lib)?
265-
}
266257
_ => (),
267258
}
268259
f.newline()?;
@@ -340,7 +331,6 @@ fn write_struct_definition(
340331
}),
341332
StructElementType::ClassRef(_) => None,
342333
StructElementType::Interface(_) => None,
343-
StructElementType::OneTimeCallback(_) => None,
344334
StructElementType::Iterator(_) => None,
345335
StructElementType::Collection(_) => None,
346336
StructElementType::Duration(mapping, default) => {
@@ -476,7 +466,6 @@ fn write_struct_initializer(
476466
},
477467
StructElementType::ClassRef(_) => el.name.to_snake_case(),
478468
StructElementType::Interface(_) => el.name.to_snake_case(),
479-
StructElementType::OneTimeCallback(_) => el.name.to_snake_case(),
480469
StructElementType::Iterator(_) => el.name.to_snake_case(),
481470
StructElementType::Collection(_) => el.name.to_snake_case(),
482471
StructElementType::Duration(mapping, default) => match default {
@@ -681,7 +670,9 @@ fn write_function(
681670
fn write_interface(f: &mut dyn Printer, handle: &Interface, lib: &Library) -> FormattingResult<()> {
682671
doxygen(f, |f| doxygen_print(f, &handle.doc, lib))?;
683672

684-
f.writeln(&format!("typedef struct {}", handle.to_c_type()))?;
673+
let struct_name = handle.to_c_type();
674+
675+
f.writeln(&format!("typedef struct {}", struct_name))?;
685676
f.writeln("{")?;
686677
indented(f, |f| {
687678
for element in &handle.elements {
@@ -748,7 +739,7 @@ fn write_interface(f: &mut dyn Printer, handle: &Interface, lib: &Library) -> Fo
748739
}
749740
InterfaceElement::DestroyFunction(name) => {
750741
doxygen(f, |f| {
751-
f.writeln("@brief Callback when the underlying owner doesn't need the callback anymore")?;
742+
f.writeln("@brief Callback when the underlying owner doesn't need the interface anymore")?;
752743
f.writeln("@param arg Context data")
753744
})?;
754745
f.writeln(&format!("void (*{})(void* arg);", name))?;
@@ -757,60 +748,47 @@ fn write_interface(f: &mut dyn Printer, handle: &Interface, lib: &Library) -> Fo
757748
}
758749
Ok(())
759750
})?;
760-
f.writeln(&format!("}} {};", handle.to_c_type()))
761-
}
751+
f.writeln(&format!("}} {};", struct_name))?;
762752

763-
fn write_one_time_callback(
764-
f: &mut dyn Printer,
765-
handle: &OneTimeCallbackHandle,
766-
lib: &Library,
767-
) -> FormattingResult<()> {
768-
doxygen(f, |f| doxygen_print(f, &handle.doc, lib))?;
753+
f.newline()?;
769754

770-
f.writeln(&format!("typedef struct {}", handle.to_c_type()))?;
771-
f.writeln("{")?;
772-
indented(f, |f| {
755+
// Write init helper
756+
doxygen(f, |f| {
757+
f.writeln("@brief ")?;
758+
docstring_print(
759+
f,
760+
&format!("Initialize a {{interface:{}}} interface", handle.name).into(),
761+
lib,
762+
)?;
773763
for element in &handle.elements {
774764
match element {
775-
OneTimeCallbackElement::Arg(name) => {
776-
doxygen(f, |f| f.writeln("@brief Context data"))?;
777-
f.writeln(&format!("void* {};", name))?
765+
InterfaceElement::Arg(name) => {
766+
f.writeln(&format!("@param {} Context data", name.to_snake_case()))?;
778767
}
779-
OneTimeCallbackElement::CallbackFunction(handle) => {
780-
f.newline()?;
781-
782-
// Print the documentation
783-
doxygen(f, |f| {
784-
// Print top-level documentation
785-
doxygen_print(f, &handle.doc, lib)?;
786-
787-
// Print each parameter value
788-
for param in &handle.parameters {
789-
match param {
790-
CallbackParameter::Arg(name) => {
791-
f.writeln(&format!("@param {} ", name))?;
792-
docstring_print(f, &"Context data".into(), lib)?;
793-
}
794-
CallbackParameter::Parameter(param) => {
795-
f.writeln(&format!("@param {} ", param.name))?;
796-
docstring_print(f, &param.doc, lib)?;
797-
}
798-
}
799-
}
800-
801-
// Print return documentation
802-
if let ReturnType::Type(_, doc) = &handle.return_type {
803-
f.writeln("@return ")?;
804-
docstring_print(f, doc, lib)?;
805-
}
806-
807-
Ok(())
808-
})?;
809-
810-
f.newline()?;
811-
812-
// Print function signature
813-
f.write(&format!(
768+
InterfaceElement::CallbackFunction(handle) => {
769+
f.writeln(&format!("@param {} ", handle.name.to_snake_case()))?;
770+
docstring_print(f, &handle.doc.brief, lib)?;
771+
}
772+
InterfaceElement::DestroyFunction(name) => {
773+
f.writeln(&format!("@param {} Callback when the underlying owner doesn't need the interface anymore", name.to_snake_case()))?;
774+
}
775+
}
776+
}
777+
Ok(())
778+
})?;
779+
f.writeln(&format!(
780+
"static {} {}_init(",
781+
struct_name,
782+
handle.name.to_snake_case()
783+
))?;
784+
indented(f, |f| {
785+
for (idx, element) in handle.elements.iter().enumerate() {
786+
match element {
787+
InterfaceElement::Arg(name) => {
788+
f.writeln(&format!("void* {}", name.to_snake_case()))?;
789+
}
790+
InterfaceElement::CallbackFunction(handle) => {
791+
f.writeln(&format!(
814792
"{} (*{})(",
815793
CReturnType(&handle.return_type),
816794
handle.name.to_snake_case(),
@@ -829,14 +807,55 @@ fn write_one_time_callback(
829807
.collect::<Vec<String>>()
830808
.join(", "),
831809
)?;
832-
833-
f.write(");")?;
810+
f.write(")")?;
834811
}
812+
InterfaceElement::DestroyFunction(name) => {
813+
f.writeln(&format!("void (*{})(void* arg)", name))?;
814+
}
815+
}
816+
if idx + 1 < handle.elements.len() {
817+
f.write(",")?;
835818
}
836819
}
837820
Ok(())
838821
})?;
839-
f.writeln(&format!("}} {};", handle.to_c_type()))
822+
f.writeln(")")?;
823+
824+
blocked(f, |f| {
825+
f.writeln(&format!("{} result = ", struct_name))?;
826+
blocked(f, |f| {
827+
for element in &handle.elements {
828+
match element {
829+
InterfaceElement::Arg(name) => {
830+
f.writeln(&format!(
831+
".{} = {},",
832+
name.to_snake_case(),
833+
name.to_snake_case()
834+
))?;
835+
}
836+
InterfaceElement::CallbackFunction(handle) => {
837+
f.writeln(&format!(
838+
".{} = {},",
839+
handle.name.to_snake_case(),
840+
handle.name.to_snake_case()
841+
))?;
842+
}
843+
InterfaceElement::DestroyFunction(name) => {
844+
f.writeln(&format!(
845+
".{} = {},",
846+
name.to_snake_case(),
847+
name.to_snake_case()
848+
))?;
849+
}
850+
}
851+
}
852+
Ok(())
853+
})?;
854+
f.write(";")?;
855+
f.writeln("return result;")
856+
})?;
857+
858+
Ok(())
840859
}
841860

842861
fn generate_cmake_config(lib: &Library, config: &CBindgenConfig) -> FormattingResult<()> {
@@ -968,7 +987,6 @@ impl<'a> Display for CType<'a> {
968987
Type::Enum(handle) => write!(f, "{}", handle.to_c_type()),
969988
Type::ClassRef(handle) => write!(f, "{}*", handle.to_c_type()),
970989
Type::Interface(handle) => write!(f, "{}", handle.to_c_type()),
971-
Type::OneTimeCallback(handle) => write!(f, "{}", handle.to_c_type()),
972990
Type::Iterator(handle) => write!(f, "{}*", handle.iter_type.to_c_type()),
973991
Type::Collection(handle) => write!(f, "{}*", handle.collection_type.to_c_type()),
974992
Type::Duration(mapping) => match mapping {

0 commit comments

Comments
 (0)