OSDN Git Service

getLogLevel() in Application interface
[mikumikustudio/libgdx-mikumikustudio.git] / backends / gdx-backends-gwt / src / com / badlogic / gdx / backends / gwt / GwtApplication.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.gwt;
18
19 import com.badlogic.gdx.Application;
20 import com.badlogic.gdx.ApplicationListener;
21 import com.badlogic.gdx.Audio;
22 import com.badlogic.gdx.Files;
23 import com.badlogic.gdx.Gdx;
24 import com.badlogic.gdx.Graphics;
25 import com.badlogic.gdx.Input;
26 import com.badlogic.gdx.LifecycleListener;
27 import com.badlogic.gdx.Net;
28 import com.badlogic.gdx.Preferences;
29 import com.badlogic.gdx.backends.gwt.preloader.Preloader;
30 import com.badlogic.gdx.backends.gwt.preloader.Preloader.PreloaderCallback;
31 import com.badlogic.gdx.backends.gwt.preloader.Preloader.PreloaderState;
32 import com.badlogic.gdx.backends.gwt.soundmanager2.SoundManager;
33 import com.badlogic.gdx.utils.Array;
34 import com.badlogic.gdx.utils.Clipboard;
35 import com.badlogic.gdx.utils.ObjectMap;
36 import com.badlogic.gdx.utils.TimeUtils;
37 import com.google.gwt.core.client.EntryPoint;
38 import com.google.gwt.core.client.GWT;
39 import com.google.gwt.core.client.JavaScriptObject;
40 import com.google.gwt.dom.client.Document;
41 import com.google.gwt.dom.client.Element;
42 import com.google.gwt.dom.client.Style;
43 import com.google.gwt.dom.client.Style.Unit;
44 import com.google.gwt.user.client.Timer;
45 import com.google.gwt.user.client.ui.FlowPanel;
46 import com.google.gwt.user.client.ui.HTMLPanel;
47 import com.google.gwt.user.client.ui.HasHorizontalAlignment;
48 import com.google.gwt.user.client.ui.HasVerticalAlignment;
49 import com.google.gwt.user.client.ui.Image;
50 import com.google.gwt.user.client.ui.InlineHTML;
51 import com.google.gwt.user.client.ui.Label;
52 import com.google.gwt.user.client.ui.Panel;
53 import com.google.gwt.user.client.ui.RootPanel;
54 import com.google.gwt.user.client.ui.SimplePanel;
55 import com.google.gwt.user.client.ui.TextArea;
56 import com.google.gwt.user.client.ui.VerticalPanel;
57
58 /** Implementation of an {@link Application} based on GWT. Clients have to override {@link #getConfig()} and
59  * {@link #getApplicationListener()}. Clients can override the default loading screen via
60  * {@link #getPreloaderCallback()} and implement any loading screen drawing via GWT widgets.
61  * @author mzechner */
62 public abstract class GwtApplication implements EntryPoint, Application {
63         private ApplicationListener listener;
64         private GwtApplicationConfiguration config;
65         private GwtGraphics graphics;
66         private GwtInput input;
67         private GwtNet net;
68         private Panel root = null;
69         private TextArea log = null;
70         private int logLevel = LOG_ERROR;
71         private Array<Runnable> runnables = new Array<Runnable>();
72         private Array<Runnable> runnablesHelper = new Array<Runnable>();
73         private Array<LifecycleListener> lifecycleListeners = new Array<LifecycleListener>();
74         private int lastWidth;
75         private int lastHeight;
76         Preloader preloader;
77         private static AgentInfo agentInfo;
78         private ObjectMap<String, Preferences> prefs = new ObjectMap<String, Preferences>();
79
80         /** @return the configuration for the {@link GwtApplication}. */
81         public abstract GwtApplicationConfiguration getConfig ();
82
83         
84         public String getPreloaderBaseURL()
85         {
86                 return GWT.getHostPageBaseURL() + "assets/";
87         }
88         
89         @Override
90         public void onModuleLoad () {
91                 GwtApplication.agentInfo = computeAgentInfo();
92                 this.listener = getApplicationListener();
93                 this.config = getConfig();
94                 this.log = config.log;
95
96                 if (config.rootPanel != null) {
97                         this.root = config.rootPanel;
98                 } else {
99                         Element element = Document.get().getElementById("embed-" + GWT.getModuleName());
100                         if (element == null) {
101                                 VerticalPanel panel = new VerticalPanel();
102                                 panel.setWidth("" + config.width + "px");
103                                 panel.setHeight("" + config.height + "px");
104                                 panel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
105                                 panel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
106                                 RootPanel.get().add(panel);
107                                 RootPanel.get().setWidth("" + config.width + "px");
108                                 RootPanel.get().setHeight("" + config.height + "px");
109                                 this.root = panel;
110                         } else {
111                                 VerticalPanel panel = new VerticalPanel();
112                                 panel.setWidth("" + config.width + "px");
113                                 panel.setHeight("" + config.height + "px");
114                                 panel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
115                                 panel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
116                                 element.appendChild(panel.getElement());
117                                 root = panel;
118                         }
119                 }
120
121                 // initialize SoundManager2
122                 SoundManager.init(GWT.getModuleBaseURL(), 9, true, new SoundManager.SoundManagerCallback(){
123
124                         @Override
125                         public void onready () {
126                                 final PreloaderCallback callback = getPreloaderCallback();
127                                 preloader = createPreloader();
128                                 preloader.preload("assets.txt", new PreloaderCallback() {
129                                         @Override
130                                         public void error (String file) {
131                                                 callback.error(file);
132                                         }
133
134                                         @Override
135                                         public void update (PreloaderState state) {
136                                                 callback.update(state);
137                                                 if (state.hasEnded()) {
138                                                         getRootPanel().clear();
139                                                         setupLoop();
140                                                 }
141                                         }
142                                 });
143                         }
144
145                         @Override
146                         public void ontimeout (String status, String errorType) {
147                                 error("SoundManager", status + " " + errorType);
148                         }
149                         
150                 });
151         }
152
153         void setupLoop () {
154                 // setup modules
155                 try {                   
156                         graphics = new GwtGraphics(root, config);                       
157                 } catch (Throwable e) {
158                         root.clear();
159                         root.add(new Label("Sorry, your browser doesn't seem to support WebGL"));
160                         return;
161                 }
162                 lastWidth = graphics.getWidth();
163                 lastHeight = graphics.getHeight();
164                 Gdx.app = this;
165                 Gdx.audio = new GwtAudio();
166                 Gdx.graphics = graphics;
167                 Gdx.gl20 = graphics.getGL20();
168                 Gdx.gl = graphics.getGLCommon();
169                 Gdx.files = new GwtFiles(preloader);
170                 this.input = new GwtInput(graphics.canvas);
171                 Gdx.input = this.input;
172                 this.net = new GwtNet();
173                 Gdx.net = this.net;
174
175                 // tell listener about app creation
176                 try {
177                         listener.create();
178                         listener.resize(graphics.getWidth(), graphics.getHeight());
179                 } catch (Throwable t) {
180                         error("GwtApplication", "exception: " + t.getMessage(), t);
181                         t.printStackTrace();
182                         throw new RuntimeException(t);
183                 }
184
185                 // setup rendering timer
186                 new Timer() {
187                         @Override
188                         public void run () {
189                                 try {
190                                         mainLoop();
191                                 } catch (Throwable t) {
192                                         error("GwtApplication", "exception: " + t.getMessage(), t);
193                                         throw new RuntimeException(t);
194                                 }
195                         }
196                 }.scheduleRepeating((int)((1f / config.fps) * 1000));
197         }
198
199         void mainLoop() {
200                 graphics.update();
201                 if (Gdx.graphics.getWidth() != lastWidth || Gdx.graphics.getHeight() != lastHeight) {
202                         GwtApplication.this.listener.resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
203                         lastWidth = graphics.getWidth();
204                         lastHeight = graphics.getHeight();
205                         Gdx.gl.glViewport(0, 0, lastWidth, lastHeight);
206                 }
207                 runnablesHelper.addAll(runnables);
208                 runnables.clear();
209                 for (int i = 0; i < runnablesHelper.size; i++) {
210                         runnablesHelper.get(i).run();
211                 }
212                 runnablesHelper.clear();                                        
213                 listener.render();
214                 input.justTouched = false;
215         }
216         
217         public Panel getRootPanel () {
218                 return root;
219         }
220
221         long loadStart = TimeUtils.nanoTime();
222
223         public Preloader createPreloader() {
224                 return new Preloader(getPreloaderBaseURL());
225         }
226
227         public PreloaderCallback getPreloaderCallback () {
228                 final Panel preloaderPanel = new VerticalPanel();
229                 preloaderPanel.setStyleName("gdx-preloader");
230                 final Image logo = new Image(GWT.getModuleBaseURL() + "logo.png");
231                 logo.setStyleName("logo");              
232                 preloaderPanel.add(logo);
233                 final Panel meterPanel = new SimplePanel();
234                 meterPanel.setStyleName("gdx-meter");
235                 meterPanel.addStyleName("red");
236                 final InlineHTML meter = new InlineHTML();
237                 final Style meterStyle = meter.getElement().getStyle();
238                 meterStyle.setWidth(0, Unit.PCT);
239                 meterPanel.add(meter);
240                 preloaderPanel.add(meterPanel);
241                 getRootPanel().add(preloaderPanel);
242                 return new PreloaderCallback() {
243
244                         @Override
245                         public void error (String file) {
246                                 System.out.println("error: " + file);
247                         }
248                         
249                         @Override
250                         public void update (PreloaderState state) {
251                                 meterStyle.setWidth(100f * state.getProgress(), Unit.PCT);
252                         }                       
253                         
254                 };
255         }
256
257         @Override
258         public Graphics getGraphics () {
259                 return graphics;
260         }
261
262         @Override
263         public Audio getAudio () {
264                 return Gdx.audio;
265         }
266
267         @Override
268         public Input getInput () {
269                 return Gdx.input;
270         }
271
272         @Override
273         public Files getFiles () {
274                 return Gdx.files;
275         }
276         
277         @Override
278         public Net getNet() {
279                 return Gdx.net;
280         }
281
282         private void checkLogLabel () {
283                 if (log == null) {
284                         log = new TextArea();
285                         log.setSize(graphics.getWidth() + "px", "200px");
286                         log.setReadOnly(true);
287                         root.add(log);
288                 }
289         }
290
291         @Override
292         public void log (String tag, String message) {
293                 if (logLevel >= LOG_INFO) {
294                         checkLogLabel();
295                         log.setText(log.getText() + "\n" + tag + ": " + message);
296                         log.setCursorPos(log.getText().length() - 1);
297                         System.out.println(tag + ": " + message);
298                 }
299         }
300
301         @Override
302         public void log (String tag, String message, Exception exception) {
303                 if (logLevel >= LOG_INFO) {
304                         checkLogLabel();
305                         log.setText(log.getText() + "\n" + tag + ": " + message + "\n" + exception.getMessage() + "\n");
306                         log.setCursorPos(log.getText().length() - 1);
307                         System.out.println(tag + ": " + message + "\n" + exception.getMessage());
308                         System.out.println(getStackTrace(exception));
309                 }
310         }
311
312         @Override
313         public void error (String tag, String message) {
314                 if (logLevel >= LOG_ERROR) {
315                         checkLogLabel();
316                         log.setText(log.getText() + "\n" + tag + ": " + message);
317                         log.setCursorPos(log.getText().length() - 1);
318                         System.err.println(tag + ": " + message);
319                 }
320         }
321
322         @Override
323         public void error (String tag, String message, Throwable exception) {
324                 if (logLevel >= LOG_ERROR) {
325                         checkLogLabel();
326                         log.setText(log.getText() + "\n" + tag + ": " + message + "\n" + exception.getMessage());
327                         log.setCursorPos(log.getText().length() - 1);
328                         System.err.println(tag + ": " + message + "\n" + exception.getMessage() + "\n");
329                         System.out.println(getStackTrace(exception));
330                 }
331         }
332
333         @Override
334         public void debug (String tag, String message) {
335                 if (logLevel >= LOG_DEBUG) {
336                         checkLogLabel();
337                         log.setText(log.getText() + "\n" + tag + ": " + message + "\n");
338                         log.setCursorPos(log.getText().length() - 1);
339                         System.out.println(tag + ": " + message + "\n");
340                 }
341         }
342
343         @Override
344         public void debug (String tag, String message, Throwable exception) {
345                 if (logLevel >= LOG_DEBUG) {
346                         checkLogLabel();
347                         log.setText(log.getText() + "\n" + tag + ": " + message + "\n" + exception.getMessage() + "\n");
348                         log.setCursorPos(log.getText().length() - 1);
349                         System.out.println(tag + ": " + message + "\n" + exception.getMessage());
350                         System.out.println(getStackTrace(exception));
351                 }
352         }
353
354         private String getStackTrace (Throwable e) {
355                 StringBuffer buffer = new StringBuffer();
356                 for (StackTraceElement trace : e.getStackTrace()) {
357                         buffer.append(trace.toString() + "\n");
358                 }
359                 return buffer.toString();
360         }
361
362         @Override
363         public void setLogLevel (int logLevel) {
364                 this.logLevel = logLevel;
365         }
366
367         @Override
368         public int getLogLevel() {
369                 return logLevel;
370         }
371
372         @Override
373         public ApplicationType getType () {
374                 return ApplicationType.WebGL;
375         }
376
377         @Override
378         public int getVersion () {
379                 return 0;
380         }
381
382         @Override
383         public long getJavaHeap () {
384                 return 0;
385         }
386
387         @Override
388         public long getNativeHeap () {
389                 return 0;
390         }
391
392         @Override
393         public Preferences getPreferences (String name) {
394                 Preferences pref = prefs.get(name);
395                 if (pref == null) {
396                         pref = new GwtPreferences(name);
397                         prefs.put(name, pref);
398                 }
399                 return pref;
400         }
401
402         @Override
403         public Clipboard getClipboard() {
404                 return new Clipboard() {
405                         @Override
406                         public String getContents () {
407                                 return null;
408                         }
409
410                         @Override
411                         public void setContents (String content) {
412                         }                       
413                 };              
414         }
415         
416         @Override
417         public void postRunnable (Runnable runnable) {
418                 runnables.add(runnable);
419         }
420
421         @Override
422         public void exit () {
423         }
424
425         /** Contains precomputed information on the user-agent. Useful for dealing with browser and OS behavioral differences. Kindly
426          * borrowed from PlayN */
427         public static AgentInfo agentInfo () {
428                 return agentInfo;
429         }
430
431         /** kindly borrowed from PlayN **/
432         private static native AgentInfo computeAgentInfo () /*-{
433                                                                                                                                                         var userAgent = navigator.userAgent.toLowerCase();
434                                                                                                                                                         return {
435                                                                                                                                                         // browser type flags
436                                                                                                                                                         isFirefox : userAgent.indexOf("firefox") != -1,
437                                                                                                                                                         isChrome : userAgent.indexOf("chrome") != -1,
438                                                                                                                                                         isSafari : userAgent.indexOf("safari") != -1,
439                                                                                                                                                         isOpera : userAgent.indexOf("opera") != -1,
440                                                                                                                                                         isIE : userAgent.indexOf("msie") != -1,
441                                                                                                                                                         // OS type flags
442                                                                                                                                                         isMacOS : userAgent.indexOf("mac") != -1,
443                                                                                                                                                         isLinux : userAgent.indexOf("linux") != -1,
444                                                                                                                                                         isWindows : userAgent.indexOf("win") != -1
445                                                                                                                                                         };
446                                                                                                                                                         }-*/;
447
448         /** Returned by {@link #agentInfo}. Kindly borrowed from PlayN. */
449         public static class AgentInfo extends JavaScriptObject {
450                 public final native boolean isFirefox () /*-{
451                                                                                                                                 return this.isFirefox;
452                                                                                                                                 }-*/;
453
454                 public final native boolean isChrome () /*-{
455                                                                                                                                 return this.isChrome;
456                                                                                                                                 }-*/;
457
458                 public final native boolean isSafari () /*-{
459                                                                                                                                 return this.isSafari;
460                                                                                                                                 }-*/;
461
462                 public final native boolean isOpera () /*-{
463                                                                                                                         return this.isOpera;
464                                                                                                                         }-*/;
465
466                 public final native boolean isIE () /*-{
467                                                                                                                 return this.isIE;
468                                                                                                                 }-*/;
469
470                 public final native boolean isMacOS () /*-{
471                                                                                                                         return this.isMacOS;
472                                                                                                                         }-*/;
473
474                 public final native boolean isLinux () /*-{
475                                                                                                                         return this.isLinux;
476                                                                                                                         }-*/;
477
478                 public final native boolean isWindows () /*-{
479                                                                                                                                 return this.isWindows;
480                                                                                                                                 }-*/;
481
482                 protected AgentInfo () {
483                 }
484         }
485
486         public String getBaseUrl () {
487                 return preloader.baseUrl;
488         }
489
490         public Preloader getPreloader () {
491                 return preloader;
492         }
493         
494         @Override
495         public void addLifecycleListener (LifecycleListener listener) {
496                 synchronized(lifecycleListeners) {
497                         lifecycleListeners.add(listener);
498                 }
499         }
500
501         @Override
502         public void removeLifecycleListener (LifecycleListener listener) {
503                 synchronized(lifecycleListeners) {
504                         lifecycleListeners.removeValue(listener, true);
505                 }               
506         }
507         
508         native static public void consoleLog(String message) /*-{
509                 console.log( "GWT: " + message );
510         }-*/;
511 }