mirror of
https://github.com/open-goal/launcher.git
synced 2024-10-19 14:47:36 -04:00
advanced: attempt to open a REPL on linux/macOS (#571)
Fixes #85 --------- Co-authored-by: Hat Kid <6624576+Hat-Kid@users.noreply.github.com>
This commit is contained in:
parent
135f200f4a
commit
465092d965
20
README.md
20
README.md
|
@ -6,12 +6,14 @@ Our attempt at distributing the [OpenGOAL](https://github.com/open-goal/jak-proj
|
||||||
|
|
||||||
The launcher uses the [Tauri](https://tauri.app/) framework.
|
The launcher uses the [Tauri](https://tauri.app/) framework.
|
||||||
|
|
||||||
- [Usage](#usage)
|
- [OpenGOAL Launcher](#opengoal-launcher)
|
||||||
- [Asking for help](#asking-for-help)
|
- [Usage](#usage)
|
||||||
- [Development](#development)
|
- [Asking for help](#asking-for-help)
|
||||||
- [Windows](#windows)
|
- [Development](#development)
|
||||||
- [Linux (Ubuntu 22.04)](#linux-ubuntu-2204)
|
- [Windows](#windows)
|
||||||
- [Building and Running](#building-and-running)
|
- [Linux (Ubuntu 22.04)](#linux-ubuntu-2204)
|
||||||
|
- [macOS](#macos)
|
||||||
|
- [Building and Running](#building-and-running)
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
@ -53,6 +55,12 @@ nvm install lts/hydrogen # installs latest nodejs 18.X
|
||||||
npm install -g yarn
|
npm install -g yarn
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### macOS
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install -g yarn
|
||||||
|
```
|
||||||
|
|
||||||
### Building and Running
|
### Building and Running
|
||||||
|
|
||||||
To build and run the application locally, all you have to do is run:
|
To build and run the application locally, all you have to do is run:
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
|
io::ErrorKind,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
process::Stdio,
|
process::Stdio,
|
||||||
time::Instant,
|
time::Instant,
|
||||||
|
@ -37,6 +38,12 @@ struct CommonConfigData {
|
||||||
tooling_version: Version,
|
tooling_version: Version,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, serde::Serialize)]
|
||||||
|
struct ToastPayload {
|
||||||
|
toast: String,
|
||||||
|
level: String,
|
||||||
|
}
|
||||||
|
|
||||||
fn common_prelude(
|
fn common_prelude(
|
||||||
config: &tokio::sync::MutexGuard<LauncherConfig>,
|
config: &tokio::sync::MutexGuard<LauncherConfig>,
|
||||||
) -> Result<CommonConfigData, CommandError> {
|
) -> Result<CommonConfigData, CommandError> {
|
||||||
|
@ -574,33 +581,66 @@ pub async fn run_compiler(
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn open_repl(
|
pub async fn open_repl(
|
||||||
config: tauri::State<'_, tokio::sync::Mutex<LauncherConfig>>,
|
config: tauri::State<'_, tokio::sync::Mutex<LauncherConfig>>,
|
||||||
|
app_handle: tauri::AppHandle,
|
||||||
game_name: String,
|
game_name: String,
|
||||||
) -> Result<(), CommandError> {
|
) -> Result<(), CommandError> {
|
||||||
// TODO - explore a linux option though this is very annoying because without doing a ton of research
|
|
||||||
// we seem to have to handle various terminals. Which honestly we should probably do on windows too
|
|
||||||
//
|
|
||||||
// So maybe we can make a menu where the user will specify what terminal to use / what launch-options to use
|
|
||||||
let config_lock = config.lock().await;
|
let config_lock = config.lock().await;
|
||||||
let config_info = common_prelude(&config_lock)?;
|
let config_info = common_prelude(&config_lock)?;
|
||||||
|
|
||||||
let data_folder = get_data_dir(&config_info, &game_name, false)?;
|
let data_folder = get_data_dir(&config_info, &game_name, false)?;
|
||||||
let exec_info = get_exec_location(&config_info, "goalc")?;
|
let exec_info = get_exec_location(&config_info, "goalc")?;
|
||||||
let mut command = Command::new("cmd");
|
let mut command;
|
||||||
command
|
|
||||||
.args([
|
|
||||||
"/K",
|
|
||||||
"start",
|
|
||||||
&bin_ext("goalc"),
|
|
||||||
"--proj-path",
|
|
||||||
&data_folder.to_string_lossy(),
|
|
||||||
])
|
|
||||||
.current_dir(exec_info.executable_dir);
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
command.creation_flags(0x08000000);
|
command = Command::new("cmd");
|
||||||
|
command
|
||||||
|
.args([
|
||||||
|
"/K",
|
||||||
|
"start",
|
||||||
|
&bin_ext("goalc"),
|
||||||
|
"--proj-path",
|
||||||
|
&data_folder.to_string_lossy(),
|
||||||
|
])
|
||||||
|
.current_dir(exec_info.executable_dir)
|
||||||
|
.creation_flags(0x08000000);
|
||||||
|
}
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
{
|
||||||
|
command = Command::new("xdg-terminal-exec");
|
||||||
|
command
|
||||||
|
.args(["./goalc", "--proj-path", &data_folder.to_string_lossy()])
|
||||||
|
.current_dir(exec_info.executable_dir);
|
||||||
|
}
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
{
|
||||||
|
command = Command::new("osascript");
|
||||||
|
command
|
||||||
|
.args([
|
||||||
|
"-e",
|
||||||
|
"'tell app \"Terminal\" to do script",
|
||||||
|
format!("\"cd {:?}\" &&", exec_info.executable_dir).as_str(),
|
||||||
|
"./goalc",
|
||||||
|
"--proj-path",
|
||||||
|
&data_folder.to_string_lossy(),
|
||||||
|
])
|
||||||
|
.current_dir(exec_info.executable_dir);
|
||||||
|
}
|
||||||
|
match command.spawn() {
|
||||||
|
Ok(_) => Ok(()),
|
||||||
|
Err(e) => {
|
||||||
|
if let ErrorKind::NotFound = e.kind() {
|
||||||
|
let _ = app_handle.emit_all(
|
||||||
|
"toast_msg",
|
||||||
|
ToastPayload {
|
||||||
|
toast: format!("'{:?}' not found in PATH!", command.get_program()),
|
||||||
|
level: "error".to_string(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return Err(CommandError::BinaryExecution(
|
||||||
|
"Unable to launch REPL".to_owned(),
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
command.spawn()?;
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
@ -748,12 +788,6 @@ pub async fn get_launch_game_string(
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, serde::Serialize)]
|
|
||||||
struct ToastPayload {
|
|
||||||
toast: String,
|
|
||||||
level: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn launch_game(
|
pub async fn launch_game(
|
||||||
config: tauri::State<'_, tokio::sync::Mutex<LauncherConfig>>,
|
config: tauri::State<'_, tokio::sync::Mutex<LauncherConfig>>,
|
||||||
|
|
|
@ -195,9 +195,17 @@ pub async fn is_avx_requirement_met(
|
||||||
}
|
}
|
||||||
match config_lock.requirements.avx {
|
match config_lock.requirements.avx {
|
||||||
None => {
|
None => {
|
||||||
if is_x86_feature_detected!("avx") || is_x86_feature_detected!("avx2") {
|
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||||
config_lock.requirements.avx = Some(true);
|
{
|
||||||
} else {
|
if is_x86_feature_detected!("avx") || is_x86_feature_detected!("avx2") {
|
||||||
|
config_lock.requirements.avx = Some(true);
|
||||||
|
} else {
|
||||||
|
config_lock.requirements.avx = Some(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
|
||||||
|
{
|
||||||
|
// TODO - macOS check if on atleast sequoia and rosetta 2 is installed
|
||||||
config_lock.requirements.avx = Some(false);
|
config_lock.requirements.avx = Some(false);
|
||||||
}
|
}
|
||||||
config_lock.save_config().map_err(|err| {
|
config_lock.save_config().map_err(|err| {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { getInternalName, SupportedGame } from "$lib/constants";
|
import { getInternalName, SupportedGame } from "$lib/constants";
|
||||||
import { openDir } from "$lib/rpc/window";
|
import { openDir } from "$lib/rpc/window";
|
||||||
import IconArrowLeft from "~icons/mdi/arrow-left";
|
|
||||||
import IconCog from "~icons/mdi/cog";
|
import IconCog from "~icons/mdi/cog";
|
||||||
import { configDir, join } from "@tauri-apps/api/path";
|
import { configDir, join } from "@tauri-apps/api/path";
|
||||||
import { createEventDispatcher, onMount } from "svelte";
|
import { createEventDispatcher, onMount } from "svelte";
|
||||||
|
@ -27,7 +26,6 @@
|
||||||
import { navigate } from "svelte-navigator";
|
import { navigate } from "svelte-navigator";
|
||||||
import { listen } from "@tauri-apps/api/event";
|
import { listen } from "@tauri-apps/api/event";
|
||||||
import { toastStore } from "$lib/stores/ToastStore";
|
import { toastStore } from "$lib/stores/ToastStore";
|
||||||
import { launchMod } from "$lib/rpc/features";
|
|
||||||
|
|
||||||
export let activeGame: SupportedGame;
|
export let activeGame: SupportedGame;
|
||||||
|
|
||||||
|
@ -167,13 +165,11 @@
|
||||||
launchGame(getInternalName(activeGame), true);
|
launchGame(getInternalName(activeGame), true);
|
||||||
}}>{$_("gameControls_button_playInDebug")}</DropdownItem
|
}}>{$_("gameControls_button_playInDebug")}</DropdownItem
|
||||||
>
|
>
|
||||||
{#if !isLinux}
|
<DropdownItem
|
||||||
<DropdownItem
|
on:click={async () => {
|
||||||
on:click={async () => {
|
openREPL(getInternalName(activeGame));
|
||||||
openREPL(getInternalName(activeGame));
|
}}>{$_("gameControls_button_openREPL")}</DropdownItem
|
||||||
}}>{$_("gameControls_button_openREPL")}</DropdownItem
|
>
|
||||||
>
|
|
||||||
{/if}
|
|
||||||
<DropdownDivider />
|
<DropdownDivider />
|
||||||
<DropdownItem
|
<DropdownItem
|
||||||
on:click={async () => {
|
on:click={async () => {
|
||||||
|
|
|
@ -330,13 +330,11 @@
|
||||||
launchMod(getInternalName(activeGame), true, modName, modSource);
|
launchMod(getInternalName(activeGame), true, modName, modSource);
|
||||||
}}>{$_("gameControls_button_playInDebug")}</DropdownItem
|
}}>{$_("gameControls_button_playInDebug")}</DropdownItem
|
||||||
>
|
>
|
||||||
{#if !isLinux}
|
<DropdownItem
|
||||||
<DropdownItem
|
on:click={async () => {
|
||||||
on:click={async () => {
|
openREPLForMod(getInternalName(activeGame), modName, modSource);
|
||||||
openREPLForMod(getInternalName(activeGame), modName, modSource);
|
}}>{$_("gameControls_button_openREPL")}</DropdownItem
|
||||||
}}>{$_("gameControls_button_openREPL")}</DropdownItem
|
>
|
||||||
>
|
|
||||||
{/if}
|
|
||||||
<DropdownDivider />
|
<DropdownDivider />
|
||||||
<DropdownItem
|
<DropdownItem
|
||||||
on:click={async () => {
|
on:click={async () => {
|
||||||
|
|
Loading…
Reference in a new issue