RosettaCodeData/Task/Active-object/Clojure/active-object.clj

37 lines
1.1 KiB
Clojure

(ns active-object
(:import (java.util Timer TimerTask)))
(defn input [integrator k]
(send integrator assoc :k k))
(defn output [integrator]
(:s @integrator))
(defn tick [integrator t1]
(send integrator
(fn [{:keys [k s t0] :as m}]
(assoc m :s (+ s (/ (* (+ (k t1) (k t0)) (- t1 t0)) 2.0)) :t0 t1))))
(defn start-timer [integrator interval]
(let [timer (Timer. true)
start (System/currentTimeMillis)]
(.scheduleAtFixedRate timer
(proxy [TimerTask] []
(run [] (tick integrator (double (/ (- (System/currentTimeMillis) start) 1000)))))
(long 0)
(long interval))
#(.cancel timer)))
(defn test-integrator []
(let [integrator (agent {:k (constantly 0.0) :s 0.0 :t0 0.0})
stop-timer (start-timer integrator 10)]
(input integrator #(Math/sin (* 2.0 Math/PI 0.5 %)))
(Thread/sleep 2000)
(input integrator (constantly 0.0))
(Thread/sleep 500)
(println (output integrator))
(stop-timer)))
user> (test-integrator)
1.414065859052494E-5