#concurrency #clojure
#параллелизм #clojure
Вопрос:
Я работаю над игрой в Clojure, используя Swing. У меня есть KeyListener для управления элементами управления, но он не обновляет ссылку.
(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))))
Теперь идея заключается в том, что основная функция, которая обновляет графический интерфейс, вызывает get-move . Он проверяет, действительна ли ссылка на перемещение в игре, и если да, возвращает ее. Прослушиватель подключен к JPanel и изменяет ссылку на основе нажатия клавиши. Прослушиватель работает нормально — всякий раз, когда нажимается кнопка, он выводит символ ключа. Я могу только предположить, что это изменение ссылки. Однако get-move всегда возвращает одно и то же значение — он никогда не видит изменения @move. Я чувствую, что я неправильно понимаю что-то фундаментальное о параллелизме и состоянии в Clojure. Что я делаю не так, и есть ли более функциональный способ справиться с этим?
Спасибо!
РЕДАКТИРОВАТЬ: Та же проблема возникает, если я использую atoms.
Ответ №1:
Это не проблема параллелизма. .getkeycharвозвращает символ, который я сравнивал со строкой. Переписывание условий в (= (str c) «j») заставляет это работать.
Комментарии:
1. Итак, если вы сравниваете с символом, вы могли бы просто написать:
(= c j)
2. указывает на символ? Приятно знать, я с этим еще не сталкивался.