From d06311c730c5381efc463f1cc9b48599a3109e64 Mon Sep 17 00:00:00 2001 From: Abhinav Sarkar Date: Wed, 16 Oct 2013 21:21:32 +0530 Subject: [PATCH] Changed to use signals terminology instead of core.async channels and functions --- src/clj/frpong/core.clj | 4 + src/cljs/frpong/core.cljs | 171 +++++++++--------- .../frpong/{helpers.cljs => signals.cljs} | 99 +++++----- 3 files changed, 135 insertions(+), 139 deletions(-) rename src/cljs/frpong/{helpers.cljs => signals.cljs} (89%) diff --git a/src/clj/frpong/core.clj b/src/clj/frpong/core.clj index 568c47b..7d3b4d2 100644 --- a/src/clj/frpong/core.clj +++ b/src/clj/frpong/core.clj @@ -4,3 +4,7 @@ `(cljs.core.async.macros/go (while true ~@body))) + +(defmacro rd [& body] `(cljs.core.async/! ~@body)) diff --git a/src/cljs/frpong/core.cljs b/src/cljs/frpong/core.cljs index ddae46e..474cf73 100644 --- a/src/cljs/frpong/core.cljs +++ b/src/cljs/frpong/core.cljs @@ -1,35 +1,34 @@ (ns frpong.core - (:require [frpong.helpers :refer (mult tap map-chan diff-chan key-chan frame-chan tick-chan event-chan)] - [cljs.core.async :refer [! chan put! close! sliding-buffer]] + (:require [frpong.signals :refer (signal keyboard ticks dom-events mult tap)] [domina :as dom :refer [log]] [domina.events :as ev]) (:require-macros [cljs.core.async.macros :as m :refer [go]] - [frpong.core :refer (go-loop)])) + [frpong.core :refer (go-loop rd wt)])) ;; ;; Signal Diagram ;; -;; +-d-----------+--------------------------+ -;; v | | -;; keyboard +-e-> sampler +---k---> paddle-postnr +-d-+ +-> gravitation +--+ | -;; ^ | p a | -;; t | | | | -;; | | | | | -;; +-------+ +-p----------+-|---+ | d -;; | | +-a-------|-|------+---------------+ | -;; | v v | | | v -;; browser +-f--> ticker +-+--t--> ball-postnr +-p-+-|------|------------p-> renderer -;; ^ | ^ | | | ^ ^ -;; Signals | | +-----|---------+ | | | | -;; ------- s | | l +--d--+ | s t -;; e: keyboard events | | | +-+-----|-------+ | | | -;; k: keydowns | | p l +-a-|-------|----+ | | -;; f: frames | | v v v v +-l--+ | | -;; t: ticker | +---t-> collision-detr | | -;; p: ball position | | ^ +-s--+-----------------------+ | -;; l: ball velocity | | s | | -;; a: ball acceleration +-----|-------------+-------------+ | -;; d: paddle positions | | -;; s: game state +------------------------------------------------------+ +;; +-d-----------+--------------------------+ +;; v | | +;; keyboard +-e-> sampler +---k---> paddle-postnr +-d-+ +-> gravitation +--+ | +;; ^ | p a | +;; t | | | | +;; | | | | | +;; +-------+ +-p----------+-|---+ | d +;; | | +-a-------|-|------+---------------+ | +;; | v v | | | v +;; browser +-b--> ticker +-+--t--> ball-postnr +-p-+-|------|------------p-> renderer +;; ^ | ^ | | | ^ ^ +;; Signals | | +-----|---------+ | | | | +;; ------- s | | l +--d--+ | s t +;; b: browser ticks | | | +-+-----|-------+ | | | +;; t: game ticks | | p l +-a-|-------|----+ | | +;; e: keyboard events | | v v v v +-l--+ | | +;; k: keydowns (at rate of t) | +---t-> collision-detr | | +;; p: ball position | | ^ +-s--+-----------------------+ | +;; l: ball velocity | | s | | +;; a: ball acceleration +-----|-------------+-------------+ | +;; d: paddle positions | | +;; s: game state +------------------------------------------------------+ ;; ;; All signals except the signal e are at the rate of the signal f. The signal e is at the rate ;; at which the keyboard issues events. @@ -74,11 +73,11 @@ (defn setup-gravity-controls "Sets up keyboard controls for changing gravity." [] - (let [keydowns (first (event-chan :keydown)) + (let [keydowns (first (dom-events :keydown)) actions { 37 #(- % *gravity-step*) 39 #(+ % *gravity-step*) } mass-el (dom/by-id "mass")] (go-loop - (let [k (:keyCode (! ticks (! acc (gravity-acc (! pos-out pos-next)))) + (let [tick (rd ticks) + pos-next (next-pos (rd pos-in) (rd vel) (rd acc) tick)] + (wt pos-out pos-next)))) (defn paddle-positioner "Paddle Positioner component. @@ -232,14 +227,14 @@ and outputs it to the `pos-out` signal." [keys pos-in pos-out] (go-loop - (let [[lpos rpos] (! pos-out [(move lpos :w :s) (move rpos :up :down)])))) + (wt pos-out [(move lpos :w :s) (move rpos :up :down)])))) (defn in-y-range? [y paddle-y] (and (> y (- paddle-y *padding*)) (< y (+ paddle-y *paddle-size* *padding*)))) @@ -280,13 +275,13 @@ signals respectively." (go-loop - (let [;; get all current values - tick (! vel-out [vel-xn vel-yn]) - (>! game-state [state-n score-n])))) + (wt vel-out [vel-xn vel-yn]) + (wt game-state [state-n score-n])))) (defn renderer "Renderer component. @@ -325,10 +320,10 @@ (dom/set-style! ball-el "fill" "orange") (dom/set-text! msg-el "") (go (loop [fps-p nil score-p nil] - (let [fps (int (/ 1000 (! chan put! close! sliding-buffer dropping-buffer timeout]] [domina :as dom :refer [log]] @@ -9,6 +9,8 @@ (defn now [] (.valueOf (js/Date.))) +(defn signal [] (chan 1)) + (defn put-all! [cs x] (doseq [c cs] (put! c x))) @@ -23,7 +25,7 @@ (close! c)))) c)) -(defn map-chan [f source] +(defn smap [f source] (let [c (chan)] (go (loop [] (if-let [v (! c x))) c)) -(defn distinct-chan [source] +(defn scounter [source] (let [c (chan)] (go - (loop [last ::init] - (let [v (! c v)) - (recur v)))) + (loop [count 0] + (if-let [v (! c count) (recur (inc count))) + (close! c)))) c)) -(defn event-chan +(defn sdiff [source] + (let [c (chan)] + (go + (let [start (! c (- v start)) (recur v)) + (close! c))))) + c)) + +(defn sampler [source n] + (let [c (chan)] + (go + (loop [count 0] + (if-let [v (! c v)) + (recur (rem (inc count) n))) + (close! c)))) + c)) + +(defn dom-events ([event-type] (let [c (chan) [lkey] (ev/listen! event-type #(put! c %))] @@ -136,10 +158,12 @@ [lkey] (ev/listen! node event-type #(put! c %))] [c #(do (ev/unlisten-by-key! lkey) (close! c))]))) -(defn key-chan [keydowns keyups sampler keycodes] - (let [c (chan) - ops { keydowns conj - keyups disj }] +(defn keyboard [sampler keycodes] + (let [[keydowns kd-stop-fn] (dom-events :keydown) ;; keydowns signal + [keyups ku-stop-fn] (dom-events :keyup) ;; keyups signal + c (chan) + ops { keydowns conj + keyups disj }] (go (loop [keys #{}] (let [[v ch] (alts! [keydowns keyups sampler] :priority true)] (if-not (nil? v) @@ -150,9 +174,9 @@ (recur keys))) (do (>! c keys) (recur keys))) (close! c))))) - c)) + [c #(do (kd-stop-fn) (ku-stop-fn))])) -(defn frame-chan [] +(defn frames [] (let [fc (chan (sliding-buffer 1000)) rc (chan (sliding-buffer 10)) step (fn step [ts] @@ -168,44 +192,17 @@ (.requestAnimationFrame js/window step) [fc stop-fn])) -(defn tick-chan [frames] - (let [c (chan)] +(defn ticks [] + (let [c (chan) + [frames stop-fn] (frames) + frames-diff (sdiff frames)] (go - (loop [prev (! c t)) (recur t)) (close! c)))) - c)) - -(defn counting-chan [source] - (let [c (chan)] - (go - (loop [count 0] - (if-let [v (! c count) (recur (inc count))) - (close! c)))) - c)) - -(defn diff-chan [source] - (let [c (chan)] - (go - (let [start (! c (- v start)) (recur v)) - (close! c))))) - c)) - -(defn dropping-chan [source n] - (let [c (chan)] - (go - (loop [count 0] - (if-let [v (! c v)) - (recur (rem (inc count) n))) - (close! c)))) - c)) + [c stop-fn])) (defprotocol Mux (muxch* [_]))