feat: Get instance by ID

This commit is contained in:
LynithDev 2024-03-24 12:18:26 +01:00
parent 3fecf109c4
commit 1cf4852a78
6 changed files with 62 additions and 23 deletions

View file

@ -1,5 +1,5 @@
// Authentication and HTTP (TODO: env?)
pub const APP_CONFIG_DIR: &str = "org.polyfrost.onelauncher";
pub const APP_CONFIG_DIR: &str = "org.polyfrost.launcher";
pub const USER_AGENT: &str = "OneLauncher/1.0.0 (polyfrost.org)";
// Microsoft Authentication

View file

@ -4,6 +4,7 @@ use anyhow::anyhow;
use async_trait::async_trait;
use chrono::{DateTime, Local};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use thiserror::Error;
use uuid::Uuid;
use crate::{utils::dirs, PolyResult};
@ -51,13 +52,14 @@ impl ClientType {
}
}
pub fn get_impl<'a>(client: &'a ClientType, instance: &'a Instance, manifest: &'a Manifest) -> Box<dyn ClientTrait<'a> + 'a> {
Box::new(match client {
ClientType::Vanilla(_) => vanilla::VanillaClient::new(instance, manifest)
})
}
#[async_trait]
pub trait ClientTrait<'a>: Send + Sync {
fn get_impl(client: &'a ClientType, instance: &'a Instance, manifest: &'a Manifest) -> Box<dyn ClientTrait<'a> + 'a> where Self: Sized {
Box::new(match client {
ClientType::Vanilla(_) => vanilla::VanillaClient::new(instance, manifest)
})
}
fn new(instance: &'a Instance, manifest: &'a Manifest) -> Self where Self: Sized;
@ -103,6 +105,14 @@ macro_rules! impl_game_client {
};
}
#[derive(Debug, Error)]
pub enum ClientManagerError {
#[error("Instance not found")]
InstanceNotFound,
#[error("Manifest not found")]
ManifestNotFound,
}
pub struct ClientManager {
instances: HashMap<Uuid, Instance>,
manifests: HashMap<Uuid, Manifest>,
@ -124,6 +134,13 @@ impl ClientManager {
})
}
pub fn get_impl_uuid<'a>(&'a self, uuid: Uuid) -> PolyResult<Box<dyn ClientTrait<'a> + 'a>> {
let instance = self.get_instance(uuid)?;
let manifest = self.get_manifest(uuid)?;
Ok(get_impl(&instance.client, &instance, &manifest))
}
pub fn get_instances(&self) -> Vec<&Instance> {
self.instances.values().collect()
}
@ -132,20 +149,20 @@ impl ClientManager {
self.instances.values().cloned().collect()
}
pub fn get_instance(&self, uuid: Uuid) -> Option<&Instance> {
self.instances.get(&uuid)
pub fn get_instance(&self, uuid: Uuid) -> PolyResult<&Instance> {
self.instances.get(&uuid).ok_or(ClientManagerError::InstanceNotFound.into())
}
pub fn get_instance_mut(&mut self, uuid: Uuid) -> Option<&mut Instance> {
self.instances.get_mut(&uuid)
pub fn get_instance_mut(&mut self, uuid: Uuid) -> PolyResult<&mut Instance> {
self.instances.get_mut(&uuid).ok_or(ClientManagerError::InstanceNotFound.into())
}
pub fn get_manifest(&self, uuid: Uuid) -> Option<&Manifest> {
self.manifests.get(&uuid)
pub fn get_manifest(&self, uuid: Uuid) -> PolyResult<&Manifest> {
self.manifests.get(&uuid).ok_or(ClientManagerError::ManifestNotFound.into())
}
pub fn get_manifest_mut(&mut self, uuid: Uuid) -> Option<&mut Manifest> {
self.manifests.get_mut(&uuid)
pub fn get_manifest_mut(&mut self, uuid: Uuid) -> PolyResult<&mut Manifest> {
self.manifests.get_mut(&uuid).ok_or(ClientManagerError::ManifestNotFound.into())
}
pub async fn create_instance(&mut self,

View file

@ -59,6 +59,16 @@ pub enum PolyError {
/// Wrapper around [`utils::dirs::DirectoryError`] to handle directory errors.
#[error("failed to get directory: {0}")]
DirectoryError(#[from] utils::dirs::DirectoryError),
/// Wrapper around [`game::client::ClientManagerError`] to handle directory errors.
#[error("failed to manage clients: {0}")]
ClientManagerError(#[from] game::client::ClientManagerError),
}
impl From<PolyError> for String {
fn from(value: PolyError) -> Self {
value.to_string()
}
}
/// Alias for a [`Result`] with the error type [`PolyError`].

View file

@ -15,15 +15,24 @@ pub async fn create_instance(
client: ClientType
) -> Result<Uuid, String> {
let manager = &mut state.lock().await.client_manager;
manager.create_instance(name, version, cover, group, client).await.or_else(|e| {
Err(e.to_string())
})
let uuid = manager.create_instance(name, version, cover, group, client).await?;
Ok(uuid)
}
#[tauri::command]
pub async fn get_instances(state: State<'_, Mutex<GameManagerState>>) -> Result<Vec<Instance>, String> {
pub async fn get_instances(
state: State<'_, Mutex<GameManagerState>>
) -> Result<Vec<Instance>, String> {
let manager = &mut state.lock().await.client_manager;
Ok(manager.get_instances_owned())
}
#[tauri::command]
pub async fn get_instance(
state: State<'_, Mutex<GameManagerState>>,
uuid: Uuid
) -> Result<Instance, String> {
let manager = &mut state.lock().await.client_manager;
let instance = manager.get_instance(uuid)?;
Ok(instance.clone())
}

View file

@ -25,6 +25,7 @@ pub fn init() -> TauriPlugin<tauri::Wry> {
auth::login_msa,
game::create_instance,
game::get_instances,
game::get_instance,
])
.build()
}

View file

@ -8,9 +8,11 @@ function BrowserPage() {
<Button
// eslint-disable-next-line solid/reactivity
onClick={async () => {
await invoke('plugin:launcher-core|launch_game');
const result = await invoke('plugin:launcher-core|get_instance', {
uuid: 'de69f608-c8de-4cb5-a295-8747dc05380a',
});
// eslint-disable-next-line no-console
console.log(`Game exited`);
console.log(result);
}}
>
Test Button
@ -18,7 +20,7 @@ function BrowserPage() {
<Button
onClick={async () => {
const result = invoke('plugin:launcher-core|get_instances');
const result = await invoke('plugin:launcher-core|get_instances');
console.log(result);
}}
>