Skip to content

Commit

Permalink
migrate sendTo
Browse files Browse the repository at this point in the history
toyobayashi committed Mar 5, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 473fc46 commit f925649
Showing 5 changed files with 170 additions and 216 deletions.
10 changes: 9 additions & 1 deletion app/src/ts/main.ts
Original file line number Diff line number Diff line change
@@ -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
})
157 changes: 64 additions & 93 deletions app/src/ts/renderer-back.ts
Original file line number Diff line number Diff line change
@@ -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', () => {
76 changes: 44 additions & 32 deletions app/src/ts/renderer/back/batch-download.ts
Original file line number Diff line number Diff line change
@@ -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<void> {
export async function batchDownload (port: MessagePort, manifest: DB): Promise<void> {
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<void> {
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<void> {
}
stopBatch = false
list.length = 0
resetBatchStatus()
resetBatchStatus(port)
}

export function batchStop (): Promise<void> {
@@ -153,13 +162,16 @@ export function batchStop (): Promise<void> {
})
}

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
}]
})
}

135 changes: 49 additions & 86 deletions app/src/ts/renderer/ipc-back.ts
Original file line number Diff line number Diff line change
@@ -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<void> {
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<T> (name: string, args: any[] = []): Promise<T> {
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<void> {
return invokeBackWindow('openManifestDatabase', [path])
}

export function getMasterHash (): Promise<string> {
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<import('./back/on-master-read').MasterData> {
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<string> {
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<string> {
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<string> {
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<ResourceData[]> {
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<boolean> {
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<boolean> {
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<IBatchError[]> {
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<void> {
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])
}
8 changes: 4 additions & 4 deletions app/src/ts/renderer/store.ts
Original file line number Diff line number Diff line change
@@ -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)

0 comments on commit f925649

Please sign in to comment.