@@ -11,6 +11,7 @@ mod views;
1111
1212use std:: {
1313 path:: PathBuf ,
14+ process:: ExitCode ,
1415 rc:: Rc ,
1516 sync:: { Arc , Mutex } ,
1617} ;
@@ -37,7 +38,7 @@ const APP_NAME: &str = "objdiff";
3738
3839// When compiling natively:
3940#[ cfg( not( target_arch = "wasm32" ) ) ]
40- fn main ( ) {
41+ fn main ( ) -> ExitCode {
4142 // Log to stdout (if you run with `RUST_LOG=debug`).
4243 tracing_subscriber:: fmt:: init ( ) ;
4344
@@ -48,15 +49,14 @@ fn main() {
4849
4950 let app_path = std:: env:: current_exe ( ) . ok ( ) ;
5051 let exec_path: Rc < Mutex < Option < PathBuf > > > = Rc :: new ( Mutex :: new ( None ) ) ;
51- let exec_path_clone = exec_path. clone ( ) ;
5252 let mut native_options =
5353 eframe:: NativeOptions { follow_system_theme : false , ..Default :: default ( ) } ;
5454 match load_icon ( ) {
5555 Ok ( data) => {
5656 native_options. viewport . icon = Some ( Arc :: new ( data) ) ;
5757 }
5858 Err ( e) => {
59- log:: warn!( "Failed to load application icon: {}" , e ) ;
59+ log:: warn!( "Failed to load application icon: {e:?}" ) ;
6060 }
6161 }
6262 let mut graphics_config = GraphicsConfig :: default ( ) ;
@@ -69,7 +69,7 @@ fn main() {
6969 }
7070 Ok ( None ) => { }
7171 Err ( e) => {
72- log:: error!( "Failed to load native config: {:?}" , e ) ;
72+ log:: error!( "Failed to load native config: {e :?}" ) ;
7373 }
7474 }
7575 graphics_config_path = Some ( config_path) ;
@@ -87,42 +87,118 @@ fn main() {
8787 } ;
8888 }
8989 }
90- eframe:: run_native (
91- APP_NAME ,
92- native_options,
93- Box :: new ( move |cc| {
94- Box :: new ( app:: App :: new (
95- cc,
90+ let mut eframe_error = None ;
91+ if let Err ( e) = run_eframe (
92+ native_options. clone ( ) ,
93+ utc_offset,
94+ exec_path. clone ( ) ,
95+ app_path. clone ( ) ,
96+ graphics_config. clone ( ) ,
97+ graphics_config_path. clone ( ) ,
98+ ) {
99+ eframe_error = Some ( e) ;
100+ }
101+ #[ cfg( feature = "wgpu" ) ]
102+ if let Some ( e) = eframe_error {
103+ // Attempt to relaunch using wgpu auto backend if the desired backend failed
104+ #[ allow( unused_mut) ]
105+ let mut should_relaunch = graphics_config. desired_backend != GraphicsBackend :: Auto ;
106+ #[ cfg( feature = "glow" ) ]
107+ {
108+ // If the desired backend is OpenGL, we should try to relaunch using the glow renderer
109+ should_relaunch &= graphics_config. desired_backend != GraphicsBackend :: OpenGL ;
110+ }
111+ if should_relaunch {
112+ log:: warn!( "Failed to launch application: {e:?}" ) ;
113+ log:: warn!( "Attempting to relaunch using auto-detected backend" ) ;
114+ native_options. wgpu_options . supported_backends = Default :: default ( ) ;
115+ if let Err ( e) = run_eframe (
116+ native_options. clone ( ) ,
96117 utc_offset,
97- exec_path_clone,
98- app_path,
99- graphics_config,
100- graphics_config_path,
101- ) )
102- } ) ,
103- )
104- . expect ( "Failed to run eframe application" ) ;
118+ exec_path. clone ( ) ,
119+ app_path. clone ( ) ,
120+ graphics_config. clone ( ) ,
121+ graphics_config_path. clone ( ) ,
122+ ) {
123+ eframe_error = Some ( e) ;
124+ } else {
125+ eframe_error = None ;
126+ }
127+ } else {
128+ eframe_error = Some ( e) ;
129+ }
130+ }
131+ #[ cfg( all( feature = "wgpu" , feature = "glow" ) ) ]
132+ if let Some ( e) = eframe_error {
133+ // Attempt to relaunch using the glow renderer if the wgpu backend failed
134+ log:: warn!( "Failed to launch application: {e:?}" ) ;
135+ log:: warn!( "Attempting to relaunch using fallback OpenGL backend" ) ;
136+ native_options. renderer = eframe:: Renderer :: Glow ;
137+ if let Err ( e) = run_eframe (
138+ native_options,
139+ utc_offset,
140+ exec_path. clone ( ) ,
141+ app_path,
142+ graphics_config,
143+ graphics_config_path,
144+ ) {
145+ eframe_error = Some ( e) ;
146+ } else {
147+ eframe_error = None ;
148+ }
149+ }
150+ if let Some ( e) = eframe_error {
151+ log:: error!( "Failed to launch application: {e:?}" ) ;
152+ return ExitCode :: FAILURE ;
153+ }
105154
106155 // Attempt to relaunch application from the updated path
107156 if let Ok ( mut guard) = exec_path. lock ( ) {
108157 if let Some ( path) = guard. take ( ) {
109158 cfg_if ! {
110159 if #[ cfg( unix) ] {
111- let result = exec:: Command :: new( path)
160+ let e = exec:: Command :: new( path)
112161 . args( & std:: env:: args( ) . collect:: <Vec <String >>( ) )
113162 . exec( ) ;
114- log:: error!( "Failed to relaunch: {result:?}" ) ;
163+ log:: error!( "Failed to relaunch: {e:?}" ) ;
164+ return ExitCode :: FAILURE ;
115165 } else {
116166 let result = std:: process:: Command :: new( path)
117167 . args( std:: env:: args( ) )
118168 . spawn( ) ;
119169 if let Err ( e) = result {
120- log:: error!( "Failed to relaunch: {:?}" , e) ;
170+ log:: error!( "Failed to relaunch: {e:?}" ) ;
171+ return ExitCode :: FAILURE ;
121172 }
122173 }
123174 }
124175 }
125176 } ;
177+ ExitCode :: SUCCESS
178+ }
179+
180+ fn run_eframe (
181+ native_options : eframe:: NativeOptions ,
182+ utc_offset : UtcOffset ,
183+ exec_path_clone : Rc < Mutex < Option < PathBuf > > > ,
184+ app_path : Option < PathBuf > ,
185+ graphics_config : GraphicsConfig ,
186+ graphics_config_path : Option < PathBuf > ,
187+ ) -> Result < ( ) , eframe:: Error > {
188+ eframe:: run_native (
189+ APP_NAME ,
190+ native_options,
191+ Box :: new ( move |cc| {
192+ Box :: new ( app:: App :: new (
193+ cc,
194+ utc_offset,
195+ exec_path_clone,
196+ app_path,
197+ graphics_config,
198+ graphics_config_path,
199+ ) )
200+ } ) ,
201+ )
126202}
127203
128204// when compiling to web using trunk.
0 commit comments