Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

コードの歩き方にVuex周りの記述を追加 #1022

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions docs/コードの歩き方.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,40 @@ subgraph Vue
end
```

## 設計

ここでは Electron 周り・Vuex 周り・UI 周りの設計方針を簡単に紹介します。

### Electron 周り(`src/electron/`)

TODO

### Vuex 周り(`src/store/`)

VOICEVOX では動的に変更される状態と、状態を変更する関数を、Vuex の`Store`を介して管理しています。
`Store`は音声・エンジン・UI などそれぞれの目的に応じて分割し、`src/store/index.ts`で統合しています。

Vuex の仕様を少し説明します。
状態は`State`に保存し、状態の変更は`Mutation`で行います。
`Mutation`は同期的に実行される必要がありますが、非同期処理を行いたい場合は`Action`を使います。
VOICEVOX 内では、UI から実行するものは`Action`を介するようにして、`Action`内から`Mutation`を実行するようにしています。
これは後述する Undo/Redo 機構のための設計です。
関数は全て文字列を渡す形になっていますが、これも Vuex の仕様です。コードを追う際は文字列で全体検索を行うと便利です。

Vuex は型サポートが不十分なので、VOICEVOX では独自に型周りの機構を作っています(`src/store/type.ts`)。
関数を定義したい場合は、まず`type.ts`に型を宣言し、対応する`Store`内に実装します。

UI から Electron やエンジンにアクセスしたい場合は、必ず Vuex を介するようにしています。
これは Vuex の元の思想である Flux の考え方を引き継いでいて、外部にアクセスすることで生じる予想外な状態の変更などをなるべく一元管理するためです。

VOICEVOX では Vuex の`Mutation`をラップする形で Undo/Redo 機構を実現しています。
状態 A→B の変更を行った時、自動的にその逆方向 B→A の変更が Undo スタックに積まれます。
詳細は[Undo/Redo を実装したい #116](https://github.com/VOICEVOX/voicevox/issues/116)をご参照ください。

### UI 周り(`src/views/`・`src/components/`)

TODO

## ソースコードのディレクトリ構成

- src
Expand Down
40 changes: 20 additions & 20 deletions docs/設計方針.md → docs/細かい設計方針.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
## Vuex とダイアログ
ダイアログは外部 API とみなし、Vuex の Store の Action 内から呼ぶことを許容しています。
これは、ダイアログの結果によってダイアログ前後の挙動を 1 つの Action に書けるという利便性を取ったためです。
ダイアログの種類によっては View に直接作用してダイアログ UI を表示するものもありますが、これも許容することにしています。
## EngineId、SpeakerId、StyleId
EngineId はエンジンが持つ ID で、世界で唯一かつ不変です。
SpeakerId は話者が持つ ID で、世界で唯一かつ不変。エンジン間でも同じ ID を持ちます。
StyleId はスタイルごとの ID で、話者ごとに唯一であれば良いです。
声を一意に決めるには、(EngineId, SpeakerId, StyleId)の3組が揃っている必要がある、という仕様を目指しています。
現状は、音声合成APIに SpeakerId 引数が無いため、(EngineId, StyleId)の2組で一意に声が決まっています。
VOICEVOX は歴史的経緯により、 SpeakerId と StyleId が混同していることがあります。
特に型が整数値になっている SpeakerId は StyleId と混同している場合があります。
(エンジン API の SpeakerId 引数に StyleId を渡したりなど。)
StyleId は現在整数値型になっていますが、将来的にはUuidにしたいと考えています。
## Vuex とダイアログ

ダイアログは外部 API とみなし、Vuex の Store の Action 内から呼ぶことを許容しています。
これは、ダイアログの結果によってダイアログ前後の挙動を 1 つの Action に書けるという利便性を取ったためです。
ダイアログの種類によっては View に直接作用してダイアログ UI を表示するものもありますが、これも許容することにしています。

## EngineId、SpeakerId、StyleId

EngineId はエンジンが持つ ID で、世界で唯一かつ不変です。
SpeakerId は話者が持つ ID で、世界で唯一かつ不変。エンジン間でも同じ ID を持ちます。
StyleId はスタイルごとの ID で、話者ごとに唯一であれば良いです。

声を一意に決めるには、(EngineId, SpeakerId, StyleId)の3組が揃っている必要がある、という仕様を目指しています。
現状は、音声合成APIに SpeakerId 引数が無いため、(EngineId, StyleId)の2組で一意に声が決まっています。

VOICEVOX は歴史的経緯により、 SpeakerId と StyleId が混同していることがあります。
特に型が整数値になっている SpeakerId は StyleId と混同している場合があります。
(エンジン API の SpeakerId 引数に StyleId を渡したりなど。)

StyleId は現在整数値型になっていますが、将来的にはUuidにしたいと考えています。