mirror of
https://github.com/Zenithsiz/dcb.git
synced 2026-02-04 00:21:57 +00:00
The main thread no longers locks the game file's cdrom.
This commit is contained in:
parent
e080bf3c4c
commit
17e352ba51
@ -8,7 +8,11 @@ use anyhow::Context;
|
||||
use dcb_cdrom_xa::CdRomCursor;
|
||||
use dcb_util::MutexPoison;
|
||||
use eframe::egui;
|
||||
use std::{fs, sync::Mutex};
|
||||
use std::{
|
||||
fs,
|
||||
io::{self, Write},
|
||||
sync::Mutex,
|
||||
};
|
||||
|
||||
/// Game file
|
||||
pub struct GameFile {
|
||||
@ -20,7 +24,7 @@ pub struct GameFile {
|
||||
}
|
||||
|
||||
impl GameFile {
|
||||
/// Creates a new game
|
||||
/// Creates a new game file from it's file
|
||||
pub fn new(file: fs::File) -> Result<Self, anyhow::Error> {
|
||||
let mut cdrom = CdRomCursor::new(file);
|
||||
let mut game_file = dcb_io::GameFile::new(&mut cdrom);
|
||||
@ -94,6 +98,11 @@ impl GameFile {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Flushes the game file to disc
|
||||
pub fn flush(&self) -> Result<(), io::Error> {
|
||||
self.cdrom.lock_unwrap().flush()
|
||||
}
|
||||
|
||||
/// Displays the game file tree
|
||||
pub fn display(
|
||||
&self, ui: &mut egui::Ui, file_search: &mut String, swap_window: &mut Option<SwapWindow>,
|
||||
@ -126,7 +135,14 @@ impl GameFile {
|
||||
|
||||
/// Performs an operation using the game file
|
||||
pub fn with_game_file<T>(&self, f: impl FnOnce(dcb_io::GameFile<&mut CdRomCursor<fs::File>>) -> T) -> T {
|
||||
// TODO: Check if main thread is using the game file, as it shouldn't be
|
||||
// We shouldn't be called from the main thread, as locking might
|
||||
// TODO: Get a better way of making sure it's the main thread and not some
|
||||
// other thread with the name 'main'?
|
||||
debug_assert_ne!(
|
||||
std::thread::current().name(),
|
||||
Some("main"),
|
||||
"Main thread should not call this function, as it might block for an indeterminate amount of time"
|
||||
);
|
||||
|
||||
// Get the game file
|
||||
let mut cdrom = self.cdrom.lock_unwrap();
|
||||
|
||||
@ -25,7 +25,7 @@ use eframe::{egui, epi, NativeOptions};
|
||||
use game_file::GameFile;
|
||||
use native_dialog::FileDialog;
|
||||
use preview_panel::{PreviewPanel, PreviewPanelBuilder};
|
||||
use std::{fs, io::Write, path::PathBuf, sync::Arc};
|
||||
use std::{fs, path::PathBuf, sync::Arc};
|
||||
use swap_window::SwapWindow;
|
||||
|
||||
fn main() {
|
||||
@ -192,10 +192,10 @@ impl epi::App for FileEditor {
|
||||
|
||||
// Flush the file if we have it
|
||||
if let Some(game_file) = &mut self.game_file {
|
||||
game_file.with_game_file(|mut game| match game.cdrom().flush() {
|
||||
match game_file.flush() {
|
||||
Ok(()) => (),
|
||||
Err(err) => alert::error(&format!("Unable to flush file tod isk: {:?}", err)),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -4,9 +4,9 @@
|
||||
use crate::GameFile;
|
||||
use anyhow::Context;
|
||||
use dcb_io::game_file::Path;
|
||||
use dcb_util::alert;
|
||||
use dcb_util::{alert, task};
|
||||
use eframe::egui;
|
||||
use std::mem;
|
||||
use std::{mem, sync::Arc};
|
||||
|
||||
/// Swap window
|
||||
#[derive(PartialEq, Clone, Default)]
|
||||
@ -30,7 +30,7 @@ impl SwapWindow {
|
||||
}
|
||||
|
||||
/// Displays this swap window
|
||||
pub fn display(&mut self, ctx: &egui::CtxRef, game_file: &GameFile) {
|
||||
pub fn display(&mut self, ctx: &egui::CtxRef, game_file: &Arc<GameFile>) {
|
||||
egui::Window::new("Swap screen").show(ctx, |ui| {
|
||||
ui.horizontal(|ui| {
|
||||
ui.label(self.first.as_str().unwrap_or("None"));
|
||||
@ -47,21 +47,30 @@ impl SwapWindow {
|
||||
|
||||
if ui.button("Swap").clicked() {
|
||||
match (&self.first, &self.second) {
|
||||
// If we got both, spawn the task to swap the files
|
||||
(SwapFileStatus::Set(lhs), SwapFileStatus::Set(rhs)) => {
|
||||
let lhs = Path::from_ascii(lhs).expect("Lhs path wasn't valid");
|
||||
let rhs = Path::from_ascii(rhs).expect("Rhs path wasn't valid");
|
||||
let lhs = lhs.clone();
|
||||
let rhs = rhs.clone();
|
||||
let game_file = Arc::clone(game_file);
|
||||
task::spawn(move || {
|
||||
// TODO: Use `PathBuf` once `dcb_io` supports it
|
||||
let lhs = Path::from_ascii(&lhs).expect("Lhs path wasn't valid");
|
||||
let rhs = Path::from_ascii(&rhs).expect("Rhs path wasn't valid");
|
||||
|
||||
let res: Result<_, anyhow::Error> = try {
|
||||
game_file.with_game_file(|mut game_file| {
|
||||
game_file.swap_files(lhs, rhs).context("Unable to swap files")
|
||||
})?;
|
||||
game_file.reload().context("Unable to reload the game")?;
|
||||
};
|
||||
// Try to swap them and reload the game file
|
||||
let res: Result<_, anyhow::Error> = try {
|
||||
game_file.with_game_file(|mut game_file| {
|
||||
game_file.swap_files(lhs, rhs).context("Unable to swap files")
|
||||
})?;
|
||||
game_file.reload().context("Unable to reload the game")?;
|
||||
};
|
||||
|
||||
match res {
|
||||
Ok(()) => alert::info("Successfully swapped!"),
|
||||
Err(err) => alert::error(&format!("Unable to swap files: {:?}", err)),
|
||||
}
|
||||
// Then alert the user
|
||||
match res {
|
||||
Ok(()) => alert::info("Successfully swapped {lhs} with {rhs}!"),
|
||||
Err(err) => alert::error(&format!("Unable to swap files: {:?}", err)),
|
||||
}
|
||||
});
|
||||
},
|
||||
_ => alert::warn("You must set both files before swapping"),
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user