mirror of
https://github.com/doukutsu-rs/doukutsu-rs
synced 2024-11-21 13:12:45 +00:00
Don't do unsafe stupidity to handle imgui::Context
This commit is contained in:
parent
fb87b3d5ab
commit
86747e0230
|
@ -51,7 +51,7 @@ exe = []
|
|||
android = []
|
||||
|
||||
[dependencies]
|
||||
glutin = { path = "./3rdparty/glutin/glutin", optional = true }
|
||||
#glutin = { path = "./3rdparty/glutin/glutin", optional = true }
|
||||
#winit = { path = "./3rdparty/winit", optional = true, default_features = false, features = ["x11"] }
|
||||
#sdl2 = { path = "./3rdparty/rust-sdl2", optional = true, features = ["unsafe_textures", "bundled", "static-link"] }
|
||||
#sdl2-sys = { path = "./3rdparty/rust-sdl2/sdl2-sys", optional = true, features = ["bundled", "static-link"] }
|
||||
|
@ -66,7 +66,7 @@ discord-rich-presence = { version = "0.2", optional = true }
|
|||
downcast = "0.11"
|
||||
encoding_rs = "0.8.33"
|
||||
fern = "0.6.2"
|
||||
#glutin = { git = "https://github.com/doukutsu-rs/glutin.git", rev = "2dd95f042e6e090d36f577cbea125560dd99bd27", optional = true, default_features = false, features = ["x11"] }
|
||||
glutin = { version = "0.32.0", optional = true }
|
||||
imgui = { git = "https://github.com/imgui-rs/imgui-rs.git", rev = "67f7f11363e62f09aa0e1288a17800e505860486" }
|
||||
image = { version = "0.24", default-features = false, features = ["png", "bmp"] }
|
||||
itertools = "0.10"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use std::any::Any;
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use imgui::DrawData;
|
||||
|
@ -82,8 +83,8 @@ pub trait BackendRenderer {
|
|||
/// Set the current clipping rectangle.
|
||||
fn set_clip_rect(&mut self, rect: Option<Rect>) -> GameResult;
|
||||
|
||||
/// Get a mutable reference to the imgui context.
|
||||
fn imgui(&self) -> GameResult<&mut imgui::Context>;
|
||||
/// Get a reference to the imgui context.
|
||||
fn imgui(&self) -> GameResult<Rc<RefCell<imgui::Context>>>;
|
||||
|
||||
/// Get an imgui texture id for the specified texture.
|
||||
fn imgui_texture_id(&self, texture: &Box<dyn BackendTexture>) -> GameResult<imgui::TextureId>;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::any::Any;
|
||||
use std::cell::RefCell;
|
||||
use std::mem;
|
||||
use std::rc::Rc;
|
||||
|
||||
use imgui::{DrawData, TextureId, Ui};
|
||||
|
||||
|
@ -25,7 +26,7 @@ impl Backend for NullBackend {
|
|||
fn create_event_loop(&self, _ctx: &Context) -> GameResult<Box<dyn BackendEventLoop>> {
|
||||
Ok(Box::new(NullEventLoop))
|
||||
}
|
||||
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
@ -53,10 +54,7 @@ impl BackendEventLoop for NullEventLoop {
|
|||
|
||||
fn new_renderer(&self) -> GameResult<Box<dyn BackendRenderer>> {
|
||||
let mut imgui = imgui::Context::create();
|
||||
imgui.io_mut().display_size = [640.0, 480.0];
|
||||
imgui.fonts().build_alpha8_texture();
|
||||
|
||||
Ok(Box::new(NullRenderer(RefCell::new(imgui))))
|
||||
NullRenderer::new(imgui)
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
|
@ -84,12 +82,12 @@ impl BackendTexture for NullTexture {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct NullRenderer(RefCell<imgui::Context>);
|
||||
pub struct NullRenderer(Rc<RefCell<imgui::Context>>);
|
||||
|
||||
impl NullRenderer {
|
||||
pub fn new(mut imgui: imgui::Context) -> Self {
|
||||
pub fn new(mut imgui: imgui::Context) -> GameResult<Box<dyn BackendRenderer>> {
|
||||
let _ = imgui.fonts().build_alpha8_texture();
|
||||
NullRenderer(RefCell::new(imgui))
|
||||
Ok(Box::new(NullRenderer(Rc::new(RefCell::new(imgui)))))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,8 +130,8 @@ impl BackendRenderer for NullRenderer {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn imgui(&self) -> GameResult<&mut imgui::Context> {
|
||||
unsafe { Ok(&mut *self.0.as_ptr()) }
|
||||
fn imgui(&self) -> GameResult<Rc<RefCell<imgui::Context>>> {
|
||||
Ok(self.0.clone())
|
||||
}
|
||||
|
||||
fn imgui_texture_id(&self, _texture: &Box<dyn BackendTexture>) -> GameResult<TextureId> {
|
||||
|
|
|
@ -44,6 +44,8 @@ use crate::game::shared_game_state::WindowMode;
|
|||
use crate::game::Game;
|
||||
use crate::game::GAME_SUSPENDED;
|
||||
|
||||
use super::graphics;
|
||||
|
||||
pub struct SDL2Backend {
|
||||
context: Sdl,
|
||||
size_hint: (u16, u16),
|
||||
|
@ -315,37 +317,39 @@ impl SDL2EventLoop {
|
|||
let gl_context: GLContext = GLContext { gles2_mode: false, platform };
|
||||
|
||||
let imgui = Self::create_imgui()?;
|
||||
|
||||
OpenGLRenderer::new(gl_context, imgui)
|
||||
}
|
||||
|
||||
fn try_create_sdl2_renderer(&self) -> GameResult<Box<dyn BackendRenderer>> {
|
||||
let imgui = Self::create_imgui()?;
|
||||
|
||||
fn try_create_sdl2_renderer(&self) -> GameResult<Box<dyn BackendRenderer>> {
|
||||
let mut refs = self.refs.borrow_mut();
|
||||
let window = std::mem::take(&mut refs.window);
|
||||
refs.window = window.make_canvas()?;
|
||||
|
||||
let imgui = Self::create_imgui()?;
|
||||
SDL2Renderer::new(self.refs.clone(), imgui)
|
||||
}
|
||||
}
|
||||
|
||||
impl BackendEventLoop for SDL2EventLoop {
|
||||
fn run(&mut self, game: &mut Game, ctx: &mut Context) {
|
||||
let imgui = unsafe { (&*(ctx.renderer.as_ref().unwrap() as *const Box<dyn BackendRenderer>)).imgui().unwrap() };
|
||||
let mut imgui_sdl2 = ImguiSdl2::new(imgui, self.refs.deref().borrow().window.window());
|
||||
let imgui = graphics::imgui_context(ctx).unwrap();
|
||||
let mut imgui_sdl2 = ImguiSdl2::new(&mut imgui.borrow_mut(), self.refs.deref().borrow().window.window());
|
||||
|
||||
{
|
||||
let state = game.state.get_mut();
|
||||
let (width, height) = self.refs.deref().borrow().window.window().size();
|
||||
ctx.screen_size = (width.max(1) as f32, height.max(1) as f32);
|
||||
|
||||
imgui.io_mut().display_size = [ctx.screen_size.0, ctx.screen_size.1];
|
||||
imgui.borrow_mut().io_mut().display_size = [ctx.screen_size.0, ctx.screen_size.1];
|
||||
let _ = state.handle_resize(ctx);
|
||||
}
|
||||
|
||||
loop {
|
||||
for event in self.event_pump.poll_iter() {
|
||||
imgui_sdl2.handle_event(imgui, &event);
|
||||
imgui_sdl2.handle_event(&mut imgui.borrow_mut(), &event);
|
||||
|
||||
match event {
|
||||
Event::Quit { .. } => {
|
||||
|
@ -377,11 +381,7 @@ impl BackendEventLoop for SDL2EventLoop {
|
|||
let state = game.state.get_mut();
|
||||
ctx.screen_size = (width.max(1) as f32, height.max(1) as f32);
|
||||
|
||||
if let Some(renderer) = &ctx.renderer {
|
||||
if let Ok(imgui) = renderer.imgui() {
|
||||
imgui.io_mut().display_size = [ctx.screen_size.0, ctx.screen_size.1];
|
||||
}
|
||||
}
|
||||
imgui.borrow_mut().io_mut().display_size = [ctx.screen_size.0, ctx.screen_size.1];
|
||||
state.handle_resize(ctx).unwrap();
|
||||
}
|
||||
_ => {}
|
||||
|
@ -504,7 +504,7 @@ impl BackendEventLoop for SDL2EventLoop {
|
|||
game.update(ctx).unwrap();
|
||||
|
||||
imgui_sdl2.prepare_frame(
|
||||
imgui.io_mut(),
|
||||
imgui.borrow_mut().io_mut(),
|
||||
self.refs.deref().borrow().window.window(),
|
||||
&self.event_pump.mouse_state(),
|
||||
);
|
||||
|
@ -879,8 +879,8 @@ impl BackendRenderer for SDL2Renderer {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn imgui(&self) -> GameResult<&mut imgui::Context> {
|
||||
unsafe { Ok(&mut *self.imgui.as_ptr()) }
|
||||
fn imgui(&self) -> GameResult<Rc<RefCell<imgui::Context>>> {
|
||||
Ok(self.imgui.clone())
|
||||
}
|
||||
|
||||
fn imgui_texture_id(&self, texture: &Box<dyn BackendTexture>) -> GameResult<TextureId> {
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::common::{Color, Rect};
|
||||
use crate::framework::backend::{BackendShader, BackendTexture, VertexData};
|
||||
use crate::framework::context::Context;
|
||||
|
@ -130,7 +133,7 @@ pub fn set_clip_rect(ctx: &mut Context, rect: Option<Rect>) -> GameResult {
|
|||
Err(GameError::RenderError("Rendering backend hasn't been initialized yet.".to_string()))
|
||||
}
|
||||
|
||||
pub fn imgui_context(ctx: &Context) -> GameResult<&mut imgui::Context> {
|
||||
pub fn imgui_context(ctx: &Context) -> GameResult<Rc<RefCell<imgui::Context>>> {
|
||||
if let Some(renderer) = ctx.renderer.as_ref() {
|
||||
return renderer.imgui();
|
||||
}
|
||||
|
|
|
@ -662,7 +662,7 @@ pub fn load_gl(gl_context: &GLContext) -> Rc<Gl> {
|
|||
pub struct OpenGLRenderer {
|
||||
refs: GLContext,
|
||||
gl: Rc<Gl>,
|
||||
imgui: UnsafeCell<imgui::Context>,
|
||||
imgui: Rc<RefCell<imgui::Context>>,
|
||||
render_data: RenderData,
|
||||
def_matrix: [[f32; 4]; 4],
|
||||
curr_matrix: [[f32; 4]; 4],
|
||||
|
@ -683,7 +683,7 @@ impl OpenGLRenderer {
|
|||
Ok(Box::new(OpenGLRenderer {
|
||||
refs,
|
||||
gl,
|
||||
imgui: UnsafeCell::new(imgui),
|
||||
imgui: Rc::new(RefCell::new(imgui)),
|
||||
render_data,
|
||||
def_matrix: [[0.0; 4]; 4],
|
||||
curr_matrix: [[0.0; 4]; 4],
|
||||
|
@ -1059,8 +1059,8 @@ impl BackendRenderer for OpenGLRenderer {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn imgui(&self) -> GameResult<&mut imgui::Context> {
|
||||
unsafe { Ok(&mut *self.imgui.get()) }
|
||||
fn imgui(&self) -> GameResult<Rc<RefCell<imgui::Context>>> {
|
||||
Ok(self.imgui.clone())
|
||||
}
|
||||
|
||||
fn imgui_texture_id(&self, texture: &Box<dyn BackendTexture>) -> GameResult<TextureId> {
|
||||
|
@ -1090,8 +1090,8 @@ impl BackendRenderer for OpenGLRenderer {
|
|||
gl.gl.Enable(gl::SCISSOR_TEST);
|
||||
|
||||
let imgui = self.imgui()?;
|
||||
let [width, height] = imgui.io().display_size;
|
||||
let [scale_w, scale_h] = imgui.io().display_framebuffer_scale;
|
||||
let [width, height] = imgui.borrow().io().display_size;
|
||||
let [scale_w, scale_h] = imgui.borrow().io().display_framebuffer_scale;
|
||||
|
||||
let fb_width = width * scale_w;
|
||||
let fb_height = height * scale_h;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::time::Instant;
|
||||
|
||||
use imgui::{FontConfig, FontSource};
|
||||
use imgui::sys::*;
|
||||
use imgui::{FontConfig, FontSource};
|
||||
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameResult;
|
||||
|
@ -108,19 +108,20 @@ impl UI {
|
|||
}
|
||||
|
||||
pub fn draw(&mut self, state: &mut SharedGameState, ctx: &mut Context, scene: &mut Box<dyn Scene>) -> GameResult {
|
||||
let ctx2 = unsafe { &mut *(ctx as *const Context as *mut Context) };
|
||||
let imgui = imgui_context(ctx)?;
|
||||
let mut imgui = imgui.borrow_mut();
|
||||
|
||||
let now = Instant::now();
|
||||
imgui.io_mut().update_delta_time(now - self.last_frame);
|
||||
self.last_frame = now;
|
||||
|
||||
let mut ui = imgui.new_frame();
|
||||
|
||||
scene.imgui_draw(&mut self.components, state, ctx2, &mut ui)?;
|
||||
scene.imgui_draw(&mut self.components, state, ctx, &mut ui)?;
|
||||
|
||||
prepare_imgui(ctx2, &ui);
|
||||
prepare_imgui(ctx, &ui);
|
||||
let draw_data = imgui.render();
|
||||
render_imgui(ctx2, draw_data)?;
|
||||
render_imgui(ctx, draw_data)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue