mirror of
https://github.com/gopher64/gopher64.git
synced 2026-07-11 01:25:20 +02:00
+1
-1
@@ -349,7 +349,7 @@ impl Device {
|
||||
load_state: false,
|
||||
load_rewind: false,
|
||||
last_rewind_saved: 0.0,
|
||||
rewind_pool: std::sync::Arc::new(std::sync::Mutex::new(
|
||||
rewind_pool: std::sync::Arc::new(tokio::sync::Mutex::new(
|
||||
std::collections::BTreeMap::new(),
|
||||
)),
|
||||
},
|
||||
|
||||
+7
-9
@@ -105,7 +105,7 @@ fn set_app_id() {
|
||||
}
|
||||
|
||||
pub fn create_runtime() -> (tokio::sync::oneshot::Sender<()>, tokio::runtime::Handle) {
|
||||
let (tx, rx) = std::sync::mpsc::channel();
|
||||
let (tx, mut rx) = tokio::sync::mpsc::unbounded_channel();
|
||||
let (close_tx, close_rx) = tokio::sync::oneshot::channel::<()>();
|
||||
|
||||
std::thread::spawn(move || {
|
||||
@@ -114,7 +114,7 @@ pub fn create_runtime() -> (tokio::sync::oneshot::Sender<()>, tokio::runtime::Ha
|
||||
rt.block_on(close_rx).unwrap();
|
||||
});
|
||||
|
||||
(close_tx, rx.recv().unwrap())
|
||||
(close_tx, rx.blocking_recv().unwrap())
|
||||
}
|
||||
|
||||
pub fn run(args: Args, arg_count: usize) -> std::io::Result<()> {
|
||||
@@ -352,9 +352,7 @@ fn android_main(app: slint::android::AndroidApp) {
|
||||
slint::android::init_with_event_listener(app.clone(), move |event| match event {
|
||||
slint::android::android_activity::PollEvent::Main(main_event) => match main_event {
|
||||
slint::android::android_activity::MainEvent::TerminateWindow { .. } => {
|
||||
if let Ok(weak_app_window) = android::WEAK_SLINT_WINDOW.lock()
|
||||
&& let Some(weak_app_window) = weak_app_window.as_ref()
|
||||
{
|
||||
if let Some(weak_app_window) = android::WEAK_SLINT_WINDOW.blocking_lock().as_ref() {
|
||||
weak_app_window
|
||||
.upgrade_in_event_loop(move |handle| {
|
||||
ui::gui::save_settings(&handle);
|
||||
@@ -369,9 +367,9 @@ fn android_main(app: slint::android::AndroidApp) {
|
||||
})
|
||||
.unwrap();
|
||||
let app_window = ui::gui::AppWindow::new().unwrap();
|
||||
*android::WEAK_SLINT_WINDOW.lock().unwrap() = Some(app_window.as_weak());
|
||||
*android::WEAK_SLINT_WINDOW.blocking_lock() = Some(app_window.as_weak());
|
||||
|
||||
*android::ANDROID_APP.lock().unwrap() = Some(app);
|
||||
*android::ANDROID_APP.blocking_lock() = Some(app);
|
||||
|
||||
let dirs = ui::get_dirs();
|
||||
|
||||
@@ -382,6 +380,6 @@ fn android_main(app: slint::android::AndroidApp) {
|
||||
|
||||
ui::gui::app_window(&app_window, true);
|
||||
close_tx.send(()).unwrap();
|
||||
*android::WEAK_SLINT_WINDOW.lock().unwrap() = None;
|
||||
*android::ANDROID_APP.lock().unwrap() = None;
|
||||
*android::WEAK_SLINT_WINDOW.blocking_lock() = None;
|
||||
*android::ANDROID_APP.blocking_lock() = None;
|
||||
}
|
||||
|
||||
+35
-52
@@ -78,7 +78,7 @@ pub struct Savestate {
|
||||
pub last_rewind_saved: f64,
|
||||
#[serde(skip)]
|
||||
pub rewind_pool:
|
||||
std::sync::Arc<std::sync::Mutex<std::collections::BTreeMap<i32, SavestateData>>>,
|
||||
std::sync::Arc<tokio::sync::Mutex<std::collections::BTreeMap<i32, SavestateData>>>,
|
||||
}
|
||||
|
||||
pub struct SavestateData {
|
||||
@@ -88,11 +88,11 @@ pub struct SavestateData {
|
||||
ra_state: Vec<u8>,
|
||||
}
|
||||
|
||||
static DEVICE_CLONE: std::sync::LazyLock<std::sync::Mutex<Box<device::Device>>> =
|
||||
std::sync::LazyLock::new(|| std::sync::Mutex::new(device::Device::new(false)));
|
||||
static DEVICE_CLONE: std::sync::LazyLock<tokio::sync::Mutex<Box<device::Device>>> =
|
||||
std::sync::LazyLock::new(|| tokio::sync::Mutex::new(device::Device::new(false)));
|
||||
|
||||
static SAVES_CLONE: std::sync::LazyLock<std::sync::Mutex<ui::storage::Saves>> =
|
||||
std::sync::LazyLock::new(|| std::sync::Mutex::new(ui::storage::Saves::default()));
|
||||
static SAVES_CLONE: std::sync::LazyLock<tokio::sync::Mutex<ui::storage::Saves>> =
|
||||
std::sync::LazyLock::new(|| tokio::sync::Mutex::new(ui::storage::Saves::default()));
|
||||
|
||||
pub fn process_savestates(device: &mut device::Device) {
|
||||
let save_rewind = if device.netplay.is_none()
|
||||
@@ -126,18 +126,10 @@ pub fn create_savestate(device: &mut device::Device, rewind: bool, rewind_frame:
|
||||
let mut ra_state: Vec<u8> = vec![0; retroachievements::state_size()];
|
||||
retroachievements::save_state(ra_state.as_mut_ptr(), ra_state.len());
|
||||
|
||||
if let Ok(mut device_clone) = DEVICE_CLONE.lock()
|
||||
&& let Ok(mut saves_clone) = SAVES_CLONE.lock()
|
||||
{
|
||||
device_clone.clone_state(device);
|
||||
saves_clone.clone_from(&device.ui.storage.saves);
|
||||
} else {
|
||||
ui::video::onscreen_message(
|
||||
"Failed to create savestate",
|
||||
ui::video::MESSAGE_LENGTH_MESSAGE_SHORT,
|
||||
);
|
||||
return;
|
||||
}
|
||||
DEVICE_CLONE.blocking_lock().clone_state(device);
|
||||
SAVES_CLONE
|
||||
.blocking_lock()
|
||||
.clone_from(&device.ui.storage.saves);
|
||||
|
||||
let save_path = device.ui.storage.paths.savestate_file_path.clone();
|
||||
let save_state_slot = device.ui.storage.save_state_slot;
|
||||
@@ -147,39 +139,32 @@ pub fn create_savestate(device: &mut device::Device, rewind: bool, rewind_frame:
|
||||
let mut error = false;
|
||||
|
||||
if rewind {
|
||||
if let Ok(device_clone) = DEVICE_CLONE.lock()
|
||||
&& let Ok(saves_clone) = SAVES_CLONE.lock()
|
||||
&& let Ok(mut pool) = rewind_pool.lock()
|
||||
{
|
||||
let mut state = device::Device::new(false);
|
||||
state.clone_state(device_clone.deref());
|
||||
let key = if let Some(key) = rewind_frame {
|
||||
key
|
||||
} else if let Some(key) = pool.keys().last() {
|
||||
key + 1
|
||||
} else {
|
||||
0
|
||||
};
|
||||
pool.insert(
|
||||
key,
|
||||
SavestateData {
|
||||
device: state,
|
||||
saves: saves_clone.clone(),
|
||||
rdp_state,
|
||||
ra_state,
|
||||
},
|
||||
);
|
||||
if pool.len() > 30 {
|
||||
pool.pop_first();
|
||||
}
|
||||
let mut pool = rewind_pool.lock().await;
|
||||
let mut state = device::Device::new(false);
|
||||
state.clone_state(DEVICE_CLONE.lock().await.deref());
|
||||
let key = if let Some(key) = rewind_frame {
|
||||
key
|
||||
} else if let Some(key) = pool.keys().last() {
|
||||
key + 1
|
||||
} else {
|
||||
error = true;
|
||||
0
|
||||
};
|
||||
pool.insert(
|
||||
key,
|
||||
SavestateData {
|
||||
device: state,
|
||||
saves: SAVES_CLONE.lock().await.clone(),
|
||||
rdp_state,
|
||||
ra_state,
|
||||
},
|
||||
);
|
||||
if pool.len() > 30 {
|
||||
pool.pop_first();
|
||||
}
|
||||
} else {
|
||||
let compressed_file = if let Ok(device_clone) = DEVICE_CLONE.lock()
|
||||
&& let Ok(saves_clone) = SAVES_CLONE.lock()
|
||||
&& let Ok(device_data) = postcard::to_stdvec(device_clone.deref())
|
||||
&& let Ok(saves_data) = postcard::to_stdvec(saves_clone.deref())
|
||||
let compressed_file = if let Ok(device_data) =
|
||||
postcard::to_stdvec(DEVICE_CLONE.lock().await.deref())
|
||||
&& let Ok(saves_data) = postcard::to_stdvec(SAVES_CLONE.lock().await.deref())
|
||||
&& let Ok(compressed_file) = ui::storage::compress_file(&[
|
||||
(&device_data, "device"),
|
||||
(&saves_data, "saves"),
|
||||
@@ -229,17 +214,15 @@ pub fn load_savestate(device: &mut device::Device, rewind: bool, rewind_frame: O
|
||||
let timeout = std::time::Duration::from_secs(1);
|
||||
let now = std::time::Instant::now();
|
||||
loop {
|
||||
if let Ok(mut pool) = device.savestate.rewind_pool.lock()
|
||||
&& pool.contains_key(&rewind_frame)
|
||||
{
|
||||
let mut pool = device.savestate.rewind_pool.blocking_lock();
|
||||
if pool.contains_key(&rewind_frame) {
|
||||
break pool.remove(&rewind_frame);
|
||||
}
|
||||
if now.elapsed() > timeout {
|
||||
break None;
|
||||
}
|
||||
}
|
||||
} else if let Ok(mut pool) = device.savestate.rewind_pool.lock()
|
||||
&& let Some((_key, state)) = pool.pop_last()
|
||||
} else if let Some((_key, state)) = device.savestate.rewind_pool.blocking_lock().pop_last()
|
||||
{
|
||||
Some(state)
|
||||
} else {
|
||||
|
||||
+19
-44
@@ -13,15 +13,15 @@ const REQUEST_SELECT_ROM: jint = 1;
|
||||
const CONFIGURE_INPUT_PROFILE: jint = 2;
|
||||
const RUN_ROM: jint = 3;
|
||||
|
||||
pub static ANDROID_APP: std::sync::Mutex<Option<slint::android::AndroidApp>> =
|
||||
std::sync::Mutex::new(None);
|
||||
pub static ANDROID_APP: tokio::sync::Mutex<Option<slint::android::AndroidApp>> =
|
||||
tokio::sync::Mutex::const_new(None);
|
||||
|
||||
pub static SELECT_ROM_TX: std::sync::Mutex<
|
||||
pub static SELECT_ROM_TX: tokio::sync::Mutex<
|
||||
Option<tokio::sync::oneshot::Sender<Option<std::path::PathBuf>>>,
|
||||
> = std::sync::Mutex::new(None);
|
||||
> = tokio::sync::Mutex::const_new(None);
|
||||
|
||||
pub static WEAK_SLINT_WINDOW: std::sync::Mutex<Option<slint::Weak<ui::gui::AppWindow>>> =
|
||||
std::sync::Mutex::new(None);
|
||||
pub static WEAK_SLINT_WINDOW: tokio::sync::Mutex<Option<slint::Weak<ui::gui::AppWindow>>> =
|
||||
tokio::sync::Mutex::const_new(None);
|
||||
|
||||
bind_java_type! {
|
||||
DocumentsContract => "android.provider.DocumentsContract",
|
||||
@@ -197,9 +197,7 @@ fn start_configure_input_profile_on_jvm(
|
||||
dinput: bool,
|
||||
deadzone: i32,
|
||||
) -> jni::errors::Result<()> {
|
||||
if let Ok(app) = ANDROID_APP.lock()
|
||||
&& let Some(app) = app.as_ref()
|
||||
{
|
||||
if let Some(app) = ANDROID_APP.blocking_lock().as_ref() {
|
||||
let raw_activity_global = app.activity_as_ptr() as jni::sys::jobject;
|
||||
let activity = unsafe { env.as_cast_raw::<Global<AndroidActivity>>(&raw_activity_global)? };
|
||||
|
||||
@@ -256,9 +254,7 @@ fn start_run_rom_on_jvm(
|
||||
netplay: Option<ui::gui::NetplayDevice>,
|
||||
weak: slint::Weak<ui::gui::AppWindow>,
|
||||
) -> jni::errors::Result<()> {
|
||||
if let Ok(app) = ANDROID_APP.lock()
|
||||
&& let Some(app) = app.as_ref()
|
||||
{
|
||||
if let Some(app) = ANDROID_APP.blocking_lock().as_ref() {
|
||||
let raw_activity_global = app.activity_as_ptr() as jni::sys::jobject;
|
||||
let activity = unsafe { env.as_cast_raw::<Global<AndroidActivity>>(&raw_activity_global)? };
|
||||
|
||||
@@ -330,9 +326,7 @@ fn start_run_rom_on_jvm(
|
||||
}
|
||||
|
||||
fn get_vm() -> Option<JavaVM> {
|
||||
if let Ok(app) = ANDROID_APP.lock()
|
||||
&& let Some(app) = app.as_ref()
|
||||
{
|
||||
if let Some(app) = ANDROID_APP.blocking_lock().as_ref() {
|
||||
Some(unsafe { JavaVM::from_raw(app.vm_as_ptr().cast()) })
|
||||
} else {
|
||||
None
|
||||
@@ -431,9 +425,7 @@ pub fn open_uri(path: &str) {
|
||||
}
|
||||
|
||||
fn open_uri_on_jvm(env: &mut Env<'_>, path: &str) -> jni::errors::Result<()> {
|
||||
if let Ok(app) = ANDROID_APP.lock()
|
||||
&& let Some(app) = app.as_ref()
|
||||
{
|
||||
if let Some(app) = ANDROID_APP.blocking_lock().as_ref() {
|
||||
let raw_activity_global = app.activity_as_ptr() as jni::sys::jobject;
|
||||
let activity = unsafe { env.as_cast_raw::<Global<AndroidActivity>>(&raw_activity_global)? };
|
||||
|
||||
@@ -459,12 +451,8 @@ pub async fn select_rom(rom_dir: slint::SharedString) -> Option<std::path::PathB
|
||||
return None;
|
||||
}
|
||||
let (tx, rx) = tokio::sync::oneshot::channel::<Option<std::path::PathBuf>>();
|
||||
if let Ok(mut tx_lock) = SELECT_ROM_TX.lock() {
|
||||
tx_lock.replace(tx);
|
||||
} else {
|
||||
eprintln!("Error locking SELECT_ROM_TX");
|
||||
return None;
|
||||
}
|
||||
SELECT_ROM_TX.lock().await.replace(tx);
|
||||
|
||||
rx.await.unwrap_or(None)
|
||||
} else {
|
||||
eprintln!("Android app not initialized");
|
||||
@@ -481,9 +469,7 @@ pub async fn select_gb_ram(_player: i32) -> Option<std::path::PathBuf> {
|
||||
}
|
||||
|
||||
fn select_rom_on_jvm(env: &mut Env<'_>, rom_dir: String) -> jni::errors::Result<()> {
|
||||
if let Ok(app) = ANDROID_APP.lock()
|
||||
&& let Some(app) = app.as_ref()
|
||||
{
|
||||
if let Some(app) = ANDROID_APP.blocking_lock().as_ref() {
|
||||
let raw_activity_global = app.activity_as_ptr() as jni::sys::jobject;
|
||||
let activity = unsafe { env.as_cast_raw::<Global<AndroidActivity>>(&raw_activity_global)? };
|
||||
|
||||
@@ -507,9 +493,7 @@ fn select_rom_on_jvm(env: &mut Env<'_>, rom_dir: String) -> jni::errors::Result<
|
||||
}
|
||||
|
||||
pub fn get_dirs() -> ui::Dirs {
|
||||
if let Ok(app) = ANDROID_APP.lock()
|
||||
&& let Some(app) = app.as_ref()
|
||||
{
|
||||
if let Some(app) = ANDROID_APP.blocking_lock().as_ref() {
|
||||
ui::Dirs {
|
||||
config_dir: app.internal_data_path().unwrap().join("config"),
|
||||
data_dir: app.external_data_path().unwrap().join("data"),
|
||||
@@ -559,9 +543,7 @@ fn get_file_from_uri_on_jvm(
|
||||
env: &mut Env<'_>,
|
||||
path: String,
|
||||
) -> jni::errors::Result<Option<std::fs::File>> {
|
||||
if let Ok(app) = ANDROID_APP.lock()
|
||||
&& let Some(app) = app.as_ref()
|
||||
{
|
||||
if let Some(app) = ANDROID_APP.blocking_lock().as_ref() {
|
||||
let raw_activity_global = app.activity_as_ptr() as jni::sys::jobject;
|
||||
let activity = unsafe { env.as_cast_raw::<Global<AndroidActivity>>(&raw_activity_global)? };
|
||||
let path = JString::from_str(env, path)?;
|
||||
@@ -600,8 +582,7 @@ pub extern "system" fn Java_io_github_gopher64_gopher64_SlintActivity_nativeOnAc
|
||||
if result_code == AndroidActivity::RESULT_OK(env)? {
|
||||
match request_code {
|
||||
REQUEST_SELECT_ROM => {
|
||||
if let Ok(mut tx_lock) = SELECT_ROM_TX.lock()
|
||||
&& let Some(tx) = tx_lock.take()
|
||||
if let Some(tx) = SELECT_ROM_TX.blocking_lock().take()
|
||||
&& !intent_data.is_null()
|
||||
{
|
||||
let result_intent =
|
||||
@@ -612,9 +593,7 @@ pub extern "system" fn Java_io_github_gopher64_gopher64_SlintActivity_nativeOnAc
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if let Ok(app) = ANDROID_APP.lock()
|
||||
&& let Some(app) = app.as_ref()
|
||||
{
|
||||
if let Some(app) = ANDROID_APP.blocking_lock().as_ref() {
|
||||
let raw_activity_global = app.activity_as_ptr() as jni::sys::jobject;
|
||||
let activity = unsafe {
|
||||
env.as_cast_raw::<Global<AndroidActivity>>(&raw_activity_global)?
|
||||
@@ -635,9 +614,7 @@ pub extern "system" fn Java_io_github_gopher64_gopher64_SlintActivity_nativeOnAc
|
||||
}
|
||||
}
|
||||
CONFIGURE_INPUT_PROFILE => {
|
||||
if let Ok(weak_app_window) = WEAK_SLINT_WINDOW.lock()
|
||||
&& let Some(weak_app_window) = weak_app_window.as_ref()
|
||||
{
|
||||
if let Some(weak_app_window) = WEAK_SLINT_WINDOW.blocking_lock().as_ref() {
|
||||
let config = ui::config::Config::new();
|
||||
ui::gui::update_input_profiles(&weak_app_window, &config);
|
||||
}
|
||||
@@ -659,9 +636,7 @@ pub extern "system" fn Java_io_github_gopher64_gopher64_SlintActivity_nativeOnAc
|
||||
{
|
||||
let _ = std::fs::remove_file(cheats_path);
|
||||
}
|
||||
if let Ok(weak_app_window) = WEAK_SLINT_WINDOW.lock()
|
||||
&& let Some(weak_app_window) = weak_app_window.as_ref()
|
||||
{
|
||||
if let Some(weak_app_window) = WEAK_SLINT_WINDOW.blocking_lock().as_ref() {
|
||||
weak_app_window
|
||||
.upgrade_in_event_loop(move |handle| {
|
||||
ui::gui::update_recent_roms(&handle, file_path.into());
|
||||
|
||||
Reference in New Issue
Block a user