Open4

Mini-Pkg: 簡易パッケージシステムの設計

okuokuokuoku

iOSやAndroidのようなシステム側のファイルシステムがそもそもパッケージをサポートしている場合は、そのパッケージシステム(AAsset 等)を直接使うことになる。PCやWebではパッケージシステムが存在しないため自前のものを設計する必要がある。

okuokuokuoku

Prior art

手元のプロジェクトでは伝統的にスクストの事例 https://www.jp.square-enix.com/conference/2014/technical_seminar/img/pdf/SQEX_DevCon_sugimoto.pdf を手本にしたidベースのパッケージシステムを使ってきた。が、YuniframeはUnityや他の既存のPOSIXアプリをWasm経由で動かすというrequirementが有るため名前ベースのファイルシステムを採用せざるを得ない。

よくあるライブラリとしてはSDLと同作者のPhysicsFS https://icculus.org/physfs/ がある。これはパッケージとして.zipのような既存のアーカイブフォーマットを使用する。

okuokuokuoku

Requirements

今回のターゲットはアセットエディタ(いわゆるお絵描きソフト)なので大量のスクリプト(4KiB以下)および多くのアセット類(256KiB以上のBMP類)を抱えることになる。これは要求としてはゲーム自体と同様のものと言える。

アーカイバとかを用意する前に、 AAsset のような他のアセットシステムと共通に使えるwrapperを用意した方が良いかな。

パスをハッシュ化するかは悩みどころ。。ハッシュ化するならFNV1aかな。巨大領域だと遅い https://aras-p.info/blog/2016/08/09/More-Hash-Function-Tests/ けど、まぁシンプルなので。

okuokuokuoku

ファイル領域の抽象化

通常のファイルシステムとかなり違うのでどうやってドキュメントしたもんか。。

path はC文字列であり、通常のスラッシュ区切りのファイルパスやWindowsにおけるバックスラッシュ(円記号)区切りのパスの 両方 を取り扱う。プログラマはファイルパスがMini-Pkgで扱われる内部のパスなのか、OSネイティブのパスなのかを意識する必要がある。

プロバイダpathresolve (後述) できる主体であり、OSのファイルシステムであったり、パッケージであったりする。Mini-Pkgのランタイムは、いくつかデフォルトのプロバイダを提供し、バックエンドに依存しないプログラミングを可能にする。プロバイダは使用前に activate されている必要があり、必要に応じて deactivate できる。プロバイダによっては、複数の activate 可能な領域を持っていることがある。

全ての pathresolve される必要がある。一度Resolveされたパスはidが発行され以降の処理はidを通して行う。 idは、使用後解放する必要があるresolve はファイルのopenではなく、メモリの許す限り行える。(普通のシステムはファイルを開ける数は4096とかで打ち止めになるので、ライブラリ側で自動的に閉じたりといった配慮が必要になる。)

I/Oキューはとりあえず "default" の一本だけとする。たぶんプロバイダに紐付けられた高優先度かつ低レイテンシキューと、共通の低プライオリティキューは追加で必要だろう。

プロバイダの遅延

プロバイダはいくつかのプラットフォーム要因の遅延を起こすことがある。

  • On Demand Resourceの取得
  • クラウドストレージとの同期や衝突
  • 前回異常終了時からの回復処理

API的にどう吸収すべきかは何とも言えない。アプリケーションでハンドルさせない方が良いのかもしれない。。