--- /dev/null
+#[allow(unused_imports)]
+
+use std::ffi::{c_char, c_int, c_void, CString};
+use crate::ui::ffi::{UiCallback, UiEvent};
+
+pub trait Application {
+ fn on_startup(&self);
+
+ fn on_exit(&self) { }
+}
+
+
+extern "C" {
+ fn ui_main();
+
+ fn ui_onstartup(callback: UiCallback, userdata: *mut c_void);
+ fn ui_onexit(callback: UiCallback, userdata: *mut c_void);
+}
+
+extern "C" fn app_startup(_event: *const UiEvent, data: *mut c_void) {
+ unsafe {
+ let app_ptr = data as *mut AppWrapper;
+ let app_ref: &mut AppWrapper = &mut *app_ptr;
+ app_ref.app.on_startup();
+ }
+}
+
+extern "C" fn app_exit(_event: *const UiEvent, data: *mut c_void) {
+ unsafe {
+ let app_ptr = data as *mut AppWrapper;
+ let app_ref: &mut AppWrapper = &mut *app_ptr;
+ app_ref.app.on_exit();
+ }
+}
+
+pub fn app_run(app: &mut dyn Application) {
+ let mut wrapper = AppWrapper { app: app };
+ unsafe {
+ let ptr: *mut AppWrapper = &mut wrapper;
+ let c_ptr: *mut c_void = ptr as *mut c_void;
+ ui_onstartup(Some(app_startup), c_ptr);
+ ui_onexit(Some(app_exit), c_ptr);
+ ui_main();
+ }
+}
+
+#[repr(C)]
+struct AppWrapper<'a> {
+ app: &'a mut dyn Application,
+}
\ No newline at end of file
#![allow(dead_code)]
-use std::ffi::{c_char, c_int, c_void, CString};
-use super::ffi::*;
+use std::ffi::{c_char, c_int, CString};
extern "C" {
fn ui_init(appname: *const c_char, argc: c_int, argv: *const *const c_char);
- fn ui_main();
-
- fn ui_onstartup(callback: UiCallback, userdata: *mut c_void);
}
pub fn app_init(appname: &str) {
unsafe {
let c_str = if appname.len() > 0 {
- let s = CString::new(appname).unwrap();
- s.as_ptr()
- } else {
- std::ptr::null()
- };
+ let s = CString::new(appname).unwrap();
+ s.as_ptr()
+ } else {
+ std::ptr::null()
+ };
ui_init(c_str, 0, std::ptr::null());
}
}
-
-pub fn app_main() {
- unsafe {
- ui_main();
- }
-}
-
-pub fn onstartup(callback: UiCallback) {
- unsafe {
- ui_onstartup(callback, std::ptr::null_mut());
- }
-}