Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::marker::PhantomData;
- use std::ptr;
- use std::os::raw::c_void;
- use std::mem::transmute;
- unsafe extern "C" fn connect<T>(user_data: *const c_void, func: *const c_void) {
- let f: &&(Fn(&mut T) + 'static) = transmute(func);
- let data = user_data as *mut T;
- f(&mut *data);
- }
- #[derive(Default, Debug, Clone)]
- struct Widget<'a> {
- size: (u32, u32),
- _marker: PhantomData<&'a Rute<'a>>,
- }
- impl<'a> Widget<'a> {
- pub fn size(mut self, width: u32, height: u32) -> Widget<'a> {
- self.size = (width, height);
- self
- }
- pub fn on_change<'b: 'a, F, T>(self, data: &'b mut T, func: F) -> Widget<'a>
- where
- F: Fn(&mut T) + 'static
- {
- unsafe {
- let f: Box<Box<Fn(&mut T) + 'static>> = Box::new(Box::new(func));
- let user_data: *const c_void = transmute(data);
- connect::<T>(user_data, Box::into_raw(f) as *const c_void);
- }
- self
- }
- }
- struct CRute;
- struct Rute<'a> {
- _rute_ffi: *const CRute,
- _marker: PhantomData<&'a CRute>,
- }
- impl<'a> Rute<'a> {
- pub fn new() -> Rute<'a> {
- Rute {
- _rute_ffi: ptr::null(),
- _marker: PhantomData,
- }
- }
- pub fn create_widget(&self) -> Widget {
- // NOTE: this will actually call some FFI stuff here
- Widget::default()
- }
- }
- struct MyApp<'a> {
- rute: &'a Rute<'a>,
- some_text: String,
- }
- impl<'a> MyApp<'a> {
- pub fn new(rute: &'a Rute<'a>) -> MyApp<'a> {
- let my_app = MyApp {
- rute: rute,
- some_text: "Foo".to_owned(),
- };
- my_app
- }
- pub fn setup_ui(&mut self) {
- self.rute.create_widget()
- .size(100, 200)
- .on_change(self, |data| {
- println!("callback {}", data.some_text);
- data.some_text = "Sometext".to_owned()
- });
- }
- }
- fn main() {
- let rute = Rute::new();
- let mut app = MyApp::new(&rute);
- app.setup_ui();
- println!("{}", app.some_text)
- }
Add Comment
Please, Sign In to add comment