2012-10-14 7 views
5

Napisałem dość prymitywny program testowy (piszę o klasach OpenGL LWJGL z powodów głównie estetycznych i postanowiłem wprowadzić tam wielowątkowość, ponieważ nigdy wcześniej nie napisałem programu współbieżnego). Po zakończeniu programu, zawsze otrzymuję ostrzeżenie: I rzeczywiście pojawia się ostrzeżenie, zanim program przejdzie do funkcji głównej. Przepraszamy za błąd (myślę, że to nie może być mój program w ogóle, ale raczej coś w samej Clojure):Nie można rozwiązać połączenia do invokeStaticMethod?

Reflection warning, NO_SOURCE_PATH:1 - call to invokeStaticMethod can't be resolved. 

nie dostanę ostrzeżenia podczas kompilacji choć, co uważam raczej dziwne. W każdym razie, tu jest program:

(ns opengltuts.core 
    (:import (org.lwjgl.opengl GL11 Display)) 
    (:use opengltuts.opengl)) ;my wrapper 

(def world-state (ref {:running true :color [1.0 0.0 0.0 1.0]})) 

(defn render-world [state] 
    (apply glClearColor (:color state)) 
    (glClear GL11/GL_COLOR_BUFFER_BIT) 
    (Display/update)) 

(defn render [] 
    (Display/create) 
    (loop [] 
    (let [world @world-state] 
     (when (:running world) 
     (do (render-world world) 
      (recur))))) 
    (Display/destroy)) 

(defn -main [] 
    ; without the annotation, I get a warning here too. 
    (let [render-thread (doto (Thread. ^Runnable render) (.start))] 
    (Thread/sleep 3000) 
    (dosync (commute world-state assoc :color [0.0 1.0 0.0 1.0])) 
    (Thread/sleep 3000) 
    (dosync (commute world-state assoc :running false)) 
    (.join render-thread))) 

To chyba nie jest zbyt idiomatyczne (słyszałem, że w Clojure zwykle nie zaczynaj wątki z new Thread, ale raczej z agentami czy coś, ale nie w pełni uchwycić, jak to działa), ale myślę, że dla tak krótkiego programu, który nie ma znaczenia.

+1

Jeśli potrzebujesz prostego wątku, możesz użyć 'future' zamiast agenta. tj. '(przyszłość (render))'. Również "Thread/sleep" jest ok, zobacz http://clojuredocs.org/clojure_core/clojure.core/future – noahlz

+0

Czy jesteś pewien, że ostrzeżenie nie pochodzi z 'opengltuts.opengl'? Gdzieś wywołuje się przeciążoną statyczną metodę i nie może ona rozwiązać dokładnego wywołania. Co się dzieje w środowisku wykonawczym, czy generujesz kod w czasie wykonywania? – noahlz

+0

@noahz Nie Nie generuję kodu. A dzieje się tak tylko na końcu programu, kiedy już dawno mam do czynienia z funkcjami OpenGL. Również wykorzystanie przyszłości jest dziwne. Oszczędza mi to trochę kropek, ale teraz potrzebuję tego dziwnego wezwania (shutdown-agentów) na końcu, ponieważ clojure nie może się domyślić, kiedy już czas skończyć. No i oczywiście dereferencja wartości zerowej powodującej efekt uboczny również nie jest odpowiednia dla mnie. Myliłem się z czasem - otrzymuję ostrzeżenie, zanim przejdę do głównej funkcji. – Cubic

Odpowiedz

0

Twój kod źródłowy Clojure jest ładowany i kompilowany w czasie wykonywania (patrz http://clojure.org/compilation), dlatego nie widzisz ostrzeżenia o odbiciu przed wykonaniem programu.

Trudno jest określić, gdzie robisz odblaskowe rozmowy przeciwko metodzie statycznej, więc tutaj są kroki Polecam:

  1. Dodaj (:gen-class) do deklaracji
  2. (ns) Dodaj (set! *warn-on-reflection* true) lub (binding [*warn-on-reflection* true] body) gdzie podejrzewasz, że występuje wywołanie odblaskowe.
+0

Kompiluję z ustawieniem projektu leiningen: warn-on-reflection. Otrzymuję ostrzeżenia o odbiciu dla wszystkich moich modułów i żadne z nich nie powoduje ich podczas kompilacji. – Cubic

+0

Po uruchomieniu 'lein compile' co widzisz pod' target/classes/'? – noahlz

+0

opengltuts-> kilka klas z nazwami ns $ function.class. Podobnie jak 'core__init.class' ' core $ loading__4784__auto__.klasa ' ' core $ _main $ fn__155.class' 'core $ _main $ fn__157.class' – Cubic

Powiązane problemy