ここらでエディタのデザインについて再考する。エディタを関数と考えるとこんな感じだろう。
(テキスト画像, 新テキスト) = f(イベント, 画面情報, 旧テキスト)
つまり、あるテキストがあって、そこにキーボードやマウスイベントを発生して更新した後のテキストを得る。また、画面の幅やフォントなどの情報を使って同時にテキストの内容を表示した画像を得る。
残念ながら、これをそのまま作っても遅すぎて数百文字程度のテキストしか扱えないので、最適化を色々考える事になる。特に画面表示はコストが高いので、どのような情報が必要なのか考える。
- テキスト
- 論理桁、行情報: ある文字が論理行のどの桁、行にあるか(文字単位)。
- 物理桁、行情報: ある文字が物理行のどの桁、行にあるか(文字単位)。
- 論理座標情報: ある文字が、論理座標のどの座標にあるか(ピクセル単位)。
- (物理座標情報: ある情報が、画面上のどの座標にあるか。)フレームワークが提供
雰囲気としては、この階層をイベントが下から上に登って行き、文字列を更新してからその影響が上から下に下り、画面が更新される事になる。これらの処理を関数と考えると次のようになる。
- 編集コマンド = コマンド解釈(物理論理座標変換(イベント, 画面情報))
- 新テキスト = テキスト変更(旧テキスト, 編集コマンド)
- 論理行 = 改行検索(新テキスト)
- 物理行 = 画面幅補正(論理行, 画面情報)
- テキスト画像 = 描画(物理行, 画面情報)
最適化のためには方向性が逆の二つの方法がある。
- 積分 : 例えば、キーが複数回押された場合、文字を一つずつ追加するのではなく、単位時間内に押されたイベント履歴から作られる文字列を全て追加する。
- 微分 : 例えば文字が追加された場合、テキスト全体を表示し直すのでは無く、追加された分だけのテキストを表示する。
- このためには、テキストの差分、論理行の差分、物理行の差分、論理座標の差分をそれぞれ取得する必要がある。
最適化とは状態の微分または積分であると考えると多少スッキリする。
テキストエディタでの実装戦略、テキストを固定長文字列で表現するか、リンクリストで表現するか等等は、イベント履歴または変更差分をどう表現するかという問題になる。これを念頭に置いて再びソースコードを読み直していこう。
今まで読んだソースコードの色々