I'm working on a game in Clojure using Swing. I have a KeyListener to take care of controls, but it's not updating a ref.
(def move (ref :drop))
(defn get-move
[block state x y moves]
(do (println @move)
(if (check-move @move x y block state) @move
:nothing)))
(defn listener
[keyevent]
(let [c (.getKeyChar keyevent)]
(do (println c)
(cond (= c "j") (dosync (ref-set move :left))
(= c "l") (dosync (ref-set move :right))
(= c "i") (dosync (ref-set move :rotate))
(= c "k") (dosync (ref-set move :drop))))))
(defn make-keylistener
[]
(proxy [KeyAdapter] []
(keyPressed [event]
(listener event))))
Now, the idea is that the main function that updates the gui calls get-move. It checks if the move ref is valid in the game, and if so returns it. The listener is attached to a JPanel and changes the ref based on a keypress. The listener works fine - whenever a button is pressed, it prints out the key char. I can only assume it's changing the ref. However, get-move always returns the same value - it never sees @move change. I feel like I'm misunderstanding something fundamental about concurrency and state in Clojure. What am I doing wrong, and is there a more functional way of handling this?
Thanks!
EDIT: Same problem occurs if I use atoms.