メインコンテンツまでスキップ

mainloop

いよいよ本格的な改造に踏み込みはじめる。 mainloop を分離した。

100行ちょいしかなかったの貼ってみる。

mainloop

void mainLoop() {
for (;;) {
if (popAddDownloadList()) {
ldDL();
}
if (Currentbuf->submit) {
Anchor *a = Currentbuf->submit;
Currentbuf->submit = NULL;
gotoLine(Currentbuf, a->start.line);
Currentbuf->pos = a->start.pos;
_followForm(true);
continue;
}

// event processing
if (CurrentEvent) {
CurrentKey = -1;
CurrentKeyData = NULL;
CurrentCmdData = (char *)CurrentEvent->data;
w3mFuncList[CurrentEvent->cmd].func();
CurrentCmdData = NULL;
CurrentEvent = CurrentEvent->next; // イベント。リンクリストになっている。デキューしている
continue;
}

// get keypress event
if (Currentbuf->event) {
if (Currentbuf->event->status != AL_UNSET) {
CurrentAlarm = Currentbuf->event;
if (CurrentAlarm->sec == 0) { /* refresh (0sec) */
Currentbuf->event = NULL;
CurrentKey = -1;
CurrentKeyData = NULL;
CurrentCmdData = (char *)CurrentAlarm->data;
w3mFuncList[CurrentAlarm->cmd].func();
CurrentCmdData = NULL;
continue;
}
} else
Currentbuf->event = NULL;
}
if (!Currentbuf->event)
CurrentAlarm = &DefaultAlarm;
if (CurrentAlarm->sec > 0) {
mySignal(SIGALRM, SigAlarm);
alarm(CurrentAlarm->sec);
}
mySignal(SIGWINCH, resize_hook);
{
do {
if (need_resize_screen)
resize_screen();
} while (sleep_till_anykey(1, 0) <= 0);
}
auto c = getch(); // 👈 ブロック
if (CurrentAlarm->sec > 0) {
alarm(0);
}
if (IS_ASCII(c)) { /* Ascii */
if (('0' <= c) && (c <= '9') &&
(prec_num || (GlobalKeymap[c] == FUNCNAME_nulcmd))) {
prec_num = prec_num * 10 + (int)(c - '0');
if (prec_num > PREC_LIMIT)
prec_num = PREC_LIMIT;
} else {
set_buffer_environ(Currentbuf);
save_buffer_position(Currentbuf);
keyPressEventProc((int)c); // 👈 KeyMap で dispatch
prec_num = 0;
}
}
prev_key = CurrentKey;
CurrentKey = -1;
CurrentKeyData = NULL;
}
}

mainloop は無限loop で実装されていて getch 関数でキーボード入力をブロックしています。 あとはシグナルのわりこみイベントがあります。 主要な入力は以下です。

  • keyboard
  • signal: SIGWINCH term の resize
  • signal: SIGALRM timer イベント
  • signal: SIGINT ctrl-c

キーボードが入力すると KeyMap のコールバックを実行して、 ループが一回まわります。 このとき、イベントが来ていれば処理されます。 なので、git アニメのコマを送るのにキーボード連打が必要だったりします。

libuv にうってつけ

ループを libuv 管理にして、 キーボードやシグナルなどの入力を一元的に管理することを目論んでいる。 以下も追加できる予定。

  • Windows 互換(POSIXがだいたい隠蔽できる)
  • network 処理 の非同期化(ダウンロード中のタブ切り替えなど)
  • アニメーション実行(あとで)