Skip to content

Instantly share code, notes, and snippets.

@sakex
Last active June 23, 2020 18:23
Show Gist options
  • Save sakex/e8f069347a5f25cae740b7025597a544 to your computer and use it in GitHub Desktop.
Save sakex/e8f069347a5f25cae740b7025597a544 to your computer and use it in GitHub Desktop.
// src/engine.rs
use std::ffi::c_void;
use std::os::raw::c_char;
use crate::bindings::{engine_factory, register_button, AbstractButtonBinding};
use crate::Button;
pub struct Engine {
ptr: *mut c_void
}
impl Engine {
pub fn new() -> Engine {
unsafe {
Engine {
ptr: engine_factory()
}
}
}
pub fn register_button<T>(&mut self, button: Box<T>)
where T: Button {
unsafe extern "C" fn click<T>(context: *mut T)
where T: Button {
let button_ref: &mut T = &mut *context;
button_ref.click();
}
unsafe extern "C" fn inner_text<T>(context: *mut T) -> *const c_char
where T: Button {
let button_ref: &mut T = &mut *context;
let text: String = button_ref.inner_text();
let c_string = text.as_ptr() as *const c_char;
std::mem::forget(text);
c_string
}
let context: *mut T = Box::into_raw(button);
let binding: Box<AbstractButtonBinding<T>> = Box::new(AbstractButtonBinding {
click,
inner_text,
context,
});
let binding_ptr: *mut c_void = Box::into_raw(binding) as *mut c_void;
unsafe { register_button(self.ptr as *mut c_void, binding_ptr); }
}
}
impl Drop for Engine {
fn drop(&mut self) {
// This would not call GUI::~Engine, you should write a wrapper around delete ptr; in C++
unsafe { libc::free(self.ptr); }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment