2012年5月8日火曜日

最近楽しんでいるもの

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

最近いじって楽しんでいるものはcloftです。

push権限ももらっていい気になっています。

cloftはclojureでかかれたbukkit pluginで、bukkitとは、minecraftのサーバです。

まだまだよくわからないことの多いclojureですが、lisp-1で関数と「変数」(正しくない書き方だろう)の名前空間が一緒なのが胡のみですね。

またカッコを減らそうという努力が伺えるのが好感度高いです。(じゃあHaskellやれよ、という声もあるのかもしれませんが・・・・)

「clojure では、マップ型および、キーワード型は、callable」で、なるほど。よく考えてある。pythonとかでやらかう[]と()をタイポしてむかつくことがないのかというのもいいです。

#!Clojure
({:a 10 :b 20 :c 30} :b)
=> 20

いままでイラつきを引き起こしている言語のくだらん記法を減らす設計に向かっているということが大事。

わかっている人に言わせればrecurとかも実用的判断らしいですが、まだよくわかりません。

専門家と議論するより、小中学生の集団を相手に会話する方が語学的にははるかに難しい。

コンテキストとスコープが共有されないと大変。 またどの範囲で効いているのかが重要で、取り違えるとまっとうな意味をなさない。

人間のコミュニケーションも、言語も一緒だよね。コンテキストを作り出す コストが高い言語は何をしても大変だろう。

話はcloftでのコードに戻る。

先に断っておくと、minecraftをやったことがないと分かりにくいと思う。

multithreadをつかってbukkitとやりとりしたらなんかおかしいのでそれを止めた

具体的にはfuture-callを使ってblockを積んだらおかしくなったのだ。

仕方ないのでJavaScriptのtimerっぽいものを実装した

大筋では

  • 起動されてからtickごとに毎回処理するcloft-scheduler
  • 何回目のtickだったか覚えるcurrent-tick
  • callbackとその発火時刻を覚えておくschedule-table
  • 「ユーザ」がcallbackの登録と発火時刻の指定に使うsettimer
からできている。

最初tableが要素にもつvectorはmutableである必要がないことに気づかなくてハマった

vectorをconsするなという噂もあります。

(def cloft-schedule-table (atom {}))
(def cloft-schedule-currenct-tick (atom 0))
(defn cloft-schedule-settimer [after f]
  ;(prn cloft-schedule-settimer after f)
  ;(prn (count @cloft-schedule-table))
  (dosync
   (let [wake-up (+ @cloft-schedule-currenct-tick after)]
     (swap! cloft-schedule-table assoc wake-up
            (cons f (@cloft-schedule-table wake-up []))))))

(defn cloft-scheduler []
  (dosync
    (let [table @cloft-schedule-table
          now @cloft-schedule-currenct-tick
          r (table now false)]
      (when r
        ;(prn r table now)
        (doseq [f r] (f)))
      (swap! cloft-schedule-table dissoc @cloft-schedule-currenct-tick))
    (swap! cloft-schedule-currenct-tick inc)))

これをplugin起動時に登録する。サーバ側は1tickごとにcloft-schedulerを呼び出す。ちなみに1tickは50msです。

  (.scheduleSyncRepeatingTask (Bukkit/getScheduler) plugin (fn [] (cloft-scheduler)) 0 1)

0 件のコメント: