コンテンツにスキップ
Documentation

アーキテクチャ概要

Media Sortは、厳密な依存関係順序で構成された4つのクレートを持つRustワークスペースです。このページでは、新しいコントリビューターがコードベースを理解しやすくするための高レベルなマップを提供します。

crates/
├── media-sort-core # 設定、i18n、取り消し/やり直し、メディアタイプ(システム依存なし)
├── media-sort-backend # ファイルシステム、メディアデコード、メタデータ抽出
├── iced-automation # ヘッドレスicedアプリシミュレーションと動画出力
└── media-sort-gui # iced GUIアプリケーションバイナリ

依存関係の方向: media-sort-gui → media-sort-backend + iced-automation → media-sort-core

media-sort-coreは他の3つのクレートに依存してはいけません。純粋なデータ型、設定ロジック、ローカライゼーションのみを含み、ファイルシステムアクセス、メディアデコード、GUIコードは一切含まれません。

  • 設定: 5つのサブ構造体(General、KeyBindings、MetadataPanel、PinnedFolders、WindowPosition)を持つSettingsStore。$CONFIG_DIR/media-sort/config.tomlにTOML形式で読み書きされます。
  • 国際化: システムロケールから自動検出するFluentベースのローカライゼーション。ロケールファイルはresources/locale/{en,de,ja}/にあります。
  • 取り消し/やり直し: done/undoneスタックを持つReversibleActionトレイト。操作にはMove、Copy、Rename、Deleteが含まれます。
  • メディアタイプ: MediaType列挙型(Image/Video/Audio)、起動時に初期化されるグローバルMediaRegistry。
  • ファイルシステム: walkdirベースの再帰的スキャン、notifyベースのライブ変更監視、プラットフォーム固有のゴミ箱への削除。
  • メディアデコード: 動画はlibmpv(カスタムwgpuシェーダー使用)、画像はimageクレート、音声はrodio + symphonia。
  • メタデータ: EXIF(kamadak-exif)、ID3(id3)、Vorbisコメント(metaflac)、MP4タグ(mp4ameta)。
  • サムネイル: LRUキャッシュを使用したバックグラウンドサムネイル生成。
  • ヘッドレスエミュレーション: ウィンドウなしでicedアプリを実行し、レンダリングされたフレームをキャプチャします。
  • 動画出力: ffmpegパイプライン経由でデモフローをMP4にレンダリングします。
  • マクロ: ボイラープレート削減のための手続き型マクロ(#[message]、#[state])。
  • App: エントリポイント、更新関数(app.rs)、ビュー構成、サブスクリプション。
  • State: すべてのUI状態、フォルダツリー、メディアエントリ、キャッシュを保持するAppState構造体。
  • Messages: ネストされたサブ列挙型(FolderMessage、MediaMessage、SettingsMessage、VideoMessage)を持つMessage列挙型。
  • Views: UIを構成する10個のビューモジュール(メインレイアウト、フォルダパネル、グリッド、プレビューなど)。
  • Widgets: カスタムウィジェット(動画プレーヤー、シェーダー、モーダル、フォルダアイコン)。
  • Subscriptions: キーボードイベント、動画再生イベント、ウィンドウイベント、ティックタイマー。

UIアーキテクチャ: The Elm Architecture(TEA)

Section titled “UIアーキテクチャ: The Elm Architecture(TEA)”

Media SortはicedのThe Elm Architecture実装に従っています。

  1. Model: AppStateがすべてのアプリケーション状態を保持
  2. Message: Message列挙型がすべての可能なイベントを表現
  3. Update: app::update()は純粋関数: (AppState, Message) → (AppState, Task<Message>)
  4. View: app::view()が現在の状態をウィジェットツリーとしてレンダリング
  5. Subscription: app::subscription()が4つのイベントストリームをマージ: ティックタイマー、キーボード、ウィンドウイベント、動画再生

状態の変更は純粋です。副作用(ファイルI/O、サムネイル生成、メディア再生)は、更新関数から返されるTaskオブジェクトを通じて処理されます。

依存関係 目的
iced GUIフレームワーク(ウィジェット、futures、wgpuレンダリング)
libmpv / libmpv-sys 動画デコードと再生
symphonia + rodio 音声デコードと出力
kamadak-exif EXIFメタデータ抽出
image 画像読み込みとサムネイル生成
fluent / unic-langid 国際化
wgpu + ash GPUレンダリング、動画用Vulkan相互運用
lucide-icons アイコンフォント
  • 開発: 全依存関係にopt-level = 3を適用し、デバッグモードでもGUIの応答性を維持。
  • リリース: lto = "fat"、codegen-units = 1で最大限の最適化。
  • プレコミット: cargo fmt --all --およびcargo clippy --fix --all-targets -- -D warnings。
  • コード生成: media-sort-core/build.rsがロケールファイルをスキャンし、locales_codegen.rsを生成。
作業内容 出発点
設定の追加 crates/media-sort-core/src/settings/ + ドキュメント更新
キーバインドの追加 crates/media-sort-core/src/settings/keybindings.rs
UIコンポーネントの追加 crates/media-sort-gui/src/view/またはwidgets/
メディアフォーマット対応の追加 crates/media-sort-core/src/media_type.rs + バックエンドデコーダー
動画の問題修正 crates/media-sort-backend/src/media/mpv_context.rs
ロケール文字列の追加 resources/locale/{en,de,ja}/main.ftl