キープレスイベントなどのイベントレートを計算して表示します。私はまた最初の出来事が起こった後にだけ率計算を開始したいと思う。もう1つの要件は、特定の量のキープレスイベント後にレート計算を停止することです。それに私の現在のアプローチは、そうClojureチャンネルでのイベントレートの計算
(defn keypress-chan
"Returns a channel that receives keys"
[]
(let [out (chan) handler (fn [e] (put! out (.-key e)))]
(js/document.addEventListener "keypress" handler false)
out))
(defn tick
"Pushes to `out` 1000 ms later"
[out]
(go
(<! (timeout 1000))
(>! out 1)))
(defn get-rate
"Calculates keypress per minute rate"
[ticks pressed]
(quot (* pressed 60) ticks))
(defn complete?
[count]
(>= count 100))
(defn main-loop []
(let [key-chan (keypress-chan) ticker-chan (chan)]
(go-loop [pressed 0 ticks 0]
(let [[value ch] (alts! [key-chan ticker-chan])]
(if (= ch key-chan)
(do
;; Start timer to calculate keypress rate
(if (zero? pressed)
(tick ticker-chan))
;; Do something with `value`, i. e. the key being pressed
(when-not (complete?)
(recur (inc pressed) ticks)))
(let [speed (get-rate ticks pressed)]
(swap! app-state assoc :rate rate)
(tick ticker-chan)
(recur pressed (inc ticks))))))))
で、これは動作しますが、main-loop
内のコードは、私には醜いようです。私は、最初の値がkey-chan
に現れて初めてタイマーを起動する "トリガ"を持っていると考えていました。その後、必要に応じて別のトリガーがタイマーを停止します。しかし、私はClojureには新しく、async
との連携方法をよく知らないので、上記のコードよりも優れたものを作成できませんでした。
このループをどのように改善できますか? タイマを関数に移動し、key-chan
の最初の値でタイマーを開始できますか? 後でそのタイマーを停止できますか?
ソートされたリストに各キー押しのタイムスタンプを格納し、過去60秒間に移動平均レートを計算します。まず、古い値を破棄することは心配しません。現在の時間から60秒以内にすべての値を取り出し、数えれば平均レート/分です。 –
@AlanThompson、アイデアありがとう!試してみる。 – coquin