WSNタスク: イベントコンテントの構造をできるだけフラットにする

Issue #351 resolved
k4nagatsuki repo owner created an issue

まず、CardWirthのイベントのデータ構造には根本的な問題があります。

ツリー状の表示を見れば分かる通り、イベントは、たとえ親子のコンテントが1つずつであっても、常に階層構造になっています。この構造は以下のように非常にまずいものです。

  • このデータ構造を処理するには大抵再帰が必要になります。再帰処理を繰り返すとすぐにスタックオーバーフローの問題が発生します。
  • この構造をそのままXML化すると、イベントツリーの内容によってはすさまじいネスト量のデータが生成されます。

そして今のWSN形式では、階層構造をそのままXML化しています。XMLを処理する言語とライブラリにもよりますが、これは人間が普通に作れる程度の長さでプログラムが処理不能になってしまうようなイベントツリーが作れてしまう事を意味します。実際、cwxeditorで200コンテントあまりを連ねたイベントツリーを作ると読込エラーが発生する場合があります。

そこで、データ構造を組み替えてフラットにする事を考えなくてはなりません。基本的に階層が必要なのは分岐がある時だけです。子コンテントが1つ、その次の子コンテントも1つ……というデータは、並列に書けるはずです。

以下のような構造を取り入れて、これを実現する事を考えています。

次が既存のイベントツリー表現の例です。

<Contents>
    <Start name="イベンツリート">
        <Contents>
            <Set type="StepUp" step="ステップ1">
                <Contents>
                    <Branch type="Step" value="1" step="ステップ1">
                        <Contents>
                            <Call type="Package" name="1" link="1">
                                <Contents>
                                    <Set type="StepUp" step="ステップ1">
                                        <Contents>
                                            <Set type="StepUp" step="ステップ1">
                                                <Contents>
                                                    <Set type="StepUp" step="ステップ1">
                                                        <Contents />
                                                </Set>
                                                </Contents>
                                            </Set>
                                        </Contents>
                                    </Set>
                                </Contents>
                            </Link>
                            <Link type="Package" name="2" link="2">
                                <Contents />
                            </Link>
                        </Contents>
                    </Set>
                </Contents>
            </Set>
        </Contents>
    </Start>
</Contents>

これをこうします。

<ContentsLine>
    <Start name="イベンツリート" />
    <Set type="StepUp" step="ステップ1" />
    <Branch type="Step" value="1" step="ステップ1">
        <Contents>
            <ContentsLine>
                <Call type="Package" name="1" link="1" />
                <Set type="StepUp" step="ステップ1" />
                <Set type="StepUp" step="ステップ1" />
                <Set type="StepUp" step="ステップ1" />
            </ContentsLine>
            <Link type="Package" name="2" link="2" />
        </Contents>
    </Branch>
</ContentsLine>

このフラットな形式は上の現行形式と同じだけの情報量を持ちながら、遥かに見やすく、データ量が少なく、スタック階層を消費しません。

Comments (5)

  1. k4nagatsuki reporter

    pull request #1383

    エンジンの内部実装を上記のように変更してみました。クラシックなシナリオを変換した時にフラット形式になります。

    ちょっと怖いので、しばらくはマージせずにテストします。この変更が入ったテスト版をアップロードしたので、興味のある方は試してみてください。私は以下の項目についていくらかテストをしましたが、CWのイベント構造は結構複雑なので(特にフラグ判定周りとか)、見逃している問題があるかもしれません。

    • イベント実行(分岐あり・なし)
    • コール系の実行
    • デバッガの表示
    • デバッガからの任意コンテントの強制実行
    • デバッガからエディタを開いて、デバッガで選択したコンテントがエディタ上で正しく選択される(CWXパス)
    • チェックコンテント周り(再実行後も。高速化のために最初の実行時に子コンテンツのデータを作るので、初回と再実行の両方でテストが必要)
    • ツリー末尾のスタートのコールがリンクに置換されるか?
    • ツリー末尾のパッケージのコールがリンクに置換されるか?
    • 逆変換
  2. k4nagatsuki reporter

    うっかりpull requestに起動時の拠点オープンに関するバグ修正を混ぜてしまいましたが、とりあえず一通り問題なさそうなのでマージを行いました。

    テストの途中でフラット構造とは関係ないイベント処理のバグを見つけてしまったので、別途pull requestします。

  3. Log in to comment