diff --git a/project.clj b/project.clj index 126bf71..3948798 100644 --- a/project.clj +++ b/project.clj @@ -7,7 +7,7 @@ :source-paths ["src/clj"] :dependencies [[org.clojure/clojure "1.5.1"] [domina "1.0.2-SNAPSHOT"] - [org.clojure/clojurescript "0.0-1878"] + [org.clojure/clojurescript "0.0-1844"] [org.clojure/core.async "0.1.222.0-83d0c2-alpha"]] :plugins [[lein-cljsbuild "0.3.3"]] diff --git a/resources/public/index.html b/resources/public/index.html index 9c3a54d..8d18882 100644 --- a/resources/public/index.html +++ b/resources/public/index.html @@ -8,6 +8,9 @@ +
FPS:
+
Position:
+
O
diff --git a/src/clj/frpong/core.clj b/src/clj/frpong/core.clj index e58c1fc..568c47b 100644 --- a/src/clj/frpong/core.clj +++ b/src/clj/frpong/core.clj @@ -1,6 +1,6 @@ (ns frpong.core) -(defn foo - "I don't do a whole lot." - [x] - (println x "Hello, World!")) +(defmacro go-loop [& body] + `(cljs.core.async.macros/go + (while true + ~@body))) diff --git a/src/cljs/frpong/core.cljs b/src/cljs/frpong/core.cljs index 924c138..af45b90 100644 --- a/src/cljs/frpong/core.cljs +++ b/src/cljs/frpong/core.cljs @@ -1,20 +1,61 @@ (ns frpong.core - (:require [cljs.core.async :as async - :refer [! chan put!]] - [domina :as dom] + (:require [frpong.helpers :as h] + [cljs.core.async :as async + :refer [! chan put! close! sliding-buffer dropping-buffer timeout]] + [domina :as dom :refer [log]] [domina.events :as ev]) - (:require-macros [cljs.core.async.macros :as m :refer [go]])) + (:require-macros [cljs.core.async.macros :as m :refer [go]] + [frpong.core :refer (go-loop)])) +(defn positioner [tick-chan vel-chan pos-chan-in pos-chan-out] + (go-loop + (let [tick (! pos-chan-out pos-next)))) -(defn event-chan [event-type] - (let [c (chan)] - (ev/listen! js/document event-type - (fn [e] (put! c e))) - c)) +(defn collision-detector [width height tick-chan pos-chan vel-chan-in vel-chan-out] + (go-loop + (let [tick (! vel-chan-out + (cond + (< xn 0) [(- vel-x) vel-y] + (< yn 0) [vel-x (- vel-y)] + (> xn width) [(- vel-x) vel-y] + (> yn height) [vel-x (- vel-y)] + :else [vel-x vel-y]))))) (defn ^:export init [] - (let [mm-chan (event-chan :mousemove)] - (go - (while true - (let [e (! pos-chan init-pos)) + (go (>! vel-chan init-vel)) + + (go-loop + (let [[x y] (map int (! chan put! close! sliding-buffer dropping-buffer timeout]] + [domina :as dom :refer [log]] + [domina.events :as ev]) + (:require-macros [cljs.core.async.macros :as m :refer [go]] + [frpong.core :refer (go-loop)])) + +(defn now [] + (.valueOf (js/Date.))) + +(defn put-all! [cs x] + (doseq [c cs] + (put! c x))) + +(defn cconj [v c1] + (let [c2 (chan)] + (go + (>! c2 v) + (while true + (>! c2 (! c (f (! c v)))) + c)) + +(defn interval-chan + ([msecs] + (interval-chan msecs :leading)) + ([msecs type] + (interval-chan (chan (dropping-buffer 1)) msecs type)) + ([c msecs type] + (condp = type + :leading (go-loop + (>! c (now)) + (! c (now)))) + c)) + +(defn throttle + ([source control] + (throttle (chan) source control)) + ([c source control] + (go + (loop [state ::init last nil cs [source]] + (let [[_ sync] cs] + (let [[v sc] (alts! cs)] + (condp = sc + source (condp = state + ::init (do (>! c v) + (recur ::throttling last + (conj cs control))) + ::throttling (recur state v cs)) + sync (if last + (do (>! c last) + (recur state nil + (conj (pop cs) control))) + (recur ::init last (pop cs)))))))) + c)) + +(defn debounce + ([source msecs] + (debounce (chan) source msecs)) + ([c source msecs] + (go + (loop [state ::init cs [source]] + (let [[_ threshold] cs] + (let [[v sc] (alts! cs)] + (condp = sc + source (condp = state + ::init + (do (>! c v) + (recur ::debouncing + (conj cs (timeout msecs)))) + ::debouncing + (recur state + (conj (pop cs) (timeout msecs)))) + threshold (recur ::init (pop cs))))))) + c)) + +(defn after-last + ([source msecs] + (after-last (chan) source msecs)) + ([c source msecs] + (go + (loop [cs [source]] + (let [[_ toc] cs] + (let [[v sc] (alts! cs :priority true)] + (recur + (condp = sc + source (conj (if toc (pop cs) cs) + (timeout msecs)) + toc (do (>! c (now)) (pop cs)))))))) + c)) + +(defn fan-in + ([ins] (fan-in (chan) ins)) + ([c ins] + (go (while true + (let [[x] (alts! ins)] + (>! c x)))) + c)) + +(defn distinct-chan + ([source] (distinct-chan (chan) source)) + ([c source] + (go + (loop [last ::init] + (let [v (! c v)) + (recur v)))) + c)) + +(defn event-chan [event-type] + (let [c (chan)] + (ev/listen! js/document event-type #(put! c %)) + c)) + +(defn frame-chan [] + (let [c (chan (sliding-buffer 1000)) + step (fn step [ts] (do (put! c ts) (.requestAnimationFrame js/window step)))] + (.requestAnimationFrame js/window step) + c)) + +(defn counting-chan [source] + (let [c (chan)] + (go + (loop [count 0] + (! c count) + (recur (inc count)))) + c)) + +(defn diff-chan [source] + (let [c (chan)] + (go + (let [start (! c (- ts start)) + (recur ts))))) + c))