Skip to content

Commit fec8172

Browse files
committed
error: Improve error handling
1 parent fe867b8 commit fec8172

File tree

7 files changed

+92
-55
lines changed

7 files changed

+92
-55
lines changed

imgui-renderer-dx11/src/renderer.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use std::marker::PhantomData;
21
use imgui::internal::RawWrapper;
32
use imgui::{DrawCmd, DrawData, DrawIdx, DrawVert};
43
use windows::core::{Result as HResult};
@@ -20,7 +19,7 @@ pub(crate) struct VertexConstantBuffer {
2019
mvp: [[f32; 4]; 4],
2120
}
2221

23-
pub struct RenderToken<'a>(PhantomData<&'a ()>);
22+
pub struct RenderToken;
2423

2524
#[derive(Debug)]
2625
pub struct Renderer {
@@ -75,13 +74,13 @@ impl Renderer {
7574
Ok(())
7675
}
7776

78-
pub fn render<'a>(&mut self, draw_data: &DrawData) -> Result<RenderToken<'a>, RenderError> {
77+
pub fn render(&mut self, draw_data: &DrawData) -> Result<RenderToken, RenderError> {
7978
// Avoid rendering when minimized
8079
if draw_data.display_size[0] <= 0.0
8180
|| draw_data.display_size[1] <= 0.0
8281
|| draw_data.draw_lists_count() == 0
8382
{
84-
return Ok(RenderToken(PhantomData));
83+
return Ok(RenderToken);
8584
}
8685

8786
self.vertex_buffer
@@ -96,7 +95,7 @@ impl Renderer {
9695
self.render_cmd_lists(draw_data);
9796
drop(state)
9897
}
99-
Ok(RenderToken(PhantomData))
98+
Ok(RenderToken)
10099
}
101100

102101
// upload vertex/index data into a single contiguous GPU buffer

imgui-renderer-ogl/src/renderer.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use std::ffi::CStr;
2-
use std::marker::PhantomData;
32
use std::mem;
43
use std::os::raw::c_char;
54

@@ -36,7 +35,7 @@ impl Renderer {
3635
self.0.with_renderer_mut(|r| r.create_device_objects(imgui))
3736
}
3837

39-
pub fn render<'a>(&mut self, draw_data: &DrawData) -> RenderToken<'a> {
38+
pub fn render(&mut self, draw_data: &DrawData) -> RenderToken {
4039
self.0.with_renderer_mut(|r| r.render(draw_data))
4140
}
4241
}
@@ -64,7 +63,7 @@ pub struct RendererInner<'gl> {
6463
#[derive(Debug, Copy, Clone)]
6564
pub struct GlVersion(pub i32);
6665

67-
pub struct RenderToken<'a>(PhantomData<&'a ()>);
66+
pub struct RenderToken;
6867

6968
impl<'gl> RendererInner<'gl> {
7069
fn set_imgui_metadata(imgui: &mut imgui::Context, ver: GlVersion) {
@@ -144,13 +143,13 @@ impl<'gl> RendererInner<'gl> {
144143
Ok(())
145144
}
146145

147-
fn render<'a>(&mut self, draw_data: &DrawData) -> RenderToken<'a> {
146+
fn render(&mut self, draw_data: &DrawData) -> RenderToken {
148147
// Avoid rendering when minimized
149148
let fb_width = draw_data.display_size[0] * draw_data.framebuffer_scale[0];
150149
let fb_height = draw_data.display_size[1] * draw_data.framebuffer_scale[1];
151150

152151
if fb_height <= 0.0 || fb_width <= 0.0 || draw_data.draw_lists_count() == 0 {
153-
return RenderToken(PhantomData);
152+
return RenderToken;
154153
}
155154

156155
unsafe {
@@ -169,7 +168,7 @@ impl<'gl> RendererInner<'gl> {
169168
}
170169
drop(state);
171170
}
172-
RenderToken(PhantomData)
171+
RenderToken
173172
}
174173

175174
// Safety: vertex_array is not 0 if gl.BindVertexArray is loaded

snowflake-ingame/src/common.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use imgui::{Condition, Image, StyleVar, TextureId, Ui, Window, WindowFlags};
22
use windows::Win32::Graphics::Direct3D11::D3D11_TEXTURE2D_DESC;
3+
use crate::ipc::cmd::GameWindowCommand;
34

45
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
56
pub struct Dimensions {
@@ -57,4 +58,34 @@ impl OverlayWindow {
5758
Image::new(tid, dim.into()).build(ui)
5859
}).unwrap_or(())
5960
}
61+
}
62+
63+
#[derive(thiserror::Error, Debug)]
64+
pub enum RenderError {
65+
#[error("A IPC error has occured ({0:?}).")]
66+
IpcError(#[from] tokio::sync::mpsc::error::SendError<GameWindowCommand>),
67+
68+
#[error("A internal OpenGL error occurred ({0:?}).")]
69+
OpenGLInternalError(#[from] imgui_renderer_ogl::RenderError),
70+
71+
#[error("A internal Direct3D11 error occurred ({0:?}).")]
72+
Direct3D11InternalError(#[from] imgui_renderer_dx11::RenderError),
73+
74+
#[error("A internal DXGI error occurred ({0:?}).")]
75+
DXGIInternalError(#[from] windows::core::Error),
76+
77+
#[error("The requested renderer has not been initialized.")]
78+
RendererNotReady,
79+
80+
#[error("The overlay texture handle has not been initialized.")]
81+
OverlayHandleNotReady,
82+
83+
#[error("The overlay could not be initialized.")]
84+
OverlayPaintNotReady,
85+
86+
#[error("The overlay mutex could not be acquired.")]
87+
OverlayMutexNotReady,
88+
89+
#[error("The ImGui context could not be readied for paint.")]
90+
ImGuiNotReady
6091
}

snowflake-ingame/src/d3d11/imgui_d3d11.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use imgui::{Context, DrawData};
44
use windows::Win32::Foundation::HWND;
55
use windows::Win32::Graphics::Direct3D11::{ID3D11Device, ID3D11RenderTargetView, ID3D11Texture2D};
66
use windows::Win32::Graphics::Dxgi::{DXGI_SWAP_CHAIN_DESC, IDXGISwapChain};
7-
use imgui_renderer_dx11::{Direct3D11ImguiRenderer, RenderError};
8-
use crate::common::Dimensions;
7+
use imgui_renderer_dx11::{Direct3D11ImguiRenderer, RenderToken};
8+
use crate::common::{Dimensions, RenderError};
99
use crate::d3d11::overlay_d3d11::Direct3D11Overlay;
1010
use windows::core::Result as HResult;
1111

@@ -14,11 +14,12 @@ pub(in crate::d3d11) struct Render<'a> {
1414
}
1515

1616
impl Render<'_> {
17-
pub fn render(self, draw_data: &DrawData) -> Result<(), RenderError> {
17+
pub fn render(self, draw_data: &DrawData) -> Result<RenderToken, RenderError> {
1818
if let Some(renderer) = self.render {
19-
renderer.render(draw_data)?;
19+
Ok(renderer.render(draw_data)?)
20+
} else {
21+
Err(RenderError::RendererNotReady)
2022
}
21-
Ok(())
2223
}
2324
}
2425

@@ -49,17 +50,16 @@ impl Direct3D11ImguiController {
4950
self.rtv.is_some()
5051
}
5152

52-
// todo: use RenderToken POW
53-
pub fn frame<'a, F: FnOnce(&mut Context, Render, &mut Direct3D11Overlay) -> ()>(
53+
pub fn frame<'a, F: FnOnce(&mut Context, Render, &mut Direct3D11Overlay) -> Result<RenderToken, RenderError>>(
5454
&mut self,
5555
overlay: &mut Direct3D11Overlay,
5656
f: F,
57-
) {
57+
) -> Result<RenderToken, RenderError> {
5858
let renderer = Render {
5959
render: self.renderer.as_mut(),
6060
};
6161

62-
f(&mut self.imgui, renderer, overlay);
62+
f(&mut self.imgui, renderer, overlay)
6363
}
6464

6565
unsafe fn init_renderer(&mut self, swapchain: &IDXGISwapChain, window: HWND) -> Result<(), RenderError>{

snowflake-ingame/src/d3d11/kernel_d3d11.rs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ use windows::Win32::Graphics::Direct3D11::{
66
D3D11_TEXTURE2D_DESC, ID3D11Device1, ID3D11Texture2D,
77
};
88
use windows::Win32::Graphics::Dxgi::*;
9+
use imgui_renderer_dx11::RenderToken;
910

10-
use crate::common::OverlayWindow;
11+
use crate::common::{OverlayWindow, RenderError};
1112
use crate::d3d11::hook::{Direct3D11HookContext, FnPresentHook, FnResizeBuffersHook};
1213
use crate::d3d11::imgui::Direct3D11ImguiController;
1314
use crate::d3d11::overlay::Direct3D11Overlay;
@@ -42,7 +43,7 @@ impl Direct3D11Kernel {
4243
mut overlay: RwLockWriteGuard<Direct3D11Overlay>,
4344
mut imgui: RwLockWriteGuard<Direct3D11ImguiController>,
4445
this: &IDXGISwapChain,
45-
) -> Result<(), Box<dyn Error>> {
46+
) -> Result<RenderToken, RenderError> {
4647
// Handle update of any overlay here.
4748
if let Ok(cmd) = handle.try_recv() {
4849
match &cmd.ty {
@@ -70,20 +71,17 @@ impl Direct3D11Kernel {
7071
}
7172

7273
if !overlay.ready_to_initialize() {
73-
eprintln!("[dx11] Texture handle not ready");
74-
return Ok::<_, Box<dyn Error>>(());
74+
return Err(RenderError::OverlayHandleNotReady)
7575
}
7676

7777
let device = unsafe { this.GetDevice::<ID3D11Device1>()? };
7878

7979
if !overlay.prepare_paint(device, swapchain_desc.OutputWindow) {
80-
eprintln!("[dx11] Failed to refresh texture for output window");
81-
return Ok::<_, Box<dyn Error>>(());
80+
return Err(RenderError::OverlayPaintNotReady)
8281
}
8382

8483
if !imgui.prepare_paint(&this, size) {
85-
eprintln!("[dx11] Failed to setup imgui render state");
86-
return Ok::<_, Box<dyn Error>>(());
84+
return Err(RenderError::ImGuiNotReady)
8785
}
8886

8987
// imgui stuff here.
@@ -95,10 +93,11 @@ impl Direct3D11Kernel {
9593
overlay.paint(|tid, dim| OverlayWindow::new(&ui, tid, dim));
9694
ui.show_demo_window(&mut false);
9795
ui.show_metrics_window(&mut false);
98-
render.render(ui.render()).unwrap()
99-
});
96+
render.render(ui.render())
97+
})
98+
} else {
99+
Err(RenderError::OverlayMutexNotReady)
100100
}
101-
Ok::<_, Box<dyn Error>>(())
102101
}
103102

104103
fn resize_impl(mut imgui: RwLockWriteGuard<Direct3D11ImguiController>) {
@@ -112,9 +111,14 @@ impl Direct3D11Kernel {
112111
Box::new(
113112
move |this: IDXGISwapChain, sync: u32, flags: u32, mut next| {
114113
let handle = handle.clone();
115-
Direct3D11Kernel::present_impl(handle, overlay.write(),
114+
match Direct3D11Kernel::present_impl(handle, overlay.write(),
116115
imgui.write(), &this)
117-
.unwrap_or(());
116+
{
117+
Ok(_) => {}
118+
Err(e) => {
119+
eprintln!("[dx11] {}", e)
120+
}
121+
}
118122
let fp = next.fp_next();
119123
fp(this, sync, flags, next)
120124
},

snowflake-ingame/src/wgl/imgui_wgl.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use imgui::{Context, DrawData};
22
use windows::Win32::Foundation::HWND;
33
use windows::Win32::Graphics::OpenGL::HGLRC;
4-
use imgui_renderer_ogl::{OpenGLImguiRenderer, RenderError};
4+
use imgui_renderer_ogl::{OpenGLImguiRenderer, RenderToken};
55
use opengl_bindings::Gl;
6-
use crate::common::Dimensions;
6+
use crate::common::{Dimensions, RenderError};
77
use crate::wgl::overlay::WGLOverlay;
88

99
pub (in crate::wgl) struct WGLImguiController {
@@ -18,11 +18,12 @@ pub(in crate::wgl) struct Render<'a> {
1818
}
1919

2020
impl Render<'_> {
21-
pub fn render(self, draw_data: &DrawData) -> Result<(), RenderError> {
21+
pub fn render(self, draw_data: &DrawData) -> Result<RenderToken, RenderError> {
2222
if let Some(renderer) = self.render {
23-
renderer.render(draw_data);
23+
Ok(renderer.render(draw_data))
24+
} else {
25+
Err(RenderError::RendererNotReady)
2426
}
25-
Ok(())
2627
}
2728
}
2829

@@ -52,16 +53,16 @@ impl WGLImguiController {
5253
}
5354

5455
// todo: use RenderToken POW
55-
pub fn frame<'a, F: FnOnce(&mut Context, Render, &mut WGLOverlay) -> ()>(
56+
pub fn frame<'a, F: FnOnce(&mut Context, Render, &mut WGLOverlay) -> Result<RenderToken, RenderError>>(
5657
&mut self,
5758
overlay: &mut WGLOverlay,
5859
f: F,
59-
) {
60+
) -> Result<RenderToken, RenderError> {
6061
let renderer = Render {
6162
render: self.renderer.as_mut(),
6263
};
6364

64-
f(&mut self.imgui, renderer, overlay);
65+
f(&mut self.imgui, renderer, overlay)
6566
}
6667

6768
pub fn prepare_paint(&mut self, gl: &Gl, window: HWND, ctx: HGLRC, screen_dim: Dimensions) -> bool {

snowflake-ingame/src/wgl/kernel_wgl.rs

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ use windows::Win32::Graphics::Gdi::{HDC, WindowFromDC};
1111
use windows::Win32::Graphics::OpenGL::{HGLRC, wglGetCurrentContext, wglGetProcAddress};
1212
use windows::Win32::System::LibraryLoader::{GetModuleHandleA, GetProcAddress};
1313
use windows::Win32::UI::WindowsAndMessaging::GetClientRect;
14+
use imgui_renderer_ogl::RenderToken;
1415
use opengl_bindings::Gl;
15-
use crate::common::{Dimensions, OverlayWindow};
16+
use crate::common::{Dimensions, OverlayWindow, RenderError};
1617
use crate::hook::{HookHandle, HookChain};
1718
use crate::ipc::cmd::{GameWindowCommand, GameWindowCommandType};
1819
use crate::ipc::IpcHandle;
@@ -89,7 +90,7 @@ impl WGLKernel {
8990
hglrc: HGLRC,
9091
mut overlay: RwLockWriteGuard<WGLOverlay>,
9192
mut imgui: RwLockWriteGuard<WGLImguiController>,
92-
) {
93+
) -> Result<RenderToken, RenderError>{
9394
// Handle update of any overlay here.
9495
if let Ok(cmd) = handle.try_recv() {
9596
match &cmd.ty {
@@ -111,23 +112,19 @@ impl WGLKernel {
111112
};
112113

113114
if !overlay.size_matches_viewpoint(&size) {
114-
// todo: error
115-
handle.send(GameWindowCommand::window_resize(&size)).unwrap();
115+
handle.send(GameWindowCommand::window_resize(&size))?;
116116
}
117117

118118
if !overlay.ready_to_initialize() {
119-
eprintln!("[wgl] Texture handle not ready");
120-
return;
119+
return Err(RenderError::OverlayHandleNotReady)
121120
}
122121

123122
if !overlay.prepare_paint(gl, window, hglrc) {
124-
eprintln!("[wgl] Failed to refresh texture for output window");
125-
return;
123+
return Err(RenderError::OverlayPaintNotReady)
126124
}
127125

128126
if !imgui.prepare_paint(gl, window, hglrc, size) {
129-
eprintln!("[wgl] Failed to setup imgui render state");
130-
return;
127+
return Err(RenderError::ImGuiNotReady)
131128
}
132129

133130
imgui.frame(&mut overlay, |ctx, render, overlay| {
@@ -137,8 +134,9 @@ impl WGLKernel {
137134
}
138135
ui.show_metrics_window(&mut false);
139136
ui.show_demo_window(&mut false);
140-
render.render(ui.render()).unwrap()
141-
});
137+
let token = render.render(ui.render())?;
138+
Ok(token)
139+
})
142140
}
143141

144142
pub fn make_swap_buffers(&self) -> FnSwapBuffersHook {
@@ -161,8 +159,13 @@ impl WGLKernel {
161159
let handle = handle.clone();
162160
let gl = gl.clone();
163161

164-
WGLKernel::swapbuffers_impl(&gl.read(), handle, hdc, hglrc,overlay.write(),
165-
imgui.write());
162+
match WGLKernel::swapbuffers_impl(&gl.read(), handle, hdc, hglrc,overlay.write(),
163+
imgui.write()) {
164+
Ok(_) => {},
165+
Err(e) => {
166+
eprintln!("[wgl] {}", e);
167+
}
168+
}
166169
let fp = next.fp_next();
167170
fp(hdc, next)
168171
})

0 commit comments

Comments
 (0)