From 3157fbdac1278ce24c05b104561fe702523a0f94 Mon Sep 17 00:00:00 2001 From: lif Date: Sat, 16 Nov 2019 22:25:03 -0800 Subject: [PATCH] Fix infinite drop() loop on close --- src/bin/example.rs | 34 +++++++++++++++++++++++----------- src/retro/wrapper.rs | 17 ++++++----------- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/bin/example.rs b/src/bin/example.rs index 3321e41..d525bdf 100644 --- a/src/bin/example.rs +++ b/src/bin/example.rs @@ -3,7 +3,7 @@ extern crate rustro; extern crate sdl2; use rustro::retro; -use rustro::retro::ffi::{GameGeometry, SystemAvInfo}; +use rustro::retro::ffi::{GameGeometry, SystemInfo, SystemAvInfo}; use rustro::retro::constants::{Input, DeviceIndex, JoypadButton, AnalogAxis}; use std::ffi::CStr; @@ -24,6 +24,7 @@ use sdl2::video::WindowContext; struct MyEmulator { retro: retro::wrapper::LibretroWrapper, + sys_info: SystemInfo, av_info: SystemAvInfo, sdl_context: sdl2::Sdl, @@ -50,10 +51,10 @@ impl MyEmulator { let raw_retro = retro::loading::LibretroApi::from_library(lib).unwrap(); let retro = retro::wrapper::LibretroWrapper::from(raw_retro); + let sys_info = retro.as_ref().get_system_info(); let title = format!( "{} - rust libretro", - unsafe { CStr::from_ptr(retro.as_ref().get_system_info().library_name) } - .to_string_lossy() + unsafe { CStr::from_ptr(sys_info.library_name) }.to_string_lossy() ); let mut av_info = retro.as_ref().get_system_av_info(); @@ -115,6 +116,7 @@ impl MyEmulator { let emu = MyEmulator { retro, av_info, + sys_info, sdl_context, canvas, pixel_format, @@ -160,16 +162,19 @@ impl MyEmulator { } pub fn load_game(&self, rom: impl AsRef) { + let path = rom.as_ref(); let mut data = None; let mut v = Vec::new(); - if let Ok(mut f) = std::fs::File::open(rom.as_ref()) { - if f.read_to_end(&mut v).is_ok() { - data = Some(v.as_ref()); + if !self.sys_info.need_fullpath { + if let Ok(mut f) = std::fs::File::open(path) { + if f.read_to_end(&mut v).is_ok() { + data = Some(v.as_ref()); + } } } self.retro .as_ref() - .load_game(Some(rom.as_ref()), data, None) + .load_game(Some(path), data, None) .unwrap(); } @@ -182,6 +187,13 @@ impl MyEmulator { } } } + +impl Drop for MyEmulator { + fn drop(&mut self) { + retro::wrapper::unset_handler(); + } +} + impl retro::wrapper::Handler for MyEmulator { fn video_refresh(&mut self, data: &[u8], width: u32, height: u32, pitch: u32) { let rect = Rect::new(0, 0, width, height); @@ -248,16 +260,16 @@ impl retro::wrapper::Handler for MyEmulator { fn set_system_av_info(&mut self, av_info: SystemAvInfo) -> bool { let (width, height) = (av_info.geometry.base_width, av_info.geometry.base_height); - self.canvas.window_mut().set_size(width, height); - self.canvas.set_logical_size(width, height); + let _ = self.canvas.window_mut().set_size(width, height); + let _ = self.canvas.set_logical_size(width, height); self.av_info = av_info; true } fn set_geometry(&mut self, geom: GameGeometry) -> bool { let (width, height) = (geom.base_width, geom.base_height); - self.canvas.window_mut().set_size(width, height); - self.canvas.set_logical_size(width, height); + let _ = self.canvas.window_mut().set_size(width, height); + let _ = self.canvas.set_logical_size(width, height); self.av_info.geometry = geom; true } diff --git a/src/retro/wrapper.rs b/src/retro/wrapper.rs index 679e6ba..95e3306 100644 --- a/src/retro/wrapper.rs +++ b/src/retro/wrapper.rs @@ -207,11 +207,6 @@ impl StaticCallbacks { None => 0, } } - pub(crate) fn reset() { - unsafe { - CB_SINGLETON.handler.take(); - } - } } pub struct LibretroWrapper { @@ -237,12 +232,6 @@ impl AsRef for LibretroWrapper { } } -impl Drop for LibretroWrapper { - fn drop(&mut self) { - StaticCallbacks::reset(); - } -} - // a note on lifetimes: we explicitly lie about them here because as long as they live as long as // the library wrapper itself we're good (we wipe our 'static references on drop() too) pub fn set_handler(handler: Pin<&'_ mut (dyn Handler + '_)>) { @@ -251,3 +240,9 @@ pub fn set_handler(handler: Pin<&'_ mut (dyn Handler + '_)>) { CB_SINGLETON.handler.replace(Pin::new_unchecked(ptr.as_mut().unwrap())); } } + +pub fn unset_handler() { + unsafe { + CB_SINGLETON.handler.take(); + } +}