From 1f65184deb0cca1c1cb160d20f3abf2598d1a919 Mon Sep 17 00:00:00 2001 From: Jack Mac Date: Fri, 1 Oct 2021 12:33:36 -0400 Subject: [PATCH] borked the lifetime, simplified here --- imgui/src/context.rs | 22 +++---- imgui/src/fonts/atlas.rs | 134 ++++++++++++++++++++++----------------- 2 files changed, 86 insertions(+), 70 deletions(-) diff --git a/imgui/src/context.rs b/imgui/src/context.rs index c1a891e..95c971e 100644 --- a/imgui/src/context.rs +++ b/imgui/src/context.rs @@ -49,7 +49,7 @@ use crate::{sys, DrawData}; #[derive(Debug)] pub struct Context { raw: *mut sys::ImGuiContext, - shared_font_atlas: Option>, + shared_font_atlas: Option, ini_filename: Option, log_filename: Option, platform_name: Option, @@ -93,7 +93,7 @@ impl Context { /// /// Panics if an active context already exists #[doc(alias = "CreateContext")] - pub fn create_with_shared_font_atlas(shared_font_atlas: UnsafeCell) -> Self { + pub fn create_with_shared_font_atlas(shared_font_atlas: SharedFontAtlas) -> Self { Self::create_internal(Some(shared_font_atlas)) } /// Suspends this context so another context can be the active context. @@ -216,18 +216,15 @@ impl Context { io.clipboard_user_data = clipboard_ctx.get() as *mut _; self.clipboard_ctx = clipboard_ctx; } - fn create_internal(shared_font_atlas: Option>) -> Self { + fn create_internal(mut shared_font_atlas: Option) -> Self { let _guard = CTX_MUTEX.lock(); assert!( no_current_context(), "A new active context cannot be created, because another one already exists" ); - let shared_font_atlas_ptr = match &shared_font_atlas { - Some(shared_font_atlas) => { - let borrowed_font_atlas = shared_font_atlas.get(); - unsafe { &*borrowed_font_atlas }.0 - } + let shared_font_atlas_ptr = match &mut shared_font_atlas { + Some(shared_font_atlas) => shared_font_atlas.as_ptr_mut(), None => ptr::null_mut(), }; // Dear ImGui implicitly sets the current context during igCreateContext if the current @@ -297,8 +294,9 @@ impl SuspendedContext { pub fn create() -> Self { Self::create_internal(None) } + /// Creates a new suspended imgui-rs context with a shared font atlas. - pub fn create_with_shared_font_atlas(shared_font_atlas: UnsafeCell) -> Self { + pub fn create_with_shared_font_atlas(shared_font_atlas: SharedFontAtlas) -> Self { Self::create_internal(Some(shared_font_atlas)) } /// Attempts to activate this suspended context. @@ -319,7 +317,7 @@ impl SuspendedContext { Err(self) } } - fn create_internal(shared_font_atlas: Option>) -> Self { + fn create_internal(shared_font_atlas: Option) -> Self { let _guard = CTX_MUTEX.lock(); let raw = unsafe { sys::igCreateContext(ptr::null_mut()) }; let ctx = Context { @@ -415,8 +413,8 @@ fn test_suspend_failure() { fn test_shared_font_atlas() { let _guard = crate::test::TEST_MUTEX.lock(); let atlas = SharedFontAtlas::create(); - let suspended1 = SuspendedContext::create_with_shared_font_atlas(atlas.clone().into()); - let mut ctx2 = Context::create_with_shared_font_atlas(atlas.into()); + let suspended1 = SuspendedContext::create_with_shared_font_atlas(atlas.clone()); + let mut ctx2 = Context::create_with_shared_font_atlas(atlas); { let _borrow = ctx2.fonts(); } diff --git a/imgui/src/fonts/atlas.rs b/imgui/src/fonts/atlas.rs index e1a8152..a3f438b 100644 --- a/imgui/src/fonts/atlas.rs +++ b/imgui/src/fonts/atlas.rs @@ -1,9 +1,8 @@ use bitflags::bitflags; -use std::cell; use std::f32; -use std::ops::{Deref, DerefMut}; use std::os::raw::{c_int, c_uchar, c_void}; use std::ptr; +use std::rc::Rc; use std::slice; use crate::fonts::font::Font; @@ -434,75 +433,94 @@ pub struct FontAtlasTexture<'a> { /// A font atlas that can be shared between contexts #[derive(Debug, Clone)] -pub struct SharedFontAtlas(pub(crate) *mut sys::ImFontAtlas); +pub struct SharedFontAtlas(pub(crate) Rc<*mut sys::ImFontAtlas>); + +impl std::ops::Deref for SharedFontAtlas { + type Target = Rc<*mut sys::ImFontAtlas>; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl std::ops::DerefMut for SharedFontAtlas { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} impl SharedFontAtlas { #[doc(alias = "ImFontAtlas", alias = "ImFontAtlas::ImFontAtlas")] pub fn create() -> SharedFontAtlas { - SharedFontAtlas(unsafe { sys::ImFontAtlas_ImFontAtlas() }) + SharedFontAtlas(unsafe { Rc::new(sys::ImFontAtlas_ImFontAtlas()) }) + } + + /// Gets a raw pointer to the underlying `ImFontAtlas`. + pub fn as_ptr(&self) -> *const sys::ImFontAtlas { + *self.0 as *const _ + } + + /// Gets a raw pointer to the underlying `ImFontAtlas`. + pub fn as_ptr_mut(&mut self) -> *mut sys::ImFontAtlas { + *self.0 } } impl Drop for SharedFontAtlas { #[doc(alias = "ImFontAtlas::Destory")] fn drop(&mut self) { - unsafe { sys::ImFontAtlas_destroy(self.0) }; - } -} - -impl Deref for SharedFontAtlas { - type Target = FontAtlas; - fn deref(&self) -> &FontAtlas { - unsafe { &*(self.0 as *const FontAtlas) } - } -} - -impl DerefMut for SharedFontAtlas { - fn deref_mut(&mut self) -> &mut FontAtlas { - unsafe { &mut *(self.0 as *mut FontAtlas) } - } -} - -/// An immutably borrowed reference to a (possibly shared) font atlas -pub enum FontAtlasRef<'a> { - Owned(&'a FontAtlas), - Shared(&'a cell::RefMut<'a, SharedFontAtlas>), -} - -impl<'a> Deref for FontAtlasRef<'a> { - type Target = FontAtlas; - fn deref(&self) -> &FontAtlas { - use self::FontAtlasRef::*; - match self { - Owned(atlas) => atlas, - Shared(cell) => cell, + // if we're about to drop the last one... + if Rc::strong_count(&self.0) == 1 { + unsafe { sys::ImFontAtlas_destroy(*self.0) }; } } } -/// A mutably borrowed reference to a (possibly shared) font atlas -pub enum FontAtlasRefMut<'a> { - Owned(&'a mut FontAtlas), - Shared(cell::RefMut<'a, SharedFontAtlas>), -} +// /// An immutably borrowed reference to a (possibly shared) font atlas +// pub enum FontAtlasRef<'a> { +// Owned(&'a FontAtlas), +// Shared(&'a cell::RefMut<'a, SharedFontAtlas>), +// } -impl<'a> Deref for FontAtlasRefMut<'a> { - type Target = FontAtlas; - fn deref(&self) -> &FontAtlas { - use self::FontAtlasRefMut::*; - match self { - Owned(atlas) => atlas, - Shared(cell) => cell, - } - } -} +// impl<'a> Deref for FontAtlasRef<'a> { +// type Target = FontAtlas; +// fn deref(&self) -> &FontAtlas { +// use self::FontAtlasRef::*; +// match self { +// Owned(atlas) => atlas, +// Shared(cell) => { +// let font_atlas: &SharedFontAtlas = &cell; +// let font_atlas: &FontAtlas = &font_atlas; -impl<'a> DerefMut for FontAtlasRefMut<'a> { - fn deref_mut(&mut self) -> &mut FontAtlas { - use self::FontAtlasRefMut::*; - match self { - Owned(atlas) => atlas, - Shared(cell) => cell, - } - } -} +// todo!() +// } +// } +// } +// } + +// /// A mutably borrowed reference to a (possibly shared) font atlas +// pub enum FontAtlasRefMut<'a> { +// Owned(&'a mut FontAtlas), +// Shared(cell::RefMut<'a, SharedFontAtlas>), +// } + +// impl<'a> Deref for FontAtlasRefMut<'a> { +// type Target = FontAtlas; +// fn deref(&self) -> &FontAtlas { +// use self::FontAtlasRefMut::*; +// match self { +// Owned(atlas) => atlas, +// Shared(cell) => cell, +// } +// } +// } + +// impl<'a> DerefMut for FontAtlasRefMut<'a> { +// fn deref_mut(&mut self) -> &mut FontAtlas { +// use self::FontAtlasRefMut::*; +// match self { +// Owned(atlas) => atlas, +// Shared(cell) => cell, +// } +// } +// }