2016-03-23 15 views
1

私はゲーム開発にclojureでlwjglを使用しようとしています。Clojure REPLからlwjglでOpenGLウィンドウを作成する

私の最初のステップは、REPLからOpenGLスクリーンに何かを表示しようとしています。十分迅速に行うならば、これは、動作することを

(import org.lwjgl.opengl GL11 Display DisplayMode 
(Display/setDisplayMode (DisplayMode. 800 600)) 
(Display/create) ; This shows a black 800x600 window as expected 
(GL11/glClearColor 1.0 0.0 0.0 1.0) 
(GL11/glClear (bit-or GL11/GL_COLOR_BUFFER_BIT GL11/GL_DEPTH_BUFFER_BIT)) 
(Display/update) 

注:このREPLレインでREPLを起動した後、私はこれまでやっていることです。しかし、しばらくすると(私が待っていても)現在のスレッドにバインドされていない現在のOpenGLコンテキストに関するエラーが出ます。私は/表示呼んでREPLがランダムに非アクティブのいくつかの時間後に別のスレッドを生み出したかのように、すべてが見えます

(Display/destroy) 
IllegalStateException From thread Thread[nREPL-worker-4,5,main]: Thread[nREPL-worker-0,5,] already has the context current org.lwjgl.opengl.ContextGL.checkAccess (ContextGL.java:184) 

を破壊しようとすると、

(Display/update) 
IllegalStateException No context is current org.lwjgl.opengl.LinuxContextImplementation.swapBuffers (LinuxContextImplementation.java:72) 

(GL11/glClear ...) 
RuntimeException No OpenGL context found in the current thread. org.lwjgl.opengl.GLContext.getCapabilities (GLContext.java:124) 

しかし、おそらくエラーの最も魅力的な

が起こります。私が読むことができたので、LWJGLは最初に作成されたスレッドからのOpenGL呼び出しのみを可能にします。そのため、これらのエラーが発生している可能性があります。

しかし、どのようにREPLがスレッドをランダムに切り替えることができますか?特に何もしていないのならば、待ってください。

答えて

2

既知の問題already reported against nREPL project(およびdiscussed on Clojure Google Group)です。 nREPLはアイドルスレッドを終了するスレッドプールを使用しているようです(恐らくkeepaliveの設定に従って)。

それが固定されるまで、あなたが(私は認める、少しぎこちない)このための回避策を使用することができます。

(import '(java.util.concurrent Executors)) 

(def opengl-executor (Executors/newSingleThreadExecutor)) 

(defmacro with-executor [executor & body] 
    `(.submit ~executor (fn [] [email protected]))) 

(on-executor opengl-executor 
    (println (.getId (Thread/currentThread)))) 

独自のexecutorを使用することでは、on-executorに包まれたすべてのコードは、そのスレッドで実行されます。 newSingleThreadExecutorは、docによると、現在の例外が例外のために失敗した場合にのみそれを置き換える単一のスレッドを作成します。遅延が長い最後の式を実行しようとすると、印刷されたスレッドIDは変わらないはずです。

アプリケーションを停止するときは、実行者shutdownを実行する必要があります。

関連する問題