Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into pr/takusea/2276-3
Browse files Browse the repository at this point in the history
  • Loading branch information
Hiroshiba committed Oct 12, 2024
2 parents 689c85b + 755d84b commit 1a64b3a
Show file tree
Hide file tree
Showing 58 changed files with 499 additions and 518 deletions.
2 changes: 1 addition & 1 deletion docs/res/起動シーケンス図.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ flowchart
870482["store.get registeredEngineDirs"] --> 250263
222321 --> 967432["engine.runEngineAll"]
656570["engine.fetchEngineInfos"] --> 870482
110954["engine.initializeEngineInfosAndAltPortInfo"] --> 656570
110954["engine.initializeAltPortInfo"] --> 656570
967432 --> 302398["runtimeInfo.setEngineInfos"]
302398 --> 321984
subgraph 656570["engine.fetchEngineInfos"]
Expand Down
2 changes: 1 addition & 1 deletion openapi.json

Large diffs are not rendered by default.

19 changes: 13 additions & 6 deletions src/backend/browser/contract.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import { EngineInfo, envEngineInfoSchema } from "@/type/preload";
import { type EngineInfo, envEngineInfoSchema } from "@/type/preload";

const baseEngineInfo = envEngineInfoSchema
.array()
.parse(JSON.parse(import.meta.env.VITE_DEFAULT_ENGINE_INFOS))[0];

export const defaultEngine: EngineInfo = {
...baseEngineInfo,
type: "path", // FIXME: ダミーで"path"にしているので、エンジンAPIのURLを設定できるようにし、type: "URL"にする
isDefault: true,
};
export const defaultEngine: EngineInfo = (() => {
const { protocol, hostname, port, pathname } = new URL(baseEngineInfo.host);
return {
...baseEngineInfo,
protocol,
hostname,
defaultPort: port,
pathname: pathname === "/" ? "" : pathname,
type: "path", // FIXME: ダミーで"path"にしているので、エンジンAPIのURLを設定できるようにし、type: "URL"にする
isDefault: true,
};
})();
export const directoryHandleStoreKey = "directoryHandle";
10 changes: 7 additions & 3 deletions src/backend/electron/engineAndVvppController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ export class EngineAndVvppController {

// エンジンの準備と起動
async launchEngines() {
// エンジンの追加と削除を反映させるためEngineInfoとAltPortInfosを再生成する
this.engineInfoManager.initializeEngineInfosAndAltPortInfo();
// AltPortInfosを再生成する
this.engineInfoManager.initializeAltPortInfo();

// TODO: デフォルトエンジンの処理をConfigManagerに移してブラウザ版と共通化する
const engineInfos = this.engineInfoManager.fetchEngineInfos();
Expand All @@ -147,7 +147,10 @@ export class EngineAndVvppController {
this.configManager.set("engineSettings", engineSettings);

await this.engineProcessManager.runEngineAll();
this.runtimeInfoManager.setEngineInfos(engineInfos);
this.runtimeInfoManager.setEngineInfos(
engineInfos,
this.engineInfoManager.altPortInfos,
);
await this.runtimeInfoManager.exportFile();
}

Expand All @@ -162,6 +165,7 @@ export class EngineAndVvppController {
// TODO: setからexportの処理は排他処理にしたほうがより良い
this.runtimeInfoManager.setEngineInfos(
this.engineInfoManager.fetchEngineInfos(),
this.engineInfoManager.altPortInfos,
);
await this.runtimeInfoManager.exportFile();
}
Expand Down
19 changes: 16 additions & 3 deletions src/backend/electron/manager/RuntimeInfoManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
import fs from "fs";
import AsyncLock from "async-lock";
import log from "electron-log/main";
import type { AltPortInfos } from "@/store/type";
import { EngineId, EngineInfo } from "@/type/preload";

/**
* ランタイム情報書き出しに必要なEngineInfo
*/
export type EngineInfoForRuntimeInfo = Pick<
EngineInfo,
"uuid" | "host" | "name"
"uuid" | "protocol" | "hostname" | "defaultPort" | "pathname" | "name"
>;

/**
Expand Down Expand Up @@ -58,12 +59,17 @@ export class RuntimeInfoManager {
* エンジン情報(書き出し用に記憶)
*/
private engineInfos: EngineInfoForRuntimeInfo[] = [];
private altportInfos: AltPortInfos = {};

/**
* エンジン情報を登録する
*/
public setEngineInfos(engineInfos: EngineInfoForRuntimeInfo[]) {
public setEngineInfos(
engineInfos: EngineInfoForRuntimeInfo[],
altportInfos: AltPortInfos,
) {
this.engineInfos = engineInfos;
this.altportInfos = altportInfos;
}

/**
Expand All @@ -76,9 +82,16 @@ export class RuntimeInfoManager {
formatVersion: this.fileFormatVersion,
appVersion: this.appVersion,
engineInfos: this.engineInfos.map((engineInfo) => {
const altPort: string | undefined =
this.altportInfos[engineInfo.uuid];
const port = altPort ?? engineInfo.defaultPort;
// NOTE: URLを正規化する
const url = new URL(`${engineInfo.protocol}//${engineInfo.hostname}`);
url.port = port;
return {
uuid: engineInfo.uuid,
url: engineInfo.host, // NOTE: 元のEngineInfo.hostにURLが入っている
// NOTE: URLインターフェースは"pathname"が空文字でも"/"を付けるので手動で結合する。
url: `${url.origin}${engineInfo.pathname}`,
name: engineInfo.name,
};
}),
Expand Down
43 changes: 21 additions & 22 deletions src/backend/electron/manager/engineInfoManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ import { AltPortInfos } from "@/store/type";
import { BaseConfigManager } from "@/backend/common/ConfigManager";

/**
* デフォルトエンジンの情報を作成する
* デフォルトエンジンの情報を取得する
*/
function createDefaultEngineInfos(defaultEngineDir: string): EngineInfo[] {
function fetchDefaultEngineInfos(defaultEngineDir: string): EngineInfo[] {
// TODO: envから直接ではなく、envに書いたengine_manifest.jsonから情報を得るようにする
const defaultEngineInfosEnv =
import.meta.env.VITE_DEFAULT_ENGINE_INFOS ?? "[]";
Expand All @@ -29,8 +29,13 @@ function createDefaultEngineInfos(defaultEngineDir: string): EngineInfo[] {
const engines = envSchema.parse(JSON.parse(defaultEngineInfosEnv));

return engines.map((engineInfo) => {
const { protocol, hostname, port, pathname } = new URL(engineInfo.host);
return {
...engineInfo,
protocol,
hostname,
defaultPort: port,
pathname: pathname === "/" ? "" : pathname,
isDefault: true,
type: "path",
executionFilePath: path.resolve(engineInfo.executionFilePath),
Expand All @@ -48,9 +53,6 @@ export class EngineInfoManager {
defaultEngineDir: string;
vvppEngineDir: string;

defaultEngineInfos: EngineInfo[] = [];
additionalEngineInfos: EngineInfo[] = [];

/** 代替ポート情報 */
public altPortInfos: AltPortInfos = {};

Expand All @@ -65,10 +67,10 @@ export class EngineInfoManager {
}

/**
* 追加エンジンの一覧を作成する
* 追加エンジンの一覧を取得する
* FIXME: store.get("registeredEngineDirs")への副作用をEngineManager外に移動する
*/
private createAdditionalEngineInfos(): EngineInfo[] {
private fetchAdditionalEngineInfos(): EngineInfo[] {
const engines: EngineInfo[] = [];
const addEngine = (engineDir: string, type: "vvpp" | "path") => {
const manifestPath = path.join(engineDir, "engine_manifest.json");
Expand All @@ -88,7 +90,10 @@ export class EngineInfoManager {

engines.push({
uuid: manifest.uuid,
host: `http://127.0.0.1:${manifest.port}`,
protocol: "http:",
hostname: "127.0.0.1",
defaultPort: manifest.port.toString(),
pathname: "",
name: manifest.name,
path: engineDir,
executionEnabled: true,
Expand Down Expand Up @@ -139,7 +144,11 @@ export class EngineInfoManager {
* 全てのエンジンの一覧を取得する。デフォルトエンジン+追加エンジン。
*/
fetchEngineInfos(): EngineInfo[] {
return [...this.defaultEngineInfos, ...this.additionalEngineInfos];
const engineInfos = [
...fetchDefaultEngineInfos(this.defaultEngineDir),
...this.fetchAdditionalEngineInfos(),
];
return engineInfos;
}

/**
Expand Down Expand Up @@ -170,11 +179,9 @@ export class EngineInfoManager {
}

/**
* EngineInfosとAltPortInfoを初期化する
* AltPortInfoを初期化する
*/
initializeEngineInfosAndAltPortInfo() {
this.defaultEngineInfos = createDefaultEngineInfos(this.defaultEngineDir);
this.additionalEngineInfos = this.createAdditionalEngineInfos();
initializeAltPortInfo() {
this.altPortInfos = {};
}

Expand All @@ -183,15 +190,7 @@ export class EngineInfoManager {
* エンジン起動時にポートが競合して代替ポートを使う場合に使用する。
*/
updateAltPort(engineId: EngineId, port: number) {
const engineInfo = this.fetchEngineInfo(engineId);
const url = new URL(engineInfo.host);
this.altPortInfos[engineId] = {
from: Number(url.port),
to: port,
};

url.port = port.toString();
engineInfo.host = url.toString();
this.altPortInfos[engineId] = port.toString();
}

/**
Expand Down
39 changes: 20 additions & 19 deletions src/backend/electron/manager/engineProcessManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import {
findAltPort,
getPidFromPort,
getProcessNameFromPid,
type HostInfo,
isAssignablePort,
url2HostInfo,
} from "../portHelper";

import { EngineInfo, EngineId, EngineSettings } from "@/type/preload";
Expand Down Expand Up @@ -86,41 +86,40 @@ export class EngineProcessManager {
}

// { hostname (localhost), port (50021) } <- url (http://localhost:50021)
const engineHostInfo = url2HostInfo(new URL(engineInfo.host));

const engineHostInfo: HostInfo = {
protocol: engineInfo.protocol,
hostname: engineInfo.hostname,
port: Number(engineInfo.defaultPort),
};

// ポートが塞がっていれば代替ポートを探す
let port = engineHostInfo.port;
log.info(
`ENGINE ${engineId}: Checking whether port ${engineHostInfo.port} is assignable...`,
`ENGINE ${engineId}: Checking whether port ${port} is assignable...`,
);

if (
!(await isAssignablePort(engineHostInfo.port, engineHostInfo.hostname))
) {
if (!(await isAssignablePort(port, engineHostInfo.hostname))) {
// ポートを既に割り当てているプロセスidの取得
const pid = await getPidFromPort(engineHostInfo);
if (pid != undefined) {
const processName = await getProcessNameFromPid(engineHostInfo, pid);
log.warn(
`ENGINE ${engineId}: Port ${engineHostInfo.port} has already been assigned by ${processName} (pid=${pid})`,
`ENGINE ${engineId}: Port ${port} has already been assigned by ${processName} (pid=${pid})`,
);
} else {
// ポートは使用不可能だがプロセスidは見つからなかった
log.warn(
`ENGINE ${engineId}: Port ${engineHostInfo.port} was unavailable`,
);
log.warn(`ENGINE ${engineId}: Port ${port} was unavailable`);
}

// 代替ポートの検索
const altPort = await findAltPort(
engineHostInfo.port,
engineHostInfo.hostname,
);
const altPort = await findAltPort(port, engineHostInfo.hostname);

// 代替ポートが見つからないとき
if (altPort == undefined) {
log.error(`ENGINE ${engineId}: No Alternative Port Found`);
dialog.showErrorBox(
`${engineInfo.name} の起動に失敗しました`,
`${engineHostInfo.port}番ポートの代わりに利用可能なポートが見つかりませんでした。PCを再起動してください。`,
`${port}番ポートの代わりに利用可能なポートが見つかりませんでした。PCを再起動してください。`,
);
app.exit(1);
throw new Error("No Alternative Port Found");
Expand All @@ -129,8 +128,10 @@ export class EngineProcessManager {
// 代替ポート情報を更新
this.engineAltPortUpdater(engineId, altPort);
log.warn(
`ENGINE ${engineId}: Applied Alternative Port: ${engineHostInfo.port} -> ${altPort}`,
`ENGINE ${engineId}: Applied Alternative Port: ${port} -> ${altPort}`,
);

port = altPort;
}

log.info(`ENGINE ${engineId}: Starting process`);
Expand All @@ -155,9 +156,9 @@ export class EngineProcessManager {
const enginePath = engineInfo.executionFilePath;
const args = engineInfo.executionArgs.concat(useGpu ? ["--use_gpu"] : [], [
"--host",
new URL(engineInfo.host).hostname,
engineHostInfo.hostname,
"--port",
new URL(engineInfo.host).port,
port.toString(),
]);

log.info(`ENGINE ${engineId} path: ${enginePath}`);
Expand Down
8 changes: 0 additions & 8 deletions src/backend/electron/portHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,6 @@ const portWarn = (port: number, message: string, isNested = false) => {
log.warn(`${isNested ? "| " : ""}PORT ${port}: ${message}`);
};

export function url2HostInfo(url: URL): HostInfo {
return {
protocol: url.protocol,
hostname: url.hostname,
port: Number(url.port),
};
}

/**
* "netstat -ano" の stdout から, 指定したポートを LISTENING しているプロセスの id を取得します.
*
Expand Down
1 change: 1 addition & 0 deletions src/components/Dialog/EngineManageDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,7 @@ const getFeatureName = (name: keyof SupportedFeatures) => {
adjustPitchScale: "全体の音高の調整",
adjustIntonationScale: "全体の抑揚の調整",
adjustVolumeScale: "全体の音量の調整",
adjustPauseLength: "句読点などの無音時間の調整",
interrogativeUpspeak: "疑問文の自動調整",
synthesisMorphing: "2種類のスタイルでモーフィングした音声を合成",
sing: "歌唱音声合成",
Expand Down
28 changes: 0 additions & 28 deletions src/components/Dialog/ImportSongProjectDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,10 @@
>
<QItemSection avatar>
<QCheckbox
v-if="multiTrackEnabled"
v-model="selectedTrackIndexes"
:val="track.value"
:disable="track.disable"
/>
<QRadio
v-else
v-model="selectedTrackIndex"
:val="track.value"
:disable="track.disable"
/>
</QItemSection>
<QItemSection>
<QItemLabel>
Expand Down Expand Up @@ -117,10 +110,6 @@ const { dialogRef, onDialogOK, onDialogCancel } = useDialogPluginComponent();
const store = useStore();
const log = createLogger("ImportExternalProjectDialog");
const multiTrackEnabled = computed(
() => store.state.experimentalSetting.enableMultiTrack,
);
// 受け入れる拡張子
const acceptExtensions = computed(
() => supportedExtensions.map((ext) => `.${ext}`).join(",") + ",.vvproj",
Expand Down Expand Up @@ -243,23 +232,6 @@ const trackOptions = computed(() => {
});
// 選択中のトラック
const selectedTrackIndexes = ref<number[] | null>(null);
const selectedTrackIndex = computed<number | null>({
get: () => {
if (selectedTrackIndexes.value == null) {
return null;
}
if (selectedTrackIndexes.value.length === 0) {
return null;
}
return selectedTrackIndexes.value[0];
},
set: (index: number | null) => {
if (index == null) {
throw new Error("assert: index != null");
}
selectedTrackIndexes.value = [index];
},
});
// データ初期化
const initializeValues = () => {
Expand Down
Loading

0 comments on commit 1a64b3a

Please sign in to comment.