borked the lifetime, simplified here

This commit is contained in:
Jack Mac 2021-10-01 12:33:36 -04:00
parent 76c74fbfc5
commit 1f65184deb
2 changed files with 86 additions and 70 deletions

View File

@ -49,7 +49,7 @@ use crate::{sys, DrawData};
#[derive(Debug)]
pub struct Context {
raw: *mut sys::ImGuiContext,
shared_font_atlas: Option<UnsafeCell<SharedFontAtlas>>,
shared_font_atlas: Option<SharedFontAtlas>,
ini_filename: Option<CString>,
log_filename: Option<CString>,
platform_name: Option<CString>,
@ -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<SharedFontAtlas>) -> 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<UnsafeCell<SharedFontAtlas>>) -> Self {
fn create_internal(mut shared_font_atlas: Option<SharedFontAtlas>) -> 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<SharedFontAtlas>) -> 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<UnsafeCell<SharedFontAtlas>>) -> Self {
fn create_internal(shared_font_atlas: Option<SharedFontAtlas>) -> 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();
}

View File

@ -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,
// }
// }
// }