Profile bindings (#55)

* basic framework. still has errors

* added functionality for main endpoints + some structuring

* formatting

* unused code

* mimicked CLI function with wait_for process

* made PR changes, added playground

* cargo fmt

* removed missed println

* misc tests fixes

* cargo fmt

* added windows support

* cargo fmt

* all OS use dunce

* restructured profile slightly; fixed mac bug

* profile changes, new main.rs

* fixed requested pr + canonicaliation bug

* fixed regressed bug in ui

* fixed regressed bugs

* fixed git error

* typo

* ran prettier

* clippy

* playground clippy

* ported profile loading fix

* profile change for real, url println and clippy

* PR changes

---------

Co-authored-by: Wyatt <wyatt@modrinth.com>
This commit is contained in:
Wyatt Verchere
2023-03-31 11:00:43 -07:00
committed by GitHub
parent 24ba986cf1
commit f48959a816
30 changed files with 857 additions and 80 deletions

View File

@@ -0,0 +1,37 @@
use std::{collections::HashMap, sync::Arc};
use tokio::process::Child;
use tokio::sync::RwLock;
// Child processes (instances of Minecraft)
// A wrapper over a Hashmap connecting PID -> Child
// Left open for future functionality re: polling children
pub struct Children(HashMap<u32, Arc<RwLock<Child>>>);
impl Children {
pub fn new() -> Children {
Children(HashMap::new())
}
// Inserts and returns a ref to the child
// Unlike a Hashmap, this directly returns the reference to the Child rather than any previously stored Child that may exist
pub fn insert(
&mut self,
pid: u32,
child: tokio::process::Child,
) -> Arc<RwLock<Child>> {
let child = Arc::new(RwLock::new(child));
self.0.insert(pid, child.clone());
child
}
// Returns a ref to the child
pub fn get(&self, pid: &u32) -> Option<Arc<RwLock<Child>>> {
self.0.get(pid).cloned()
}
}
impl Default for Children {
fn default() -> Self {
Self::new()
}
}

View File

@@ -110,6 +110,12 @@ impl DirectoryInfo {
self.config_dir.join("icons")
}
/// Get the profiles directory for created profiles
#[inline]
pub fn profiles_dir(&self) -> PathBuf {
self.config_dir.join("profiles")
}
/// Get the file containing the global database
#[inline]
pub fn database_file(&self) -> PathBuf {

View File

@@ -22,6 +22,9 @@ pub use self::projects::*;
mod users;
pub use self::users::*;
mod children;
pub use self::children::*;
// Global state
static LAUNCHER_STATE: OnceCell<Arc<State>> = OnceCell::const_new();
pub struct State {
@@ -36,6 +39,8 @@ pub struct State {
// TODO: settings API
/// Launcher configuration
pub settings: RwLock<Settings>,
/// Reference to process children
pub children: RwLock<Children>,
/// Launcher profile metadata
pub(crate) profiles: RwLock<Profiles>,
/// Launcher user account info
@@ -73,6 +78,8 @@ impl State {
let io_semaphore =
Semaphore::new(settings.max_concurrent_downloads);
let children = Children::new();
Ok(Arc::new(Self {
database,
directories,
@@ -81,6 +88,7 @@ impl State {
settings: RwLock::new(settings),
profiles: RwLock::new(profiles),
users: RwLock::new(users),
children: RwLock::new(children),
}))
}
})

View File

@@ -3,6 +3,7 @@ use crate::config::BINCODE_CONFIG;
use crate::data::DirectoryInfo;
use crate::state::projects::Project;
use daedalus::modded::LoaderVersion;
use dunce::canonicalize;
use futures::prelude::*;
use serde::{Deserialize, Serialize};
use std::{
@@ -98,7 +99,7 @@ impl Profile {
}
Ok(Self {
path: path.canonicalize()?,
path: canonicalize(path)?,
metadata: ProfileMetadata {
name,
icon: None,
@@ -236,10 +237,13 @@ impl Profiles {
{
for (profile_path, _profile_opt) in profiles.iter() {
let mut read_paths = |path: &str| {
for path in std::fs::read_dir(profile_path.join(path))? {
files.insert(path?.path(), profile_path.clone());
let new_path = profile_path.join(path);
if new_path.exists() {
for path in std::fs::read_dir(profile_path.join(path))?
{
files.insert(path?.path(), profile_path.clone());
}
}
Ok::<(), crate::Error>(())
};
read_paths("mods")?;
@@ -268,9 +272,7 @@ impl Profiles {
#[tracing::instrument(skip(self))]
pub fn insert(&mut self, profile: Profile) -> crate::Result<&Self> {
self.0.insert(
profile
.path
.canonicalize()?
canonicalize(&profile.path)?
.to_str()
.ok_or(
crate::ErrorKind::UTFError(profile.path.clone()).as_error(),
@@ -286,12 +288,12 @@ impl Profiles {
&'a mut self,
path: &'a Path,
) -> crate::Result<&Self> {
self.insert(Self::read_profile_from_dir(&path.canonicalize()?).await?)
self.insert(Self::read_profile_from_dir(&canonicalize(path)?).await?)
}
#[tracing::instrument(skip(self))]
pub fn remove(&mut self, path: &Path) -> crate::Result<&Self> {
let path = PathBuf::from(path.canonicalize()?.to_str().unwrap());
let path = PathBuf::from(&canonicalize(path)?.to_str().unwrap());
self.0.remove(&path);
Ok(self)
}