2013-05-05 14 views
5

Yaygın bir zamanlayıcı çözümü olup olmadığını merak ediyorum.Zamanlayıcılar clojure'da mı?

Ben de işlemleri yoluyla "global" devlet kene her 20 ms'te kullanıcıların giriş işlemek istiyorum basit bir oyun motoru yazmak (veya 20ms (veya başka bir süre sonra kez bazı eylemleri gerçekleştirmek)) ve temelde güncellemek istiyorum ve Ben futures kullanmayı planlıyorum, bu çözüm eşzamanlılık uyarılarıyla uğraşabilmelidir.

Bana bir tavsiyede bulunabilir miyim?

cevap

11

.

ilk zamanlayıcılar ait konulardır. Burada bir çok seçenek var:

  • eylemler arasında uyur bir iplik, (future (loop [] (do-something) (Thread/sleep 20) (when (game-still-running) (recur))))
  • Kullanım Java gibi bir şey başlatın TimerTask - Clojure
  • Kullanım içeren benim küçük yardımcı programı Task gibi bir kütüphane gelen aramaya kolay yinelenen görevler
  • için bir DSL
  • kullanın gelen zamanlayıcı işlevi ne olursa olsun oyun motoru kullandığınız - bunların en bir oyun döngü
oluşturma konusunda bazı araçlar sağlamak

Muhtemelen sadece basit iplik seçeneği kullanmak istiyorum - bu eğer gerekiyorsa daha sonra daha fazla özellik kesmek oldukça kurmak kolay ve kolaydır.

ikinci konu taşıma oyun durumu olduğunu. Bu aslında yanıltıcıdır sorundur ve size yapıyoruz oyunun belirli türdeki etrafında dizayn etmesi gerekir, bu yüzden sadece birkaç tavsiye noktalarını vereceğiz: En oyun durumu değişmez ise

  • , o zaman bir çok avantaj elde edersiniz: Oyun güncellemesi bir sonraki oyun durumunu hesaplarken render kodunuz mevcut oyun durumunu bağımsız olarak çizebilir. Kesilebilirlik bazı performans maliyetlerine sahiptir, ancak çalışabilmeniz için eşzamanlılık avantajları çok büyüktür. Her iki mini Clojure oyunum (Ironclad ve Alchemy) bu yaklaşımı kullanır
  • Muhtemelen oyun durumunuzu bir tek üst düzey var'da denemelisiniz. Bu çalışmayı, oyunun farklı bölümlerini farklı varslara bölmekten daha iyi buluyorum. Ayrıca, ref bazlı işlemlere gerçekten ihtiyacınız olmadığı anlamına gelir: Bir atom veya aracı genellikle hile yapar.
  • Sen oyun durumu güncelleme işlevi tarafından sırayla işleme almak için gereken olayların bir kuyruğunu uygulamak isteyebilirsiniz. Birden fazla eş zamanlı etkinlik kaynağınız varsa (örneğin, oyuncu eylemleri, zamanlayıcı işaretler, ağ etkinlikleri vb.) Bu özellikle önemlidir.o kanalları
  • kullanarak iletişim faaliyetleri ayrılabilir karmaşık görevler söz konusu olduğunda)
+0

Teşekkürler, oyunların çok zor olduğunu kabul ediyorum, clojure özelliklerini kullanarak mimarlık planlama yolum sadece başlıyor :) – asdf

4

Bu çözüm JVM üzerinde Clojure yazıyoruz varsayar. Böyle şey işe yarayabilir: Aslında burada iki ayrı sorunları var

(import '(java.util TimerTask Timer)) 

(let [task (proxy [TimerTask] [] 
      (run [] (println "Here we go!")))] 
    (. (new Timer) (schedule task (long 20)))) 
+0

Ayrıca ilgili ve ilginç http://pragprog.com/magazines/2011-07/create-unix-services-with-clojure –

+0

Teşekkürler, sonunda 'tick' mesajım görünmeye başladı :) – asdf

+4

@dig, JVM'de "ScheduledExecutorService" öğesini kullanmayı düşünün: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html. Zamanlayıcı, yürütme hizmetinin sahip olmadığı bazı dezavantajlara sahiptir. –

4

Bugünlerde çok iyi ölçekler

  • beri iyi bir seçim olduğunu çekirdek/asenk dikkate alacağını bir iplik burada

bağlayıcı aktivitesi kaçınır kroki

(require '[clojure.core.async :refer [go-loop]]) 
(go-loop [] 
    (do 
    (do-something ...) 
    (Thread/sleep 1000) 
    (recur)))) 
olduğunu
+2

'(

İlgili konular