API improvements

- added `Archive.closeStreams()` method to close all the unpacking streams
- added `Downloader.closeStreams()` method to close all the downloading streams
- added the same methods to the streams itself
- fixed launch button events execution
- added prefix creation during the game installation/updagin
  if it is not created
- added some hack to the `Process.running()` method to show that the process
  is not running if it is a zombie
This commit is contained in:
Observer KRypt0n_ 2021-12-27 00:27:39 +02:00
parent e8c721dc93
commit 68d766da58
No known key found for this signature in database
GPG key ID: DC5D4EC1303465DA
8 changed files with 145 additions and 33 deletions

View file

@ -27,7 +27,7 @@
"maximize": false,
"hidden": true,
"resizable": false,
"exitProcessOnClose": true
"exitProcessOnClose": false
},
"browser": {},
"cloud": {}

View file

@ -1,11 +1,21 @@
import '../i18n';
import App from '../index.svelte';
import Archive from '../ts/core/Archive';
import Downloader from '../ts/core/Downloader';
declare const Neutralino;
Neutralino.init();
Neutralino.events.on('ready', () => import('../defaultSettings'));
Neutralino.events.on('windowClose', () => {
Downloader.closeStreams(true);
Archive.closeStreams(true);
Neutralino.app.exit();
});
const app = new App({
target: document.getElementById('app')!
});

View file

@ -21,7 +21,7 @@ export default class Launcher
this.progressBar = new ProgressBar(this);
// Progress bar test
this.progressBar.init({
/*this.progressBar.init({
label: 'Abobus',
showSpeed: true,
showEta: true,
@ -42,7 +42,7 @@ export default class Launcher
}
};
t(0);
t(0);*/
});
}

View file

@ -10,6 +10,16 @@ declare const NL_CWD;
class Stream
{
protected _id: number = -1;
/**
* ID of the archive unpacker process
*/
public get id(): number
{
return this._id;
}
/**
* The interval in ms between progress event calls
*/
@ -67,6 +77,8 @@ class Stream
Neutralino.os.execCommand(command, {
background: true
}).then((result) => {
this._id = result.pid;
});
const updateProgress = async () => {
@ -156,10 +168,20 @@ class Stream
if (this.throwedError)
callback();
}
/**
* Close unpacking stream
*/
public close(forced: boolean = false)
{
Neutralino.os.execCommand(`kill ${forced ? '-9' : '-15'} ${this._id}`);
}
}
export default class Archive
{
protected static streams: Stream[] = [];
/**
* Get type of archive
*
@ -259,7 +281,23 @@ export default class Archive
*/
public static unpack(path: string, unpackDir: string|null = null): Promise<Stream>
{
return new Promise((resolve) => resolve(new Stream(path, unpackDir)));
return new Promise((resolve) => {
const stream = new Stream(path, unpackDir);
this.streams.push(stream);
resolve(stream);
});
}
/**
* Close every open archive unpacking stream
*/
public static closeStreams(forced: boolean = false)
{
this.streams.forEach((stream) => {
stream.close(forced);
});
}
}

View file

@ -4,6 +4,16 @@ declare const Neutralino;
class Stream
{
protected _id: number = -1;
/**
* ID of the curl process
*/
public get id(): number
{
return this._id;
}
/**
* The interval in ms between progress event calls
*/
@ -31,12 +41,14 @@ class Stream
Neutralino.os.execCommand(`curl -s -L -N -o "${output}" "${uri}"`, {
background: true
}).then((result) => {
this._id = result.pid;
});
const updateProgress = () => {
Neutralino.filesystem.getStats(output).then((stats) => {
if (this.onProgress)
this.onProgress(stats.size, this.total, this.previous - stats.size);
this.onProgress(stats.size, this.total, stats.size - this.previous);
this.previous = stats.size;
@ -94,10 +106,20 @@ class Stream
if (this.finished)
callback();
}
/**
* Close downloading stream
*/
public close(forced: boolean = false)
{
Neutralino.os.execCommand(`kill ${forced ? '-9' : '-15'} ${this._id}`);
}
}
export default class Downloader
{
protected static streams: Stream[] = [];
/**
* Download file
*
@ -110,11 +132,28 @@ export default class Downloader
{
return new Promise(async (resolve) => {
fetch(uri).then((response) => {
resolve(new Stream(uri, output ?? this.fileFromUri(uri), response.length!));
const stream = new Stream(uri, output ?? this.fileFromUri(uri), response.length!);
this.streams.push(stream);
resolve(stream);
});
});
}
/**
* Close every open downloading stream
*/
public static closeStreams(forced: boolean = false)
{
this.streams.forEach((stream) => {
stream.close(forced);
});
}
/**
* Get a file name from the URI
*/
public static fileFromUri(uri: string): string
{
const file = uri.split('/').pop()!.split('#')[0].split('?')[0];

View file

@ -8,12 +8,12 @@ export default class State
public launchButton: HTMLElement;
protected _state: LauncherState = 'game-launch-available';
protected _state: LauncherState = 'game-installation-available';
protected events = {
'game-launch-available': import('./states/Launch'),
'game-install-available': import('./states/Install'),
'game-installation-available': import('./states/Install'),
'game-update-available': import('./states/Install')
};
@ -25,7 +25,7 @@ export default class State
this.launchButton.onclick = () => {
if (this.events[this._state])
this.events[this._state].then((event) => event.default());
this.events[this._state].then((event) => event.default(this.launcher));
};
}

View file

@ -1,39 +1,64 @@
import type Launcher from '../../Launcher';
import Game from '../../Game';
import constants from '../../Constants';
import Runners from '../../core/Runners';
declare const Neutralino;
export default (launcher: Launcher): Promise<void> => {
return new Promise(async (resolve) => {
Game.update(await Game.current).then((stream) => {
launcher.progressBar?.init({
label: 'Downloading game...',
showSpeed: true,
showEta: true,
showPercents: true,
showTotals: true
const prefixDir = await constants.paths.prefix.current;
Neutralino.filesystem.getStats(prefixDir)
.then(() => updateGame())
.catch(() => {
Runners.createPrefix(prefixDir).then((result) => {
if (result === true)
updateGame();
else
{
// TODO
console.error('There\'s no wine version installed to use to create the prefix');
resolve();
}
});
});
stream?.downloadStart(() => launcher.progressBar?.show());
stream?.downloadProgress((current: number, total: number, difference: number) => {
launcher.progressBar?.update(current, total, difference);
});
stream?.unpackStart(() => {
const updateGame = async () => {
Game.update(await Game.current).then((stream) => {
launcher.progressBar?.init({
label: 'Unpacking game...',
label: 'Downloading game...',
showSpeed: true,
showEta: true,
showPercents: true,
showTotals: true
});
stream?.downloadStart(() => launcher.progressBar?.show());
stream?.downloadProgress((current: number, total: number, difference: number) => {
launcher.progressBar?.update(current, total, difference);
});
stream?.unpackStart(() => {
launcher.progressBar?.init({
label: 'Unpacking game...',
showSpeed: true,
showEta: true,
showPercents: true,
showTotals: true
});
});
stream?.unpackProgress((current: number, total: number, difference: number) => {
launcher.progressBar?.update(current, total, difference);
});
stream?.unpackFinish(() => resolve());
});
stream?.unpackProgress((current: number, total: number, difference: number) => {
launcher.progressBar?.update(current, total, difference);
});
stream?.unpackFinish(() => resolve());
});
};
});
};

View file

@ -106,8 +106,8 @@ class Process
public running(): Promise<boolean>
{
return new Promise((resolve) => {
Neutralino.os.execCommand(`ps -p ${this.id}`).then((output) => {
resolve(output.stdOut.includes(this.id));
Neutralino.os.execCommand(`ps -p ${this.id} -S`).then((output) => {
resolve(output.stdOut.includes(this.id) && !output.stdOut.includes('Z '));
});
});
}