From f92564933c3b52c2ecff1700693e7c7315cb15fe Mon Sep 17 00:00:00 2001 From: toyobayashi Date: Wed, 6 Mar 2024 00:18:34 +0800 Subject: [PATCH] migrate sendTo --- app/src/ts/main.ts | 10 +- app/src/ts/renderer-back.ts | 157 +++++++++------------ app/src/ts/renderer/back/batch-download.ts | 76 +++++----- app/src/ts/renderer/ipc-back.ts | 135 +++++++----------- app/src/ts/renderer/store.ts | 8 +- 5 files changed, 170 insertions(+), 216 deletions(-) diff --git a/app/src/ts/main.ts b/app/src/ts/main.ts index 358e09f..1bf4b14 100644 --- a/app/src/ts/main.ts +++ b/app/src/ts/main.ts @@ -1,5 +1,5 @@ import './common/asar' -import { app, BrowserWindow, ipcMain, BrowserWindowConstructorOptions, Menu, MenuItem, globalShortcut } from 'electron' +import { app, BrowserWindow, ipcMain, BrowserWindowConstructorOptions, Menu, MenuItem, globalShortcut, MessageChannelMain } from 'electron' import { join } from 'path' import * as url from 'url' import './common/get-path' @@ -24,6 +24,8 @@ let mainWindow: BrowserWindow | null = null let backWindow: BrowserWindow | null = null function createWindow (): void { + const { port1, port2 } = new MessageChannelMain() + const browerWindowOptions: BrowserWindowConstructorOptions = { width: 1296, height: 863, @@ -50,6 +52,7 @@ function createWindow (): void { if (!mainWindow) return mainWindow.show() mainWindow.focus() + mainWindow.webContents.postMessage('port', null, [port1]) }) mainWindow.on('closed', function () { @@ -75,6 +78,11 @@ function createWindow (): void { } }) + backWindow.on('ready-to-show', function () { + if (!backWindow) return + backWindow.webContents.postMessage('port', null, [port2]) + }) + backWindow.on('closed', function () { backWindow = null }) diff --git a/app/src/ts/renderer-back.ts b/app/src/ts/renderer-back.ts index 8e1fd8c..2dc434c 100644 --- a/app/src/ts/renderer-back.ts +++ b/app/src/ts/renderer-back.ts @@ -2,133 +2,104 @@ import './renderer/preload' import { ipcRenderer } from 'electron' import DB from './common/db' import { batchDownload, batchStop, getBatchErrorList, setDownloaderProxy } from './renderer/back/batch-download' -import mainWindowId from './renderer/back/main-window-id' +// import mainWindowId from './renderer/back/main-window-id' import readMaster from './renderer/back/on-master-read' let manifest: DB | null = null let master: DB | null = null -ipcRenderer.on('openManifestDatabase', async (event, callbackChannel: string, path: string) => { - if (manifest) { - event.sender.sendTo(mainWindowId, callbackChannel, null) - return +ipcRenderer.on('port', e => { + const mainWindowPort = e.ports[0] + + function defineRemoteFunction (name: string, fn: (...args: any[]) => any): void { + mainWindowPort.addEventListener('message', (event) => { + if (event.data.type === name) { + Promise.resolve(fn(...event.data.payload)).then(ret => { + mainWindowPort.postMessage({ + id: event.data.id, + err: null, + data: ret + }) + }).catch(err => { + mainWindowPort.postMessage({ + id: event.data.id, + err: err.message, + data: undefined + }) + }) + } + }) } - try { + + defineRemoteFunction('openManifestDatabase', async (path: string) => { + if (manifest) { + return + } manifest = await DB.open(path) - event.sender.sendTo(mainWindowId, callbackChannel, null) - } catch (err: any) { - event.sender.sendTo(mainWindowId, callbackChannel, err.message) - } -}) + }) -ipcRenderer.on('openMasterDatabase', async (event, callbackChannel: string, path: string) => { - if (master) { - event.sender.sendTo(mainWindowId, callbackChannel, null) - return - } - try { + defineRemoteFunction('openMasterDatabase', async (path: string) => { + if (master) { + return + } master = await DB.open(path) - event.sender.sendTo(mainWindowId, callbackChannel, null) - } catch (err: any) { - event.sender.sendTo(mainWindowId, callbackChannel, err.message) - } -}) + }) -ipcRenderer.on('getMasterHash', async (event, callbackChannel: string) => { - try { + defineRemoteFunction('getMasterHash', async () => { const masterHash = (await manifest!.find('manifests', ['name', 'hash'], { name: 'master.mdb' }))[0].hash as string - event.sender.sendTo(mainWindowId, callbackChannel, null, masterHash) - } catch (err: any) { - event.sender.sendTo(mainWindowId, callbackChannel, err.message, '') - } -}) + return masterHash + }) -ipcRenderer.on('readMasterData', async (event, callbackChannel: string, masterFile: string) => { - try { + defineRemoteFunction('readMasterData', async (masterFile: string) => { master = await DB.open(masterFile) const masterData = await readMaster(master, manifest!) await master.close() master = null - event.sender.sendTo(mainWindowId, callbackChannel, null, masterData) - } catch (err: any) { - event.sender.sendTo(mainWindowId, callbackChannel, err.message, '') - } -}) + return masterData + }) -ipcRenderer.on('getCardHash', async (event, callbackChannel: string, id: string | number) => { - try { + defineRemoteFunction('getCardHash', async (id: string | number) => { const res = await manifest!.find('manifests', ['hash'], { name: `card_bg_${id}.unity3d` }) - event.sender.sendTo(mainWindowId, callbackChannel, null, res[0].hash) - } catch (err: any) { - event.sender.sendTo(mainWindowId, callbackChannel, err.message, '') - } -}) + return res[0].hash + }) -ipcRenderer.on('getIconHash', async (event, callbackChannel: string, id: string | number) => { - try { + defineRemoteFunction('getIconHash', async (id: string | number) => { const res = await manifest!.findOne('manifests', ['hash'], { name: `card_${id}_m.unity3d` }) - event.sender.sendTo(mainWindowId, callbackChannel, null, res.hash) - } catch (err: any) { - event.sender.sendTo(mainWindowId, callbackChannel, err.message, '') - } -}) + return res.hash + }) -ipcRenderer.on('getEmblemHash', async (event, callbackChannel: string, id: string | number) => { - try { + defineRemoteFunction('getEmblemHash', async (id: string | number) => { const res = await manifest!.findOne('manifests', ['hash'], { name: `emblem_${id}_l.unity3d` }) - event.sender.sendTo(mainWindowId, callbackChannel, null, res.hash) - } catch (err: any) { - event.sender.sendTo(mainWindowId, callbackChannel, err.message, '') - } -}) + return res.hash + }) -ipcRenderer.on('searchResources', async (event, callbackChannel: string, queryString: string) => { - try { + defineRemoteFunction('searchResources', async (queryString: string) => { const res = await manifest!.find<{ name: string, hash: string }>('manifests', ['name', 'hash', 'size'], { name: { $like: `%${queryString.trim()}%` } }) - event.sender.sendTo(mainWindowId, callbackChannel, null, res) - } catch (err: any) { - event.sender.sendTo(mainWindowId, callbackChannel, err.message, '') - } -}) + return res + }) -let batchDownloading = false + let batchDownloading = false -ipcRenderer.on('startBatchDownload', async (event, callbackChannel: string) => { - try { + defineRemoteFunction('startBatchDownload', async () => { batchDownloading = true - await batchDownload(manifest!) - event.sender.sendTo(mainWindowId, callbackChannel, null, batchDownloading) - } catch (err: any) { - event.sender.sendTo(mainWindowId, callbackChannel, err.message, '') - } -}) + await batchDownload(mainWindowPort, manifest!) + return batchDownloading + }) -ipcRenderer.on('stopBatchDownload', async (event, callbackChannel: string) => { - try { + defineRemoteFunction('stopBatchDownload', async () => { await batchStop() batchDownloading = false - event.sender.sendTo(mainWindowId, callbackChannel, null, batchDownloading) - } catch (err: any) { - event.sender.sendTo(mainWindowId, callbackChannel, err.message, '') - } -}) + return batchDownloading + }) -ipcRenderer.on('getBatchErrorList', (event, callbackChannel: string) => { - try { + defineRemoteFunction('getBatchErrorList', () => { const list = getBatchErrorList() - event.sender.sendTo(mainWindowId, callbackChannel, null, list) - } catch (err: any) { - event.sender.sendTo(mainWindowId, callbackChannel, err.message, null) - } -}) + return list + }) -ipcRenderer.on('setDownloaderProxy', (event, callbackChannel: string, proxy: string) => { - try { + defineRemoteFunction('setDownloaderProxy', (proxy: string) => { setDownloaderProxy(proxy) - event.sender.sendTo(mainWindowId, callbackChannel, null) - } catch (err: any) { - event.sender.sendTo(mainWindowId, callbackChannel, err.message) - } + }) }) window.addEventListener('beforeunload', () => { diff --git a/app/src/ts/renderer/back/batch-download.ts b/app/src/ts/renderer/back/batch-download.ts index 64e23a7..d92d32d 100644 --- a/app/src/ts/renderer/back/batch-download.ts +++ b/app/src/ts/renderer/back/batch-download.ts @@ -3,8 +3,8 @@ import { formatSize } from '../../common/util' import getPath from '../../common/get-path' import { md5File } from './hash' import type { DownloadPromise, ResourceType as ResourceTypeEnum } from 'mishiro-core' -import { ipcRenderer } from 'electron' -import mainWindowId from './main-window-id' +// import { ipcRenderer } from 'electron' +// import mainWindowId from './main-window-id' import { warn } from '../log' import configurer from '../config' @@ -23,7 +23,7 @@ interface ManifestResouceWithPath extends ManifestResouce { let stopBatch = false -async function checkFiles (manifest: DB): Promise<{ +async function checkFiles (port: MessagePort, manifest: DB): Promise<{ list: ManifestResouceWithPath[] count: number }> { @@ -53,12 +53,15 @@ async function checkFiles (manifest: DB): Promise<{ const n = Date.now() if ((n >= (t + 100)) || (i === records.length - 1)) { t = n - ipcRenderer.sendTo(mainWindowId, 'setBatchStatus', { - name: 'Checking', - status: `${i + 1} / ${records.length}`, - status2: `${completeCount} / ${records.length}`, - curprog: 100 * (i + 1) / records.length, - totalprog: 0 + port.postMessage({ + type: 'setBatchStatus', + payload: [{ + name: 'Checking', + status: `${i + 1} / ${records.length}`, + status2: `${completeCount} / ${records.length}`, + curprog: 100 * (i + 1) / records.length, + totalprog: 0 + }] }) } } @@ -81,16 +84,16 @@ export function setDownloaderProxy (proxy: string): void { downloader.setProxy(proxy) } -export async function batchDownload (manifest: DB): Promise { +export async function batchDownload (port: MessagePort, manifest: DB): Promise { errorList = [] - const info = await checkFiles(manifest) + const info = await checkFiles(port, manifest) list = info.list const count = info.count const totalCount = list.length + count if (stopBatch) { stopBatch = false list.length = 0 - resetBatchStatus() + resetBatchStatus(port) return } for (let i = 0; i < list.length; i++) { @@ -101,21 +104,27 @@ export async function batchDownload (manifest: DB): Promise { continue } const status2 = `${i + count} / ${totalCount}` - ipcRenderer.sendTo(mainWindowId, 'setBatchStatus', { - name: resource.name, - status: '', - status2: status2, - curprog: 0, - totalprog: 100 * (i + count) / totalCount + port.postMessage({ + type: 'setBatchStatus', + payload: [{ + name: resource.name, + status: '', + status2: status2, + curprog: 0, + totalprog: 100 * (i + count) / totalCount + }] }) try { currentDownloadPromise = downloader.downloadOneRaw(type, resource.hash, resource.path, (prog) => { - ipcRenderer.sendTo(mainWindowId, 'setBatchStatus', { - name: resource.name ?? '', - status: `${formatSize(prog.current)} / ${formatSize(prog.max)}`, - status2: status2, - curprog: prog.loading, - totalprog: 100 * (i + count) / totalCount + prog.loading / totalCount + port.postMessage({ + type: 'setBatchStatus', + payload: [{ + name: resource.name ?? '', + status: `${formatSize(prog.current)} / ${formatSize(prog.max)}`, + status2: status2, + curprog: prog.loading, + totalprog: 100 * (i + count) / totalCount + prog.loading / totalCount + }] }) }) await currentDownloadPromise @@ -141,7 +150,7 @@ export async function batchDownload (manifest: DB): Promise { } stopBatch = false list.length = 0 - resetBatchStatus() + resetBatchStatus(port) } export function batchStop (): Promise { @@ -153,13 +162,16 @@ export function batchStop (): Promise { }) } -function resetBatchStatus (): void { - ipcRenderer.sendTo(mainWindowId, 'setBatchStatus', { - name: '', - status: '', - status2: '', - curprog: 0, - totalprog: 0 +function resetBatchStatus (port: MessagePort): void { + port.postMessage({ + type: 'setBatchStatus', + payload: [{ + name: '', + status: '', + status2: '', + curprog: 0, + totalprog: 0 + }] }) } diff --git a/app/src/ts/renderer/ipc-back.ts b/app/src/ts/renderer/ipc-back.ts index fe3e85e..aee4f6f 100644 --- a/app/src/ts/renderer/ipc-back.ts +++ b/app/src/ts/renderer/ipc-back.ts @@ -1,6 +1,8 @@ +import store, { Action } from './store' + const { ipcRenderer } = window.node.electron -const backWindowId = ipcRenderer.sendSync('backWindowId') +// const backWindowId = ipcRenderer.sendSync('backWindowId') let id = 0 @@ -9,123 +11,84 @@ function createChannelName (): string { return `__main_callback_${id}__` } -export function openManifestDatabase (path: string): Promise { +let backWindowPort: MessagePort + +ipcRenderer.on('port', e => { + backWindowPort = e.ports[0] + + backWindowPort.addEventListener('message', (ev) => { + if (ev.data.type === 'setBatchStatus') { + store.commit(Action.SET_BATCH_STATUS, ev.data.payload[0]) + } + }) +}) + +function invokeBackWindow (name: string, args: any[] = []): Promise { + console.log('invokeBackWindow: ', name, args) return new Promise((resolve, reject) => { + if (!backWindowPort) { + reject(new Error('back window is not ready')) + return + } const callbackChannel = createChannelName() - ipcRenderer.once(callbackChannel, (_event, errmsg) => { - if (errmsg) reject(new Error(errmsg)) - else resolve() + backWindowPort.addEventListener('message', (ev) => { + console.log('recieve: ', ev.data) + if (ev.data.id === callbackChannel) { + if (ev.data.err) { + reject(new Error(ev.data.err)) + } else { + resolve(ev.data.data) + } + } + }, { once: true }) + backWindowPort.postMessage({ + id: callbackChannel, + type: name, + payload: args }) - ipcRenderer.sendTo(backWindowId, 'openManifestDatabase', callbackChannel, path) }) } +export function openManifestDatabase (path: string): Promise { + return invokeBackWindow('openManifestDatabase', [path]) +} + export function getMasterHash (): Promise { - return new Promise((resolve, reject) => { - const callbackChannel = createChannelName() - ipcRenderer.once(callbackChannel, (_event, errmsg, hash) => { - if (errmsg) reject(new Error(errmsg)) - else resolve(hash) - }) - ipcRenderer.sendTo(backWindowId, 'getMasterHash', callbackChannel) - }) + return invokeBackWindow('getMasterHash') } export function readMasterData (masterFile: string): Promise { - return new Promise((resolve, reject) => { - const callbackChannel = createChannelName() - ipcRenderer.once(callbackChannel, (_event, errmsg, data) => { - if (errmsg) reject(new Error(errmsg)) - else resolve(data) - }) - ipcRenderer.sendTo(backWindowId, 'readMasterData', callbackChannel, masterFile) - }) + return invokeBackWindow('readMasterData', [masterFile]) } export function getCardHash (id: string | number): Promise { - return new Promise((resolve, reject) => { - const callbackChannel = createChannelName() - ipcRenderer.once(callbackChannel, (_event, errmsg, hash) => { - if (errmsg) reject(new Error(errmsg)) - else resolve(hash) - }) - ipcRenderer.sendTo(backWindowId, 'getCardHash', callbackChannel, id) - }) + return invokeBackWindow('getCardHash', [id]) } export function getIconHash (id: string | number): Promise { - return new Promise((resolve, reject) => { - const callbackChannel = createChannelName() - ipcRenderer.once(callbackChannel, (_event, errmsg, hash) => { - if (errmsg) reject(new Error(errmsg)) - else resolve(hash) - }) - ipcRenderer.sendTo(backWindowId, 'getIconHash', callbackChannel, id) - }) + return invokeBackWindow('getIconHash', [id]) } export function getEmblemHash (id: string | number): Promise { - return new Promise((resolve, reject) => { - const callbackChannel = createChannelName() - ipcRenderer.once(callbackChannel, (_event, errmsg, hash) => { - if (errmsg) reject(new Error(errmsg)) - else resolve(hash) - }) - ipcRenderer.sendTo(backWindowId, 'getEmblemHash', callbackChannel, id) - }) + return invokeBackWindow('getEmblemHash', [id]) } export function searchResources (query: string): Promise { - return new Promise((resolve, reject) => { - const callbackChannel = createChannelName() - ipcRenderer.once(callbackChannel, (_event, errmsg, data) => { - if (errmsg) reject(new Error(errmsg)) - else resolve(data) - }) - ipcRenderer.sendTo(backWindowId, 'searchResources', callbackChannel, query) - }) + return invokeBackWindow('searchResources', [query]) } export function startBatchDownload (): Promise { - return new Promise((resolve, reject) => { - const callbackChannel = createChannelName() - ipcRenderer.once(callbackChannel, (_event, errmsg, downloading) => { - if (errmsg) reject(new Error(errmsg)) - else resolve(downloading) - }) - ipcRenderer.sendTo(backWindowId, 'startBatchDownload', callbackChannel) - }) + return invokeBackWindow('startBatchDownload') } export function stopBatchDownload (): Promise { - return new Promise((resolve, reject) => { - const callbackChannel = createChannelName() - ipcRenderer.once(callbackChannel, (_event, errmsg, downloading) => { - if (errmsg) reject(new Error(errmsg)) - else resolve(downloading) - }) - ipcRenderer.sendTo(backWindowId, 'stopBatchDownload', callbackChannel) - }) + return invokeBackWindow('stopBatchDownload') } export function getBatchErrorList (): Promise { - return new Promise((resolve, reject) => { - const callbackChannel = createChannelName() - ipcRenderer.once(callbackChannel, (_event, errmsg, list) => { - if (errmsg) reject(new Error(errmsg)) - else resolve(list) - }) - ipcRenderer.sendTo(backWindowId, 'getBatchErrorList', callbackChannel) - }) + return invokeBackWindow('getBatchErrorList') } export function setDownloaderProxy (proxy: string): Promise { - return new Promise((resolve, reject) => { - const callbackChannel = createChannelName() - ipcRenderer.once(callbackChannel, (_event, errmsg, list) => { - if (errmsg) reject(new Error(errmsg)) - else resolve(list) - }) - ipcRenderer.sendTo(backWindowId, 'setDownloaderProxy', callbackChannel, proxy) - }) + return invokeBackWindow('setDownloaderProxy', [proxy]) } diff --git a/app/src/ts/renderer/store.ts b/app/src/ts/renderer/store.ts index bdcba73..9914aaa 100644 --- a/app/src/ts/renderer/store.ts +++ b/app/src/ts/renderer/store.ts @@ -4,7 +4,7 @@ import Vuex from 'vuex' import type { MasterData } from './back/on-master-read' import type { BGM, Live } from './back/resolve-audio-manifest' -const { ipcRenderer } = window.node.electron +// const { ipcRenderer } = window.node.electron Vue.use(Vuex) @@ -76,9 +76,9 @@ const store = new Vuex.Store<{ // store.commit(Action.SET_BATCH_DOWNLOADING, payload) // }) -ipcRenderer.on('setBatchStatus', (_event, status) => { - store.commit(Action.SET_BATCH_STATUS, status) -}) +// ipcRenderer.on('setBatchStatus', (_event, status) => { +// store.commit(Action.SET_BATCH_STATUS, status) +// }) export function setResVer (resVer: number): void { store.commit(Action.SET_RES_VER, resVer)