2011-11-11 3 views
1

나는 Swing을 사용하여 Clojure에서 게임을하고있다. 컨트롤을 처리하는 KeyListener가 있지만 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)))) 

이제는 gui를 업데이트하는 주요 기능이 get-move를 호출한다는 아이디어가 있습니다. 이동 참조가 게임에서 유효한지 확인한 후 이동 참조를 반환합니다. 청취자는 JPanel에 첨부되고 키 누르기를 기반으로 참조를 변경합니다. 청취자는 잘 작동합니다. 버튼을 누를 때마다 키 문자가 인쇄됩니다. 나는 그것이 단지 심판을 바꾸고 있다고 생각할 수있다. 그러나 get-move는 항상 같은 값을 반환합니다. @move가 변경되는 것을 결코 보지 못합니다. 나는 Clojure에서 동시성과 상태에 관한 근본적인 것을 오해하고있는 것처럼 느낀다. 내가 뭘 잘못하고 있고, 이것을 처리하는 더 기능적인 방법이 있습니까?

감사합니다.

편집 : 원자를 사용하는 경우에도 동일한 문제가 발생합니다.

답변

1

동시성 문제가 아닙니다. .getKeyChar는 문자열과 비교하는 char을 반환합니다. 조건을 (= (str c) "j"로) 다시 쓰면 작동합니다.

+3

char와 비교할 때 다음과 같이 간단하게 쓸 수 있습니다 :'(= c \ j)' – Scott

+0

\ char을 나타 냅니까? 잘 알면서도, 나는 아직 그것을 보지 못했습니다. – Joel

관련 문제