ついに GC の除去に成功した
地道な作業により GC を除去することができた。
w3m の GC の用途は主に、文字列と動的配列やリンクリストなどのコレクションに に使われている。
コレクションの方は量が多くないのでがんばればできる。 適宜 std::vector, std::unordered_map, std::list, std::shared_ptr などに置き換えていく。
文字列の方は、量が多いので大変。 文字列の寿命管理と長い文字列の連結用途の2つがある。 連結用途の方は、 Strcat_XXX という関数が頻出するのでわかる。 こっちは std::stringstream に置き換えて、 Strcat_XXXは << オエレーターに置き換えらえることが多い。
さらに減量
> cloc --exclude-dir=docusaurus "--match-f=\.(c|h|cpp)$" src
140 text files.
140 unique files.
0 files ignored.
github.com/AlDanial/cloc v 1.90 T=0.08 s (1664.0 files/s, 411521.6 lines/s)
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
C++ 65 2174 3058 23014
C/C++ Header 75 642 199 5536
-------------------------------------------------------------------------------
SUM: 140 2816 3257 28550
-------------------------------------------------------------------------------流れで削ったので細かく覚えていないが、 前回の cloc が 36000 くらいだったのでだいぶ削った。
regex => std::regex
hash => std::unordered_map
GC関連 => std::shared_ptr
Str => std::string
機能回復が必要
動くが使える状態ではないです。 コード整理は山場を越えたので、機能回復に注力していく。 あと #if _MSC_VER 分岐をなおす。 libuv のシステムアクセス関数で置き換えることができる目論見。 当初予定していた ptty を lubuv 化する計画は、 ftxui で代替された。 libuv はネットワークとファイルシステムアクセスの抽象化と非同期化に対して やりなおし。
module 分け
GC と global 変数への依存があって、 機能毎に分割しづらかったのだけど、 GC の除去と global 把握ができたので分けたい。
(common/core) string / url / utf-8 / logger / input interface
(use libuv) filesystem / tcp / http / https
(html) parser / renderer
(screen) tab / buffer / follow link / history / scroll / cursor
(tui) global option / keyinput / keymap / command
あと、部品間の相互参照を片方向参照に改める。 app => parser => app->width のような参照を、 app => parser(app->width) のように 事前に引数化するなどして防ぐ。 header の #include を絞る。
全体のデザイン
ひとつ問題があって cookie の処理中に 受け入れますか? という モーダルダイアログに相当するものを出したい。 ネットワークサブシステムが UI にアクセスする、 しかも keyinput をジャックするという問題がある。
オリジナルでは、その場で gets するとか、新しい入力ループを開始していた。 ftxui の netsted loop で対応できるかもしれない。
この方法では、ダイアログを放置して別のタブに切り替えることができない。 なので keyinput をスタックに積んでオーバーライドするデザインを検討。
auto answer = co_await modal_input("accept cookie?(y/n)");core ライブラリにある程度の機能を持たせる必要がある。