見出し画像

MGL週報 #55 - 大規模リファクタリング進行中

このエントリはゲーム開発用フレームワーク「MGL」の開発記録です。MGLはzlibライセンスの下に無償で提供されています。



今週の作業内容

大規模リファクタリング

clang-tidyによるコード解析の環境がおおよそ整ったため、リファクタリングの作業に着手しています。

この作業はプロジェクト全体に変更を加えるため、色々と慎重に進めていく必要があります。処理結果に影響を与えてはいけないのはもちろん、既にドキュメント化済みの項目については差異が発生しないよう並行して進めていかなければなりません。また、修正した結果clangでは通るけどMSVCではビルドに失敗するというケースにも遭遇しています。

このような問題から、作業タスクを機能単位で分割して検証しながらの進行となっています。

リンク先のストーリーボードに登録されているタスクが全て「終了」となったらこの作業は完了です。全体としては重たい作業ではありますが、うまく分割して少しづつでも進められるようにしています。

clang-tidyによるチェックは問題の検出よりもコーディングポリシーの定義という側面が強く、その内容の取捨選択もまた時間を取られる要素の1つです。今回は特定のカテゴリのポリシーを一旦全部有効化し、MGLの実装内容に合わなかったり対処が難しいものを無効化しながらリファクタリングを進めています。

この作業を一通り終えた暁には、MGLのポリシーを定義した設定ファイルと、それに準拠したソースコードが手元に残るはずです。これこそが今回の最大の目的です。そこから先はポリシーに従うことでコードの品質を保ったり、今回やむなく無効化した設定を復活させて改善を試みたりといった事が可能になる……といった未来を期待して今の作業を進めています。

clang-formatのあれこれ

タスク化こそしていませんが、clang-formatの設定にも色々と悩んでいます。

こちらは既存のソースコードの書き方を再現するような設定を作ってみたのですが、一部で大きく書式を変えてしまう……と言うより壊してしまう現象に悩まされています。

具体的には、次のようなコードです。

// 何かの定数テーブル
constexpr const int kAnyTable[] =
{
    100,
    210,
    306,
    428
};

// メッセージテーブル
constexpr const char *kMessageTable[] =
{
    "message1",
    "message2",
    "message3",
    "message4"
};

ソースコード上で不規則な定数を扱う際にテーブルとして定義することは多々あります。しかし、これを整形したところ……

// 何かの定数テーブル
constexpr const int kAnyTable[] =
        {
            100,
            210,
            306,
            428};

// メッセージテーブル
constexpr const char *kMessageTable[] =
        {
            "message1",
            "message2",
            "message3",
            "message4"};

変なインデントが入っているし、'}'の位置も変ですね。'}'は末尾の要素の後に','を入れることで修正できますが、インデントの問題はちょっと複雑です。

これはclang-formatが定数配列の定義を「本来1行で書くところを、長くなるため折り返した記述」と認識している事が原因らしいです。その際に 'ContinuationIndentWidth' という「途中で折り返した行にインデントをいくつ入れるか」のパラメータを参照し、これがデフォルトで8であるために変なインデントが入ってしまっています。

では 'ContinuationIndentWidth: 0' とすれば直るのかと言えば、ここに限っては意図通りになります。しかし、関数の引数やif文の条件式を複数行に分けて書いた場合などもインデントが0になってしまうため、今度はそちらが壊れてしまいます。

// 適用前
if (
    anyLooooooooooooongExpr1 ||
    anyLooooooooooooongExpr2 ||
    anyLooooooooooooongExpr3)
{
    ...
}

// 適用後
if (
anyLooooooooooooongExpr1 ||
anyLooooooooooooongExpr2 ||
anyLooooooooooooongExpr3)
{
    ...
}

ここでは一例として挙げましたが、このような「あっちを立てればこっちが立たず」がどこにどれだけ潜んでいるのかは未だに見えていません。ですので、一旦はソースコード全体に適用せずに、Vimのプラグインを用いて部分的に適用しながら様子を見ている状態です。

理想は管理下にあるソースコード全体を整形するバッチ処理を実行して、意図した通り綺麗に書式が揃う事です。それを実現するにはもう少しドキュメントを読み漁って検証を進める必要がありそうですね。


その他

ドキュメント化予定だったセーブデータ関連の機能、今更作り直したくなってきました。

この記事が気に入ったらサポートをしてみませんか?