+extern "C" fn destroy_boxed<T>(data: *mut c_void) {
+ if data.is_null() {
+ return;
+ }
+ unsafe {
+ drop(Box::from_raw(data as *mut T));
+ }
+}
+
+pub struct UiDoc {
+ pub ctx: UiContext,
+ ptr: *mut c_void
+}
+
+impl Clone for UiDoc {
+ fn clone(&self) -> Self {
+ unsafe {
+ ui_document_ref(self.ptr);
+ }
+ UiDoc {
+ ctx: self.ctx.clone(),
+ ptr: self.ptr
+ }
+ }
+}
+
+impl Drop for UiDoc {
+ fn drop(&mut self) {
+ unsafe {
+ if !self.ptr.is_null() {
+ ui_document_unref(self.ptr);
+ }
+ }
+ }
+}
+
+impl UiDoc {
+ pub fn new<T: UiModel>(mut data: T) -> UiDoc {
+ unsafe {
+ let doc = ui_document_new(mem::size_of::<*mut T>());
+ let mut ctx = UiContext { ptr: ui_document_context(doc) };
+ data.init(&ctx);
+ let data_ptr = ctx.reg_box(Box::new(data)); // returns *mut T
+ let doc_storage: *mut *mut T = doc.cast();
+ *doc_storage = data_ptr;
+ UiDoc { ctx: ctx, ptr: doc }
+ }
+ }
+}
+