Fix infinite drop() loop on close

This commit is contained in:
lif 2019-11-16 22:25:03 -08:00
parent d9f1d789ca
commit 3157fbdac1
2 changed files with 29 additions and 22 deletions

View file

@ -3,7 +3,7 @@ extern crate rustro;
extern crate sdl2; extern crate sdl2;
use rustro::retro; 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 rustro::retro::constants::{Input, DeviceIndex, JoypadButton, AnalogAxis};
use std::ffi::CStr; use std::ffi::CStr;
@ -24,6 +24,7 @@ use sdl2::video::WindowContext;
struct MyEmulator { struct MyEmulator {
retro: retro::wrapper::LibretroWrapper, retro: retro::wrapper::LibretroWrapper,
sys_info: SystemInfo,
av_info: SystemAvInfo, av_info: SystemAvInfo,
sdl_context: sdl2::Sdl, sdl_context: sdl2::Sdl,
@ -50,10 +51,10 @@ impl MyEmulator {
let raw_retro = retro::loading::LibretroApi::from_library(lib).unwrap(); let raw_retro = retro::loading::LibretroApi::from_library(lib).unwrap();
let retro = retro::wrapper::LibretroWrapper::from(raw_retro); let retro = retro::wrapper::LibretroWrapper::from(raw_retro);
let sys_info = retro.as_ref().get_system_info();
let title = format!( let title = format!(
"{} - rust libretro", "{} - rust libretro",
unsafe { CStr::from_ptr(retro.as_ref().get_system_info().library_name) } unsafe { CStr::from_ptr(sys_info.library_name) }.to_string_lossy()
.to_string_lossy()
); );
let mut av_info = retro.as_ref().get_system_av_info(); let mut av_info = retro.as_ref().get_system_av_info();
@ -115,6 +116,7 @@ impl MyEmulator {
let emu = MyEmulator { let emu = MyEmulator {
retro, retro,
av_info, av_info,
sys_info,
sdl_context, sdl_context,
canvas, canvas,
pixel_format, pixel_format,
@ -160,16 +162,19 @@ impl MyEmulator {
} }
pub fn load_game(&self, rom: impl AsRef<Path>) { pub fn load_game(&self, rom: impl AsRef<Path>) {
let path = rom.as_ref();
let mut data = None; let mut data = None;
let mut v = Vec::new(); let mut v = Vec::new();
if let Ok(mut f) = std::fs::File::open(rom.as_ref()) { if !self.sys_info.need_fullpath {
if f.read_to_end(&mut v).is_ok() { if let Ok(mut f) = std::fs::File::open(path) {
data = Some(v.as_ref()); if f.read_to_end(&mut v).is_ok() {
data = Some(v.as_ref());
}
} }
} }
self.retro self.retro
.as_ref() .as_ref()
.load_game(Some(rom.as_ref()), data, None) .load_game(Some(path), data, None)
.unwrap(); .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 { impl retro::wrapper::Handler for MyEmulator {
fn video_refresh(&mut self, data: &[u8], width: u32, height: u32, pitch: u32) { fn video_refresh(&mut self, data: &[u8], width: u32, height: u32, pitch: u32) {
let rect = Rect::new(0, 0, width, height); 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 { fn set_system_av_info(&mut self, av_info: SystemAvInfo) -> bool {
let (width, height) = (av_info.geometry.base_width, av_info.geometry.base_height); let (width, height) = (av_info.geometry.base_width, av_info.geometry.base_height);
self.canvas.window_mut().set_size(width, height); let _ = self.canvas.window_mut().set_size(width, height);
self.canvas.set_logical_size(width, height); let _ = self.canvas.set_logical_size(width, height);
self.av_info = av_info; self.av_info = av_info;
true true
} }
fn set_geometry(&mut self, geom: GameGeometry) -> bool { fn set_geometry(&mut self, geom: GameGeometry) -> bool {
let (width, height) = (geom.base_width, geom.base_height); let (width, height) = (geom.base_width, geom.base_height);
self.canvas.window_mut().set_size(width, height); let _ = self.canvas.window_mut().set_size(width, height);
self.canvas.set_logical_size(width, height); let _ = self.canvas.set_logical_size(width, height);
self.av_info.geometry = geom; self.av_info.geometry = geom;
true true
} }

View file

@ -207,11 +207,6 @@ impl StaticCallbacks {
None => 0, None => 0,
} }
} }
pub(crate) fn reset() {
unsafe {
CB_SINGLETON.handler.take();
}
}
} }
pub struct LibretroWrapper { pub struct LibretroWrapper {
@ -237,12 +232,6 @@ impl AsRef<LibretroApi> 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 // 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) // the library wrapper itself we're good (we wipe our 'static references on drop() too)
pub fn set_handler(handler: Pin<&'_ mut (dyn Handler + '_)>) { 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())); CB_SINGLETON.handler.replace(Pin::new_unchecked(ptr.as_mut().unwrap()));
} }
} }
pub fn unset_handler() {
unsafe {
CB_SINGLETON.handler.take();
}
}