Skip to content

Commit 94ec091

Browse files
committed
Add multithreading and fix modal
1 parent 3010388 commit 94ec091

7 files changed

Lines changed: 186 additions & 170 deletions

File tree

electron/index.ts

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
// Native
2-
import { join } from 'path';
2+
import path from 'path';
33

44
// Packages
55
import { BrowserWindow, app, ipcMain, IpcMainEvent, dialog } from 'electron';
66
import isDev from 'electron-is-dev';
77

8-
import { translate } from './scripts/translate';
8+
const { Worker } = require('worker_threads');
99

1010
const height = 800;
1111
const width = 1280;
@@ -20,12 +20,13 @@ function createWindow() {
2020
resizable: true,
2121
fullscreenable: true,
2222
webPreferences: {
23-
preload: join(__dirname, 'preload.js')
23+
preload: path.join(__dirname, 'preload.js'),
24+
nodeIntegrationInWorker: true
2425
}
2526
});
2627

2728
const port = process.env.PORT || 3000;
28-
const url = isDev ? `http://localhost:${port}` : join(__dirname, '../src/out/index.html');
29+
const url = isDev ? `http://localhost:${port}` : path.join(__dirname, '../src/out/index.html');
2930

3031
// and load the index.html of the app.
3132
if (isDev) {
@@ -34,7 +35,7 @@ function createWindow() {
3435
window?.loadFile(url);
3536
}
3637
// Open the DevTools.
37-
// window.webContents.openDevTools({ mode: 'detach' });
38+
window.webContents.openDevTools({ mode: 'detach' });
3839

3940
ipcMain.on('openDialog', () => {
4041
dialog
@@ -47,7 +48,29 @@ function createWindow() {
4748
.catch((err) => console.log(err));
4849
});
4950
ipcMain.on('translate', (event: IpcMainEvent, request: any) => {
50-
translate(request).then((result) => event.sender.send('translate', result));
51+
const workerPath = path.resolve(__dirname, 'worker.js');
52+
const worker = new Worker(workerPath);
53+
54+
// Envoie la requête de traduction au worker
55+
worker.postMessage(request);
56+
57+
// Récupère les logs une fois la traduction terminée
58+
worker.on('message', (result: any) => {
59+
event.sender.send('translate', result);
60+
});
61+
62+
// Gestion des erreurs
63+
worker.on('error', (error: any) => {
64+
console.error('Worker error:', error);
65+
event.sender.send('translate', { success: false, error });
66+
});
67+
68+
// Gestion de la fin du worker
69+
worker.on('exit', (code: any) => {
70+
if (code !== 0) {
71+
console.error(`Worker stopped with exit code ${code}`);
72+
}
73+
});
5174
});
5275
}
5376

electron/preload.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@ const api = {
2525
LaunchTranslation: (request: typeof requestInterface) => {
2626
ipcRenderer.send('translate', request);
2727
},
28-
/**
29-
* Provide an easier way to listen to events
30-
*/
3128
on: (channel: string, callback: (data: any) => void) => {
3229
ipcRenderer.on(channel, (_, data) => callback(data));
3330
}

electron/scripts/translate.ts

Lines changed: 0 additions & 129 deletions
This file was deleted.

electron/worker.ts

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/* eslint-disable no-unused-expressions */
2+
import fs from 'fs';
3+
import { gameKey } from './scripts/variables';
4+
import { requestInterface } from './scripts/interfaces';
5+
6+
const { parentPort } = require('worker_threads');
7+
const dirTree = require('directory-tree');
8+
9+
// Simule la fonction de traduction (singleTranslate)
10+
const singleTranslate = async (request: requestInterface, language: string): Promise<string[]> => {
11+
const logs: any[] = [];
12+
dirTree(request.path, { extensions: /\.yml$/ }, (_item: any, path: any): any => {
13+
// Vérifie si dans le chemin du fichier, il y a le dossier localization
14+
// Si non, passe le fichier
15+
if (path.split('\\').indexOf(gameKey[request.game as keyof typeof gameKey]) === -1) {
16+
return null;
17+
}
18+
19+
// Ignore les fichiers qui ne sont pas dans un sous dossier english
20+
// Sauf ceux qui sont à la racine du dossier localization
21+
if (
22+
path.split('\\').indexOf(request.sourceLanguage ?? 'english') === -1 &&
23+
path.split('\\').indexOf(gameKey[request.game as keyof typeof gameKey]) + 2 !== path.split('\\').length
24+
) {
25+
return null;
26+
}
27+
28+
// Si le chemin contient le dossier replace, ignore ce fichier
29+
// (à gérer plus tard car la nomenclature est différente)
30+
if (path.split('\\').indexOf('replace') !== -1) {
31+
return null;
32+
}
33+
// debug ? console.log('FIRST BLOCK') : '';
34+
// Décompose le chemin du fichier
35+
const locPath = path.split('\\');
36+
// debug ? console.log(locPath) : '';
37+
//
38+
// console.log(gameKey);
39+
const filePath = locPath.splice(
40+
locPath.indexOf(gameKey[request.game as keyof typeof gameKey]) + 1,
41+
locPath.length - locPath.indexOf(gameKey[request.game as keyof typeof gameKey])
42+
);
43+
// debug ? console.log(filePath) : '';
44+
// debug ? console.log(' ') : '';
45+
46+
// Ignore le fichier ne contient pas la nomenclature indiquant qu'il s'agit d'une source anglaise
47+
if (filePath[filePath.length - 1].match(/l_english/g) === null) {
48+
// console.log(' ');
49+
return null;
50+
}
51+
52+
// debug ? console.log('SECOND BLOCK') : '';
53+
filePath[filePath.length - 1] = filePath[filePath.length - 1].replace(/l_english/g, `l_${language}`);
54+
// debug ? console.log(filePath) : '';
55+
56+
// Récupere le contenu du fichier
57+
let content = fs.readFileSync(path, { encoding: 'utf8', flag: 'r' });
58+
// console.log(content)
59+
content = content.replace(/l_english/g, `l_${language}`);
60+
// console.log(content)
61+
// debug ? console.log(' ') : '';
62+
63+
// debug ? console.log('THIRD BLOCK') : '';
64+
// Vérifie si le fichier est à la racine du dossier localization
65+
// Si non, place remplace le nom du dossier par la langue visée
66+
if (filePath.length > 1) {
67+
filePath[0] = language;
68+
}
69+
// debug ? console.log(filePath) : '';
70+
71+
// Défini le nouveau chemin du fichier
72+
const newPath = `${locPath.join('/')}/${filePath.join('/')}`;
73+
// debug ? console.log(newPath) : '';
74+
// Récupère/crée le chemin pour le fichier le log qui contiendra la liste des fichiers ajoutés
75+
const logPath = `${locPath.join('/')}/.addedFiles`;
76+
// debug ? console.log(logPath) : '';
77+
// console.log(' ');
78+
79+
// debug ? console.log('FOURTH BLOCK') : '';
80+
const folders = filePath;
81+
// debug ? console.log(folders) : '';
82+
const a = folders.pop();
83+
// debug ? console.log(a) : '';
84+
const dirPath = `${locPath.join('/')}/${folders.join('/')}`;
85+
// debug ? console.log(dirPath) : '';
86+
filePath.push(a);
87+
// debug ? console.log(filePath) : '';
88+
logs.push(`CONVERTING '${path}'`);
89+
logs.push(`TO '${locPath.join('\\')}\\${filePath.join('\\')}'`);
90+
91+
// debug ? '' : console.log(`CONVERTING '${path}'`);
92+
// debug ? '' : console.log(`TO '${locPath.join('\\')}\\${filePath.join('\\')}'`);
93+
94+
// debug ? console.log('FIFTH BLOCK') : '';
95+
try {
96+
fs.mkdirSync(dirPath, { recursive: true });
97+
fs.writeFileSync(newPath, content, { encoding: 'utf8', flag: 'wx' });
98+
fs.writeFileSync(logPath, `/${filePath.join('/')} \n`, { encoding: 'utf8', flag: 'a' });
99+
fs.writeFileSync('.logs', `Added file : ${newPath} \n`, { encoding: 'utf8', flag: 'a' });
100+
logs.push('File added');
101+
// debug ? console.log('File added') : '';
102+
} catch (error: any) {
103+
if (error.errno === -4075) {
104+
logs.push('File already exist');
105+
// console.log('File already exist');
106+
} else {
107+
console.log(error);
108+
}
109+
}
110+
logs.push(' ');
111+
// debug ? console.log(' ') : '';
112+
// console.log(' ');
113+
return null;
114+
});
115+
return logs;
116+
};
117+
118+
// Le worker écoute les messages envoyés par le processus principal
119+
parentPort.on('message', async (request: any) => {
120+
const logs: any[] = [];
121+
let characters = 0;
122+
123+
// Effectue les traductions pour toutes les langues simultanément
124+
await Promise.all(request.outputLanguages.map((language: any) => singleTranslate(request, language)))
125+
.then((result) => {
126+
result.forEach((res) => {
127+
logs.push(...res);
128+
});
129+
})
130+
.catch((error) => {
131+
console.error(error); // Gère les erreurs de traduction
132+
});
133+
134+
// Envoie les logs au processus principal une fois toutes les traductions terminées
135+
console.log({ characters, logs });
136+
parentPort.postMessage({ success: true, logs });
137+
});

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "paradox-mod-language-converter",
3-
"version": "1.0.0",
3+
"version": "1.1.0",
44
"license": "MIT",
55
"main": "main/index.js",
66
"author": {

0 commit comments

Comments
 (0)