OSDN Git Service

getLogLevel() in Application interface
[mikumikustudio/libgdx-mikumikustudio.git] / backends / gdx-backend-lwjgl / src / com / badlogic / gdx / backends / lwjgl / LwjglAWTCanvas.java
1 /*******************************************************************************
2  * Copyright 2011 See AUTHORS file.
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * 
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  * 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  ******************************************************************************/
16
17 package com.badlogic.gdx.backends.lwjgl;
18
19 import java.awt.Canvas;
20 import java.awt.Cursor;
21 import java.awt.Dimension;
22 import java.awt.GraphicsEnvironment;
23 import java.util.ArrayList;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
27
28 import org.lwjgl.LWJGLException;
29 import org.lwjgl.opengl.AWTGLCanvas;
30 import org.lwjgl.opengl.PixelFormat;
31
32 import com.badlogic.gdx.Application;
33 import com.badlogic.gdx.ApplicationListener;
34 import com.badlogic.gdx.Audio;
35 import com.badlogic.gdx.Files;
36 import com.badlogic.gdx.Gdx;
37 import com.badlogic.gdx.Graphics;
38 import com.badlogic.gdx.Input;
39 import com.badlogic.gdx.LifecycleListener;
40 import com.badlogic.gdx.Net;
41 import com.badlogic.gdx.Preferences;
42 import com.badlogic.gdx.backends.openal.OpenALAudio;
43 import com.badlogic.gdx.utils.Array;
44 import com.badlogic.gdx.utils.Clipboard;
45 import com.badlogic.gdx.utils.GdxRuntimeException;
46
47 /** An OpenGL surface on an AWT Canvas, allowing OpenGL to be embedded in a Swing application. All OpenGL calls are done on the
48  * EDT. This is slightly less efficient then a dedicated thread, but greatly simplifies synchronization. Note that you may need to
49  * call {@link #stop()} or a Swing application may deadlock on System.exit due to how LWJGL and/or Swing deal with shutdown hooks.
50  * @author Nathan Sweet */
51 public class LwjglAWTCanvas implements Application {
52         final LwjglGraphics graphics;
53         final OpenALAudio audio;
54         final LwjglFiles files;
55         final LwjglAWTInput input;
56         final LwjglNet net;
57         final ApplicationListener listener;
58         final AWTGLCanvas canvas;
59         final List<Runnable> runnables = new ArrayList();
60         final List<Runnable> executedRunnables = new ArrayList();
61         final Array<LifecycleListener> lifecycleListeners = new Array<LifecycleListener>();
62         boolean running = true;
63         int lastWidth;
64         int lastHeight;
65         int logLevel = LOG_INFO;
66         private Cursor cursor;
67
68         public LwjglAWTCanvas (ApplicationListener listener, boolean useGL2) {
69                 this(listener, useGL2, null);
70         }
71
72         public LwjglAWTCanvas (ApplicationListener listener, boolean useGL2, LwjglAWTCanvas sharedContextCanvas) {
73                 LwjglNativesLoader.load();
74
75                 AWTGLCanvas sharedDrawable = sharedContextCanvas != null ? sharedContextCanvas.canvas : null;
76                 try {
77                         canvas = new AWTGLCanvas(GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(), new PixelFormat(),
78                                 sharedDrawable) {
79                                 private final Dimension minSize = new Dimension(0, 0);
80
81                                 public Dimension getMinimumSize () {
82                                         return minSize;
83                                 }
84
85                                 @Override
86                                 public void initGL () {
87                                         create();
88                                 }
89
90                                 @Override
91                                 public void paintGL () {
92                                         try {
93                                                 LwjglAWTCanvas.this.render();
94                                                 swapBuffers();
95                                                 repaint();
96                                         } catch (LWJGLException ex) {
97                                                 throw new GdxRuntimeException(ex);
98                                         }
99                                 }
100                         };
101                 } catch (LWJGLException ex) {
102                         throw new GdxRuntimeException(ex);
103                 }
104
105                 graphics = new LwjglGraphics(canvas, useGL2) {
106                         public void setTitle (String title) {
107                                 super.setTitle(title);
108                                 LwjglAWTCanvas.this.setTitle(title);
109                         }
110
111                         public boolean setDisplayMode (int width, int height, boolean fullscreen) {
112                                 if (!super.setDisplayMode(width, height, fullscreen)) return false;
113                                 if (!fullscreen) LwjglAWTCanvas.this.setDisplayMode(width, height);
114                                 return true;
115                         }
116
117                         public boolean setDisplayMode (DisplayMode displayMode) {
118                                 if (!super.setDisplayMode(displayMode)) return false;
119                                 LwjglAWTCanvas.this.setDisplayMode(displayMode.width, displayMode.height);
120                                 return true;
121                         }
122                 };
123                 if (!LwjglApplicationConfiguration.disableAudio && Gdx.audio == null) {
124                         audio = new OpenALAudio();
125                         Gdx.audio = audio;
126                 } else {
127                         audio = null;
128                 }
129                 if (Gdx.files == null) {
130                         files = new LwjglFiles();
131                         Gdx.files = files;
132                 } else {
133                         files = null;
134                 }
135                 if (Gdx.net == null) {
136                         net = new LwjglNet();
137                         Gdx.net = net;
138                 } else {
139                         net = null;
140                 }
141                 input = new LwjglAWTInput(canvas);
142                 this.listener = listener;
143
144                 setGlobals();
145         }
146
147         protected void setDisplayMode (int width, int height) {
148         }
149
150         protected void setTitle (String title) {
151         }
152
153         @Override
154         public ApplicationListener getApplicationListener () {
155                 return listener;
156         }
157
158         public Canvas getCanvas () {
159                 return canvas;
160         }
161
162         @Override
163         public Audio getAudio () {
164                 return Gdx.audio;
165         }
166
167         @Override
168         public Files getFiles () {
169                 return files;
170         }
171
172         @Override
173         public Graphics getGraphics () {
174                 return graphics;
175         }
176
177         @Override
178         public Input getInput () {
179                 return input;
180         }
181
182         @Override
183         public Net getNet () {
184                 return net;
185         }
186
187         @Override
188         public ApplicationType getType () {
189                 return ApplicationType.Desktop;
190         }
191
192         @Override
193         public int getVersion () {
194                 return 0;
195         }
196
197         void setGlobals () {
198                 Gdx.app = this;
199                 if (audio != null) Gdx.audio = audio;
200                 if (files != null) Gdx.files = files;
201                 if (net != null) Gdx.net = net;
202                 Gdx.graphics = graphics;
203                 Gdx.input = input;
204         }
205
206         void create () {
207                 try {
208                         setGlobals();
209                         graphics.initiateGLInstances();
210                         listener.create();
211                         lastWidth = Math.max(1, graphics.getWidth());
212                         lastHeight = Math.max(1, graphics.getHeight());
213                         listener.resize(lastWidth, lastHeight);
214                         start();
215                 } catch (Exception ex) {
216                         stopped();
217                         throw new GdxRuntimeException(ex);
218                 }
219         }
220
221         void render () {
222                 if (!running) return;
223                 
224                 setGlobals();
225                 canvas.setCursor(cursor);
226                 graphics.updateTime();
227
228                 int width = Math.max(1, graphics.getWidth());
229                 int height = Math.max(1, graphics.getHeight());
230                 if (lastWidth != width || lastHeight != height) {
231                         lastWidth = width;
232                         lastHeight = height;
233                         Gdx.gl.glViewport(0, 0, lastWidth, lastHeight);
234                         resize(width, height);
235                         listener.resize(width, height);
236                 }
237
238                 synchronized (runnables) {
239                         executedRunnables.clear();
240                         executedRunnables.addAll(runnables);
241                         runnables.clear();
242
243                         for (int i = 0; i < executedRunnables.size(); i++) {
244                                 try {
245                                         executedRunnables.get(i).run();
246                                 } catch (Throwable t) {
247                                         t.printStackTrace();
248                                 }
249                         }
250                 }
251
252                 input.processEvents();
253                 if (running) {
254                         listener.render();
255                         if (audio != null) {
256                                 audio.update();
257                         }
258                 }
259         }
260
261         /** Called after {@link ApplicationListener} create and resize, but before the game loop iteration. */
262         protected void start () {
263         }
264
265         /** Called when the canvas size changes. */
266         protected void resize (int width, int height) {
267         }
268
269         /** Called when the game loop has stopped. */
270         protected void stopped () {
271         }
272
273         public void stop () {
274                 if (!running) return;
275                 running = false;
276                 setGlobals();
277                 Array<LifecycleListener> listeners = lifecycleListeners;
278                 synchronized (listeners) {
279                         for (LifecycleListener listener : listeners) {
280                                 listener.pause();
281                                 listener.dispose();
282                         }
283                 }
284                 listener.pause();
285                 listener.dispose();
286
287                 Gdx.app = null;
288                 
289                 Gdx.graphics = null;
290                 
291                 if (audio != null) {
292                         audio.dispose();
293                         Gdx.audio = null;
294                 }
295
296                 if (files != null) Gdx.files = null;
297
298                 if (net != null) Gdx.net = null;
299                 
300                 stopped();
301         }
302
303         @Override
304         public long getJavaHeap () {
305                 return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
306         }
307
308         @Override
309         public long getNativeHeap () {
310                 return getJavaHeap();
311         }
312
313         Map<String, Preferences> preferences = new HashMap<String, Preferences>();
314
315         @Override
316         public Preferences getPreferences (String name) {
317                 if (preferences.containsKey(name)) {
318                         return preferences.get(name);
319                 } else {
320                         Preferences prefs = new LwjglPreferences(name);
321                         preferences.put(name, prefs);
322                         return prefs;
323                 }
324         }
325
326         @Override
327         public Clipboard getClipboard () {
328                 return new LwjglClipboard();
329         }
330
331         @Override
332         public void postRunnable (Runnable runnable) {
333                 synchronized (runnables) {
334                         runnables.add(runnable);
335                 }
336         }
337
338         @Override
339         public void debug (String tag, String message) {
340                 if (logLevel >= LOG_DEBUG) {
341                         System.out.println(tag + ": " + message);
342                 }
343         }
344
345         @Override
346         public void debug (String tag, String message, Throwable exception) {
347                 if (logLevel >= LOG_DEBUG) {
348                         System.out.println(tag + ": " + message);
349                         exception.printStackTrace(System.out);
350                 }
351         }
352
353         public void log (String tag, String message) {
354                 if (logLevel >= LOG_INFO) {
355                         System.out.println(tag + ": " + message);
356                 }
357         }
358
359         @Override
360         public void log (String tag, String message, Exception exception) {
361                 if (logLevel >= LOG_INFO) {
362                         System.out.println(tag + ": " + message);
363                         exception.printStackTrace(System.out);
364                 }
365         }
366
367         @Override
368         public void error (String tag, String message) {
369                 if (logLevel >= LOG_ERROR) {
370                         System.err.println(tag + ": " + message);
371                 }
372         }
373
374         @Override
375         public void error (String tag, String message, Throwable exception) {
376                 if (logLevel >= LOG_ERROR) {
377                         System.err.println(tag + ": " + message);
378                         exception.printStackTrace(System.err);
379                 }
380         }
381
382         @Override
383         public void setLogLevel (int logLevel) {
384                 this.logLevel = logLevel;
385         }
386
387         @Override
388         public int getLogLevel() {
389                 return logLevel;
390         }
391
392         @Override
393         public void exit () {
394                 postRunnable(new Runnable() {
395                         @Override
396                         public void run () {
397                                 stop();
398                                 System.exit(-1);
399                         }
400                 });
401         }
402
403         /** Make the canvas' context current. It is highly recommended that the context is only made current inside the AWT thread (for
404          * example in an overridden paintGL()). */
405         public void makeCurrent () {
406                 try {
407                         canvas.makeCurrent();
408                         setGlobals();
409                 } catch (LWJGLException ex) {
410                         throw new GdxRuntimeException(ex);
411                 }
412         }
413
414         /** Test whether the canvas' context is current. */
415         public boolean isCurrent () {
416                 try {
417                         return canvas.isCurrent();
418                 } catch (LWJGLException ex) {
419                         throw new GdxRuntimeException(ex);
420                 }
421         }
422
423         /** @param cursor May be null. */
424         public void setCursor (Cursor cursor) {
425                 this.cursor = cursor;
426         }
427
428         @Override
429         public void addLifecycleListener (LifecycleListener listener) {
430                 synchronized (lifecycleListeners) {
431                         lifecycleListeners.add(listener);
432                 }
433         }
434
435         @Override
436         public void removeLifecycleListener (LifecycleListener listener) {
437                 synchronized (lifecycleListeners) {
438                         lifecycleListeners.removeValue(listener, true);
439                 }
440         }
441 }