Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

String settings hooks #82

Merged
merged 16 commits into from
Apr 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions theseus/src/api/jre.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
//! Authentication flow interface
use std::path::PathBuf;

use crate::{
launcher::download,
prelude::Profile,
Expand Down Expand Up @@ -139,3 +141,8 @@ pub async fn validate_globals() -> crate::Result<bool> {
let settings = state.settings.read().await;
Ok(settings.java_globals.is_all_valid())
}

// Validates JRE at a given at a given path
pub async fn check_jre(path: PathBuf) -> crate::Result<Option<JavaVersion>> {
Ok(jre::check_java_at_filepath(&path))
}
2 changes: 1 addition & 1 deletion theseus/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub mod tags;
pub mod data {
pub use crate::state::{
DirectoryInfo, Hooks, JavaSettings, MemorySettings, ModLoader,
ProfileMetadata, Settings, WindowSize,
ProfileMetadata, Settings, Theme, WindowSize,
};
}

Expand Down
4 changes: 2 additions & 2 deletions theseus/src/api/pack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,8 @@ async fn install_pack(
.await?;

let loading_bar = init_loading(
LoadingBarType::PackDownload {
pack_name ,
LoadingBarType::PackDownload {
pack_name,
pack_id: project_id,
pack_version: version_id,
},
Expand Down
86 changes: 51 additions & 35 deletions theseus/src/api/process.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! Theseus process management interface
use std::path::{Path, PathBuf};

use uuid::Uuid;

use crate::state::MinecraftChild;
pub use crate::{
state::{
Expand All @@ -9,31 +11,33 @@ pub use crate::{
State,
};

// Gets whether a child process stored in the state by PID has finished
// Gets whether a child process stored in the state by UUID has finished
#[tracing::instrument]
pub async fn has_finished_by_pid(pid: u32) -> crate::Result<bool> {
Ok(get_exit_status_by_pid(pid).await?.is_some())
pub async fn has_finished_by_uuid(uuid: &Uuid) -> crate::Result<bool> {
Ok(get_exit_status_by_uuid(uuid).await?.is_some())
}

// Gets the exit status of a child process stored in the state by PID
// Gets the exit status of a child process stored in the state by UUID
#[tracing::instrument]
pub async fn get_exit_status_by_pid(pid: u32) -> crate::Result<Option<i32>> {
pub async fn get_exit_status_by_uuid(
uuid: &Uuid,
) -> crate::Result<Option<i32>> {
let state = State::get().await?;
let children = state.children.read().await;
Ok(children.exit_status(&pid).await?.and_then(|f| f.code()))
Ok(children.exit_status(uuid).await?.and_then(|f| f.code()))
}

// Gets the PID of each stored process in the state
// Gets the UUID of each stored process in the state
#[tracing::instrument]
pub async fn get_all_pids() -> crate::Result<Vec<u32>> {
pub async fn get_all_uuids() -> crate::Result<Vec<Uuid>> {
let state = State::get().await?;
let children = state.children.read().await;
Ok(children.keys())
}

// Gets the PID of each *running* stored process in the state
// Gets the UUID of each *running* stored process in the state
#[tracing::instrument]
pub async fn get_all_running_pids() -> crate::Result<Vec<u32>> {
pub async fn get_all_running_uuids() -> crate::Result<Vec<Uuid>> {
let state = State::get().await?;
let children = state.children.read().await;
children.running_keys().await
Expand All @@ -55,62 +59,62 @@ pub async fn get_all_running_profiles() -> crate::Result<Vec<Profile>> {
children.running_profiles().await
}

// Gets the PID of each stored process in the state by profile path
// Gets the UUID of each stored process in the state by profile path
#[tracing::instrument]
pub async fn get_pids_by_profile_path(
pub async fn get_uuids_by_profile_path(
profile_path: &Path,
) -> crate::Result<Vec<u32>> {
) -> crate::Result<Vec<Uuid>> {
let state = State::get().await?;
let children = state.children.read().await;
children.running_keys_with_profile(profile_path).await
}

// Gets stdout of a child process stored in the state by PID, as a string
// Gets stdout of a child process stored in the state by UUID, as a string
#[tracing::instrument]
pub async fn get_stdout_by_pid(pid: u32) -> crate::Result<String> {
pub async fn get_stdout_by_uuid(uuid: &Uuid) -> crate::Result<String> {
let state = State::get().await?;
// Get stdout from child
let children = state.children.read().await;

// Extract child or return crate::Error
if let Some(child) = children.get(&pid) {
if let Some(child) = children.get(uuid) {
let child = child.read().await;
Ok(child.stdout.get_output().await?)
} else {
Err(crate::ErrorKind::LauncherError(format!(
"No child process with PID {}",
pid
"No child process by UUID {}",
uuid
))
.as_error())
}
}

// Gets stderr of a child process stored in the state by PID, as a string
// Gets stderr of a child process stored in the state by UUID, as a string
#[tracing::instrument]
pub async fn get_stderr_by_pid(pid: u32) -> crate::Result<String> {
pub async fn get_stderr_by_uuid(uuid: &Uuid) -> crate::Result<String> {
let state = State::get().await?;
// Get stdout from child
let children = state.children.read().await;

// Extract child or return crate::Error
if let Some(child) = children.get(&pid) {
if let Some(child) = children.get(uuid) {
let child = child.read().await;
Ok(child.stderr.get_output().await?)
} else {
Err(crate::ErrorKind::LauncherError(format!(
"No child process with PID {}",
pid
"No child process with UUID {}",
uuid
))
.as_error())
}
}

// Kill a child process stored in the state by PID, as a string
// Kill a child process stored in the state by UUID, as a string
#[tracing::instrument]
pub async fn kill_by_pid(pid: u32) -> crate::Result<()> {
pub async fn kill_by_uuid(uuid: &Uuid) -> crate::Result<()> {
let state = State::get().await?;
let children = state.children.read().await;
if let Some(mchild) = children.get(&pid) {
if let Some(mchild) = children.get(uuid) {
let mut mchild = mchild.write().await;
kill(&mut mchild).await
} else {
Expand All @@ -119,13 +123,13 @@ pub async fn kill_by_pid(pid: u32) -> crate::Result<()> {
}
}

// Wait for a child process stored in the state by PID
// Wait for a child process stored in the state by UUID
#[tracing::instrument]
pub async fn wait_for_by_pid(pid: u32) -> crate::Result<()> {
pub async fn wait_for_by_uuid(uuid: &Uuid) -> crate::Result<()> {
let state = State::get().await?;
let children = state.children.read().await;
// No error returned for already killed process
if let Some(mchild) = children.get(&pid) {
if let Some(mchild) = children.get(uuid) {
let mut mchild = mchild.write().await;
wait_for(&mut mchild).await
} else {
Expand All @@ -137,18 +141,30 @@ pub async fn wait_for_by_pid(pid: u32) -> crate::Result<()> {
// Kill a running child process directly, and wait for it to be killed
#[tracing::instrument]
pub async fn kill(running: &mut MinecraftChild) -> crate::Result<()> {
running.child.kill().await?;
running.current_child.write().await.kill().await?;
wait_for(running).await
}

// Await on the completion of a child process directly
#[tracing::instrument]
pub async fn wait_for(running: &mut MinecraftChild) -> crate::Result<()> {
let result = running.child.wait().await.map_err(|err| {
crate::ErrorKind::LauncherError(format!(
"Error running minecraft: {err}"
))
})?;
// We do not wait on the Child directly, but wait on the thread manager.
// This way we can still run all cleanup hook functions that happen after.
let result = running
.manager
.take()
.ok_or_else(|| {
crate::ErrorKind::LauncherError(format!(
"Process manager already completed or missing for process {}",
running.uuid
))
})?
.await?
.map_err(|err| {
crate::ErrorKind::LauncherError(format!(
"Error running minecraft: {err}"
))
})?;

match result.success() {
false => Err(crate::ErrorKind::LauncherError(format!(
Expand Down
Loading