tundlebool/src/app_logic.rs

161 lines
4.9 KiB
Rust
Raw Normal View History

2025-04-18 00:15:28 +02:00
use std::{path::PathBuf, sync::Arc};
2025-04-15 18:08:34 +02:00
use crossbeam_channel::Receiver;
2025-04-18 00:15:28 +02:00
use egui::mutex::Mutex;
2025-04-17 00:39:10 +02:00
use log::{debug, info};
2025-04-15 18:08:34 +02:00
2025-04-18 00:15:28 +02:00
use crate::{config::{self, ConfigProvider}, mod_builder::ModConfiguration, omori_locator};
2025-04-15 18:08:34 +02:00
#[derive(Clone)]
pub enum UiState {
Loading,
2025-04-15 18:38:11 +02:00
KeyRequired(String),
2025-04-17 00:39:10 +02:00
PickGame(Result<PathBuf, String>, Vec<(PathBuf, u64)>),
2025-04-18 00:15:28 +02:00
PickPlaytest(Vec<(PathBuf, u64)>),
Configure(ModConfiguration),
2025-04-15 18:38:11 +02:00
Error(String)
2025-04-15 18:08:34 +02:00
}
#[derive(Clone)]
pub struct UiStateHolder {
pub state: Arc<Mutex<UiState>>
}
pub enum UiEvent {
2025-04-17 00:39:10 +02:00
SetKey(Vec<u8>),
UsePath(PathBuf),
2025-04-18 00:15:28 +02:00
UseSteamPath,
UseConfiguration(ModConfiguration)
2025-04-15 18:08:34 +02:00
}
pub struct AppThread {
ui_state: UiStateHolder,
context: egui::Context,
ui_event_channel: Receiver<UiEvent>,
decryption_key: Vec<u8>
}
impl AppThread {
fn commit(&self, s: UiState) {
let mut state = self.ui_state.state.lock();
*state = s;
2025-04-18 00:15:28 +02:00
drop(state);
self.context.request_repaint();
2025-04-15 18:08:34 +02:00
}
2025-04-18 00:15:28 +02:00
fn get_key(&self, reason: String) -> anyhow::Result<Vec<u8>> {
2025-04-15 18:08:34 +02:00
self.commit(UiState::KeyRequired(reason));
loop {
2025-04-15 18:38:11 +02:00
match self.ui_event_channel.recv()? {
2025-04-15 18:08:34 +02:00
UiEvent::SetKey(key) => {
2025-04-16 18:44:53 +02:00
self.commit(UiState::Loading);
return Ok(key);
2025-04-15 18:08:34 +02:00
}
_ => {}
}
}
}
2025-04-18 00:15:28 +02:00
fn pick_game(&self, provider: &mut ConfigProvider) -> anyhow::Result<PathBuf> {
2025-04-16 23:23:17 +02:00
let steam_location = match omori_locator::get_omori_path() {
Ok(l) => Ok(l),
Err(e) => Err(String::from(format!("{:#}", e)))
};
let location_history = provider.get_game_paths()?;
self.commit(UiState::PickGame(steam_location.clone(), location_history.clone()));
2025-04-17 00:39:10 +02:00
loop {
match self.ui_event_channel.recv()? {
UiEvent::UsePath(path) => {
provider.set_game_path_used(&path)?;
self.commit(UiState::Loading);
return Ok(path);
},
UiEvent::UseSteamPath => {
self.commit(UiState::Loading);
return Ok(steam_location.expect("The steam location was not set even if the UI told us to use it. This should never happen"));
}
_ => {}
}
}
2025-04-16 23:23:17 +02:00
}
2025-04-18 00:15:28 +02:00
fn pick_playtest(&self, provider: &mut ConfigProvider) -> anyhow::Result<PathBuf> {
let playtest_history = provider.get_playtest_paths()?;
self.commit(UiState::PickPlaytest(playtest_history.clone()));
loop {
match self.ui_event_channel.recv()? {
UiEvent::UsePath(path) => {
provider.set_playtest_path_used(&path)?;
self.commit(UiState::Loading);
return Ok(path);
},
_ => {}
}
}
}
fn configure_bundling(&self, provider: &mut ConfigProvider, path: &PathBuf) -> anyhow::Result<ModConfiguration> {
let configuration = provider.get_configuration_for_playtest(path);
self.commit(UiState::Configure(configuration));
loop {
match self.ui_event_channel.recv()? {
UiEvent::UseConfiguration(config) => {
provider.set_configuration_for_playtest(&path, &config)?;
self.commit(UiState::Loading);
return Ok(config);
},
_ => {}
}
}
}
2025-04-15 18:08:34 +02:00
pub fn create(state_holder: &UiStateHolder, context: &egui::Context, ui_event_channel: &Receiver<UiEvent>) -> AppThread {
AppThread {
ui_state: state_holder.clone(),
context: context.clone(),
ui_event_channel: ui_event_channel.clone(),
decryption_key: Vec::new()
}
}
2025-04-15 18:38:11 +02:00
fn real_main(&mut self) -> anyhow::Result<()> {
2025-04-16 23:23:17 +02:00
debug!("I am ALIVE! HAHAHAHA!");
2025-04-15 18:08:34 +02:00
self.commit(UiState::Loading);
2025-04-15 18:38:11 +02:00
let mut config_provider = config::ConfigProvider::new()?;
2025-04-16 18:44:53 +02:00
self.decryption_key = match config_provider.get_key() {
Some(key) => key,
None => match omori_locator::get_omori_key() {
Ok(key) => key,
Err(reason) => self.get_key(format!("{:#}", reason))?,
}
};
config_provider.set_key(&self.decryption_key)?;
2025-04-15 18:08:34 +02:00
2025-04-17 00:39:10 +02:00
let game_path = self.pick_game(&mut config_provider)?;
info!("Will use {:?}", game_path);
2025-04-16 23:23:17 +02:00
2025-04-18 00:15:28 +02:00
let playtest_path = self.pick_playtest(&mut config_provider)?;
info!("Playtest {:?}", playtest_path);
let config = self.configure_bundling(&mut config_provider, &playtest_path)?;
info!("Config {:?}", config);
2025-04-15 18:38:11 +02:00
Ok(())
}
pub fn main(&mut self) {
match self.real_main() {
Ok(_) => {},
2025-04-16 18:44:53 +02:00
Err(e) => self.commit(UiState::Error(format!("{:#}", e))),
2025-04-15 18:38:11 +02:00
}
2025-04-15 18:08:34 +02:00
}
}