Skip to content

Commit

Permalink
kill engines on tab close
Browse files Browse the repository at this point in the history
  • Loading branch information
franciscoBSalgueiro committed Oct 15, 2023
1 parent e36b65a commit 1f60af1
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 50 deletions.
26 changes: 26 additions & 0 deletions src-tauri/src/chess.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ impl EngineProcess {
self.stdin.write_all(b"stop\n").await?;
Ok(())
}

async fn kill(&mut self) -> Result<(), Error> {
self.stdin.write_all(b"quit\n").await?;
Ok(())
}
}

#[cfg(target_os = "windows")]
Expand Down Expand Up @@ -243,6 +248,27 @@ pub enum GoMode {
Infinite,
}

#[tauri::command]
#[specta::specta]
pub async fn kill_engines(tab: String, state: tauri::State<'_, AppState>) -> Result<(), Error> {
let keys: Vec<_> = state
.engine_processes
.iter()
.map(|x| x.key().clone())
.collect();
for key in keys.clone() {
if key.0 == tab {
{
let process = state.engine_processes.get_mut(&key).unwrap();
let mut process = process.lock().await;
process.kill().await?;
}
state.engine_processes.remove(&key).unwrap();
}
}
Ok(())
}

#[tauri::command]
#[specta::specta]
pub async fn stop_engine(
Expand Down
3 changes: 2 additions & 1 deletion src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use tauri::{
use tauri_plugin_log::LogTarget;

use crate::chess::{
analyze_game, get_engine_name, get_pieces_count, get_single_best_move, make_move,
analyze_game, get_engine_name, get_pieces_count, get_single_best_move, kill_engines, make_move,
make_random_move, put_piece, similar_structure, stop_engine, validate_fen,
};
use crate::db::{
Expand Down Expand Up @@ -163,6 +163,7 @@ fn main() {
get_best_moves,
analyze_game,
stop_engine,
kill_engines
))
.events(tauri_specta::collect_events!(BestMovesPayload));

Expand Down
95 changes: 52 additions & 43 deletions src/bindings.ts
Original file line number Diff line number Diff line change
@@ -1,47 +1,55 @@
// This file was generated by [tauri-specta](https://github.com/oscartbeaumont/tauri-specta). Do not edit this file manually.
// This file was generated by [tauri-specta](https://github.com/oscartbeaumont/tauri-specta). Do not edit this file manually.

export const commands = {
async closeSplashscreen(): Promise<null> {
return await TAURI_INVOKE("plugin:tauri-specta|close_splashscreen");
},
async findFidePlayer(player: string): Promise<__Result__<{ fideid: number; name: string; country: string; sex: string; title: string | null; w_title: string | null; o_title: string | null; foa_title: string | null; rating: number | null; games: number | null; k: number | null; rapid_rating: number | null; rapid_games: number | null; rapid_k: number | null; blitz_rating: number | null; blitz_games: number | null; blitz_k: number | null; birthday: number | null; flag: string | null } | null, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("plugin:tauri-specta|find_fide_player", { player }) };
} catch (e) {
if (e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async getBestMoves(engine: string, tab: string, goMode: GoMode, options: EngineOptions): Promise<__Result__<null, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("plugin:tauri-specta|get_best_moves", { engine, tab, goMode, options }) };
} catch (e) {
if (e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async analyzeGame(moves: string[], engine: string, goMode: GoMode, options: AnalysisOptions): Promise<__Result__<{ best: BestMoves; novelty: boolean }[], string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("plugin:tauri-specta|analyze_game", { moves, engine, goMode, options }) };
} catch (e) {
if (e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async stopEngine(engine: string, tab: string): Promise<__Result__<null, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("plugin:tauri-specta|stop_engine", { engine, tab }) };
} catch (e) {
if (e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
}
export const commands = {
async closeSplashscreen() : Promise<null> {
return await TAURI_INVOKE("plugin:tauri-specta|close_splashscreen");
},
async findFidePlayer(player: string) : Promise<__Result__<{ fideid: number; name: string; country: string; sex: string; title: string | null; w_title: string | null; o_title: string | null; foa_title: string | null; rating: number | null; games: number | null; k: number | null; rapid_rating: number | null; rapid_games: number | null; rapid_k: number | null; blitz_rating: number | null; blitz_games: number | null; blitz_k: number | null; birthday: number | null; flag: string | null } | null, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("plugin:tauri-specta|find_fide_player", { player }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async getBestMoves(engine: string, tab: string, goMode: GoMode, options: EngineOptions) : Promise<__Result__<null, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("plugin:tauri-specta|get_best_moves", { engine, tab, goMode, options }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async analyzeGame(moves: string[], engine: string, goMode: GoMode, options: AnalysisOptions) : Promise<__Result__<{ best: BestMoves; novelty: boolean }[], string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("plugin:tauri-specta|analyze_game", { moves, engine, goMode, options }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async stopEngine(engine: string, tab: string) : Promise<__Result__<null, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("plugin:tauri-specta|stop_engine", { engine, tab }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async killEngines(tab: string) : Promise<__Result__<null, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("plugin:tauri-specta|kill_engines", { tab }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
}
}

export const events = __makeEvents__<{
bestMovesPayload: BestMovesPayload
bestMovesPayload: BestMovesPayload
}>({
bestMovesPayload: "plugin:tauri-specta:best-moves-payload"
bestMovesPayload: "plugin:tauri-specta:best-moves-payload"
})

/** user-defined types **/
Expand All @@ -55,7 +63,7 @@ export type Score = { type: "cp"; value: number } | { type: "mate"; value: numbe

/** tauri-specta globals **/

import { invoke as TAURI_INVOKE } from "@tauri-apps/api";
import { invoke as TAURI_INVOKE } from "@tauri-apps/api";
import * as TAURI_API_EVENT from "@tauri-apps/api/event";
import { type WebviewWindowHandle as __WebviewWindowHandle__ } from "@tauri-apps/api/window";

Expand All @@ -67,8 +75,8 @@ type __EventObj__<T> = {
cb: TAURI_API_EVENT.EventCallback<T>
) => ReturnType<typeof TAURI_API_EVENT.once<T>>;
emit: T extends null
? (payload?: T) => ReturnType<typeof TAURI_API_EVENT.emit>
: (payload: T) => ReturnType<typeof TAURI_API_EVENT.emit>;
? (payload?: T) => ReturnType<typeof TAURI_API_EVENT.emit>
: (payload: T) => ReturnType<typeof TAURI_API_EVENT.emit>;
};

type __Result__<T, E> =
Expand All @@ -88,7 +96,7 @@ function __makeEvents__<T extends Record<string, any>>(
get: (_, event) => {
const name = mappings[event as keyof T];

return new Proxy((() => { }) as any, {
return new Proxy((() => {}) as any, {
apply: (_, __, [window]: [__WebviewWindowHandle__]) => ({
listen: (arg: any) => window.listen(name, arg),
once: (arg: any) => window.once(name, arg),
Expand All @@ -110,3 +118,4 @@ function __makeEvents__<T extends Record<string, any>>(
);
}


2 changes: 0 additions & 2 deletions src/components/panels/analysis/BestMoves.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,7 @@ export default function BestMovesComponent({

useEffect(() => {
async function waitForMove() {
console.log("waiting for move");
const unlisten = await events.bestMovesPayload.listen(({ payload }) => {
console.log("got move", payload);
const ev = payload.bestLines;
if (payload.engine === engine.path && payload.tab === activeTab) {
startTransition(() => {
Expand Down
10 changes: 6 additions & 4 deletions src/components/tabs/BoardsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import { activeTabAtom, tabsAtom } from "@/atoms/atoms";
import ConfirmChangesModal from "./ConfirmChangesModal";
import { match } from "ts-pattern";
import { Reorder } from "framer-motion";
import { commands } from "@/bindings";
import { unwrap } from "@/utils/invoke";

const useStyles = createStyles((theme) => ({
newTab: {
Expand All @@ -41,9 +43,10 @@ export default function BoardsPage() {
const { classes } = useStyles();
const [tabs, setTabs] = useAtom(tabsAtom);
const [activeTab, setActiveTab] = useAtom(activeTabAtom);
const [saveModalOpened, toggleSaveModal] = useToggle();

const closeTab = useCallback(
(value: string | null, forced?: boolean) => {
async (value: string | null, forced?: boolean) => {
if (value !== null) {
const closedTab = tabs.find((tab) => tab.value === value);
const tabState = JSON.parse(sessionStorage.getItem(value) || "{}");
Expand All @@ -63,9 +66,10 @@ export default function BoardsPage() {
}
}
setTabs((prev) => prev.filter((tab) => tab.value !== value));
unwrap(await commands.killEngines(value));
}
},
[tabs, activeTab, setTabs, setActiveTab]
[tabs, activeTab, setTabs, toggleSaveModal, setActiveTab]
);

function selectTab(index: number) {
Expand Down Expand Up @@ -165,8 +169,6 @@ export default function BoardsPage() {
["ctrl+9", () => selectTab(tabs.length - 1)],
]);

const [saveModalOpened, toggleSaveModal] = useToggle();

return (
<>
<ConfirmChangesModal
Expand Down

0 comments on commit 1f60af1

Please sign in to comment.