ゴール
Node.js で RxJS と keypress を使い、「fps の 1 フレーム内で先頭の 1 キー入力のみを受け付ける」という処理を作ること。
サンプルコード
var keypress = require('keypress');
var Rx = require('rx');
var FPS = 2;
keypress(process.stdin);
process.stdin.setRawMode(true);
process.stdin.resume();
var pauser = new Rx.Subject();
var timerSource = Rx.Observable
.timer(0, 1000 / FPS)
.timeInterval()
.map(function(data) {
pauser.onNext(true);
return data;
})
;
var wrappedHandler;
var keypressSource = Rx.Observable
.fromEventPattern(
function addHandler(handler) {
wrappedHandler = function(chr, key) {
handler(key);
};
process.stdin.addListener('keypress', wrappedHandler);
},
function removeHandelr(handler) {
process.stdin.removeListener('keypress', wrappedHandler);
}
)
.pausable(pauser)
.filter(function() {
var isStopped = pauser.isStopped;
pauser.onNext(false);
return !isStopped;
})
;
timerSource.subscribe(
function(data) {
console.log('Frame count:', data.value);
}
);
keypressSource.subscribe(
function (key) {
console.log('Input key:', key.name);
if (key && key.ctrl && key.name === "c") {
process.stdin.pause();
process.exit(0);
}
}
);
node
コマンドで実行して適当にキーを連打すると、以下の様な出力になると思います:
$node ./filename.js
Frame count: 0
Input key: j
Frame count: 1
Input key: j
Frame count: 2
Frame count: 3
Input key: n
Frame count: 4
Input key: n
Frame count: 5
Input key: k
Frame count: 6
Input key: k
Frame count: 7
Input key: k
Frame count: 8
Frame count: 9
Frame count: 10
Input key: c
同フレーム内で、2回以上のキー受付をしていないことがわかると思います。
なお、抜けるには Ctrl-C
を押して下さい。
参考リンク
- 「RxJS」初心者入門 – JavaScriptの非同期処理の常識を変えるライブラリ
- Bridging to Events
- Rx.Observable.fromEvent(element, eventName, [selector])
- Rx.Observable.fromEventPattern(addHandler, [removeHandler], [selector])
- Rx.Observable.prototype.pausable(pauser)
- Rx.Observable.timer(dueTime, [period], [scheduler])
- おしゃれCLIを作るためのnpmモジュール達 の keypress の項目