OSDN Git Service

c759c663afe1f7d6305d344f9e06b77fd62a2b07
[mikumikustudio/MikuMikuStudio.git] / engine / src / desktop / com / jme3 / system / JmeSystem.java
1 /*
2  * Copyright (c) 2009-2010 jMonkeyEngine
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  *   notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  *   notice, this list of conditions and the following disclaimer in the
14  *   documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17  *   may be used to endorse or promote products derived from this software
18  *   without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 package com.jme3.system;
33
34 import com.jme3.app.SettingsDialog;
35 import com.jme3.app.SettingsDialog.SelectionListener;
36 import com.jme3.asset.AssetManager;
37 import com.jme3.asset.AssetNotFoundException;
38 import com.jme3.asset.DesktopAssetManager;
39 import com.jme3.audio.AudioRenderer;
40 import java.io.IOException;
41 import java.io.InputStream;
42 import java.net.URL;
43 import java.util.concurrent.atomic.AtomicBoolean;
44 import java.util.concurrent.atomic.AtomicInteger;
45 import java.util.logging.Level;
46 import java.util.logging.Logger;
47 import javax.swing.SwingUtilities;
48
49 public class JmeSystem {
50
51     private static final Logger logger = Logger.getLogger(JmeSystem.class.getName());
52     private static boolean initialized = false;
53     private static boolean lowPermissions = false;
54
55     public static boolean trackDirectMemory() {
56         return false;
57     }
58
59     public static void setLowPermissions(boolean lowPerm) {
60         lowPermissions = lowPerm;
61     }
62
63     public static boolean isLowPermissions() {
64         return lowPermissions;
65     }
66
67     public static AssetManager newAssetManager(URL configFile) {
68         return new DesktopAssetManager(configFile);
69     }
70
71     public static AssetManager newAssetManager() {
72         return new DesktopAssetManager(null);
73     }
74
75     public static boolean showSettingsDialog(AppSettings sourceSettings, final boolean loadFromRegistry) {
76         if (SwingUtilities.isEventDispatchThread()) {
77             throw new IllegalStateException("Cannot run from EDT");
78         }
79
80
81         final AppSettings settings = new AppSettings(false);
82         settings.copyFrom(sourceSettings);
83         String iconPath = sourceSettings.getSettingsDialogImage();
84         final URL iconUrl = JmeSystem.class.getResource(iconPath.startsWith("/") ? iconPath : "/" + iconPath);
85         if (iconUrl == null) {
86             throw new AssetNotFoundException(sourceSettings.getSettingsDialogImage());
87         }
88
89         final AtomicBoolean done = new AtomicBoolean();
90         final AtomicInteger result = new AtomicInteger();
91         final Object lock = new Object();
92
93         final SelectionListener selectionListener = new SelectionListener() {
94
95             public void onSelection(int selection) {
96                 synchronized (lock) {
97                     done.set(true);
98                     result.set(selection);
99                     lock.notifyAll();
100                 }
101             }
102         };
103         SwingUtilities.invokeLater(new Runnable() {
104
105             public void run() {
106                 synchronized (lock) {
107                     SettingsDialog dialog = new SettingsDialog(settings, iconUrl, loadFromRegistry);
108                     dialog.setSelectionListener(selectionListener);
109                     dialog.showDialog();
110                 }
111             }
112         });
113
114         synchronized (lock) {
115             while (!done.get()) {
116                 try {
117                     lock.wait();
118                 } catch (InterruptedException ex) {
119                 }
120             }
121         }
122
123         sourceSettings.copyFrom(settings);
124
125         return result.get() == SettingsDialog.APPROVE_SELECTION;
126     }
127
128     private static boolean is64Bit(String arch) {
129         if (arch.equals("x86")) {
130             return false;
131         } else if (arch.equals("amd64")) {
132             return true;
133         } else if (arch.equals("x86_64")) {
134             return true;
135         } else if (arch.equals("ppc") || arch.equals("PowerPC")) {
136             return false;
137         } else if (arch.equals("ppc64")) {
138             return true;
139         } else if (arch.equals("i386") || arch.equals("i686")) {
140             return false;
141         } else if (arch.equals("universal")) {
142             return false;
143         } else {
144             throw new UnsupportedOperationException("Unsupported architecture: " + arch);
145         }
146     }
147
148     public static Platform getPlatform() {
149         String os = System.getProperty("os.name").toLowerCase();
150         String arch = System.getProperty("os.arch").toLowerCase();
151         logger.log(Level.INFO,"os = "+os+" arch = "+arch);
152         boolean is64 = is64Bit(arch);
153         if (os.contains("windows")) {
154             return is64 ? Platform.Windows64 : Platform.Windows32;
155         } else if (os.contains("linux") || os.contains("freebsd")) {
156             return is64 ? Platform.Linux64 : Platform.Linux32;
157         } else if (os.contains("mac os x") || os.contains("darwin")) {
158             if (arch.startsWith("ppc")) {
159                 return is64 ? Platform.MacOSX_PPC64 : Platform.MacOSX_PPC32;
160             } else {
161                 return is64 ? Platform.MacOSX64 : Platform.MacOSX32;
162             }
163         } else if (os.contains("sunos")) {
164             return is64 ? Platform.SolarisAMD64 : Platform.SolarisX86;
165         } else {
166             throw new UnsupportedOperationException("The specified platform: " + os + " is not supported.");
167         }
168     }
169
170     private static JmeContext newContextLwjgl(AppSettings settings, JmeContext.Type type) {
171         try {
172             Class<? extends JmeContext> ctxClazz = null;
173             switch (type) {
174                 case Canvas:
175                     ctxClazz = (Class<? extends JmeContext>) Class.forName("com.jme3.system.lwjgl.LwjglCanvas");
176                     break;
177                 case Display:
178                     ctxClazz = (Class<? extends JmeContext>) Class.forName("com.jme3.system.lwjgl.LwjglDisplay");
179                     break;
180                 case OffscreenSurface:
181                     ctxClazz = (Class<? extends JmeContext>) Class.forName("com.jme3.system.lwjgl.LwjglOffscreenBuffer");
182                     break;
183                 default:
184                     throw new IllegalArgumentException("Unsupported context type " + type);
185             }
186
187             return ctxClazz.newInstance();
188         } catch (InstantiationException ex) {
189             logger.log(Level.SEVERE, "Failed to create context", ex);
190         } catch (IllegalAccessException ex) {
191             logger.log(Level.SEVERE, "Failed to create context", ex);
192         } catch (ClassNotFoundException ex) {
193             logger.log(Level.SEVERE, "CRITICAL ERROR: Context class is missing!\n"
194                     + "Make sure jme3_lwjgl-ogl is on the classpath.", ex);
195         }
196
197         return null;
198     }
199
200     private static JmeContext newContextJogl(AppSettings settings, JmeContext.Type type) {
201         try {
202             Class<? extends JmeContext> ctxClazz = null;
203             switch (type) {
204                 case Display:
205                     ctxClazz = (Class<? extends JmeContext>) Class.forName("com.jme3.system.jogl.JoglDisplay");
206                     break;
207                 case Canvas:
208                     ctxClazz = (Class<? extends JmeContext>) Class.forName("com.jme3.system.jogl.JoglCanvas");
209                     break;
210                 default:
211                     throw new IllegalArgumentException("Unsupported context type " + type);
212             }
213
214             return ctxClazz.newInstance();
215         } catch (InstantiationException ex) {
216             logger.log(Level.SEVERE, "Failed to create context", ex);
217         } catch (IllegalAccessException ex) {
218             logger.log(Level.SEVERE, "Failed to create context", ex);
219         } catch (ClassNotFoundException ex) {
220             logger.log(Level.SEVERE, "CRITICAL ERROR: Context class is missing!\n"
221                     + "Make sure jme3_jogl is on the classpath.", ex);
222         }
223
224         return null;
225     }
226
227     private static JmeContext newContextCustom(AppSettings settings, JmeContext.Type type) {
228         try {
229             String className = settings.getRenderer().substring("CUSTOM".length());
230
231             Class<? extends JmeContext> ctxClazz = null;
232             ctxClazz = (Class<? extends JmeContext>) Class.forName(className);
233             return ctxClazz.newInstance();
234         } catch (InstantiationException ex) {
235             logger.log(Level.SEVERE, "Failed to create context", ex);
236         } catch (IllegalAccessException ex) {
237             logger.log(Level.SEVERE, "Failed to create context", ex);
238         } catch (ClassNotFoundException ex) {
239             logger.log(Level.SEVERE, "CRITICAL ERROR: Context class is missing!", ex);
240         }
241
242         return null;
243     }
244
245     public static JmeContext newContext(AppSettings settings, JmeContext.Type contextType) {
246         initialize(settings);
247         JmeContext ctx;
248         if (settings.getRenderer() == null
249                 || settings.getRenderer().equals("NULL")
250                 || contextType == JmeContext.Type.Headless) {
251             ctx = new NullContext();
252             ctx.setSettings(settings);
253         } else if (settings.getRenderer().startsWith("LWJGL")) {
254             ctx = newContextLwjgl(settings, contextType);
255             ctx.setSettings(settings);
256         } else if (settings.getRenderer().startsWith("JOGL")) {
257             ctx = newContextJogl(settings, contextType);
258             ctx.setSettings(settings);
259         } else if (settings.getRenderer().startsWith("CUSTOM")) {
260             ctx = newContextCustom(settings, contextType);
261             ctx.setSettings(settings);
262         } else {
263             throw new UnsupportedOperationException(
264                     "Unrecognizable renderer specified: "
265                     + settings.getRenderer());
266         }
267         return ctx;
268     }
269
270     public static AudioRenderer newAudioRenderer(AppSettings settings) {
271         initialize(settings);
272         Class<? extends AudioRenderer> clazz = null;
273         try {
274             if (settings.getAudioRenderer().startsWith("LWJGL")) {
275                 clazz = (Class<? extends AudioRenderer>) Class.forName("com.jme3.audio.lwjgl.LwjglAudioRenderer");
276             } else if (settings.getAudioRenderer().startsWith("JOAL")) {
277                 clazz = (Class<? extends AudioRenderer>) Class.forName("com.jme3.audio.joal.JoalAudioRenderer");
278             } else {
279                 throw new UnsupportedOperationException(
280                         "Unrecognizable audio renderer specified: "
281                         + settings.getAudioRenderer());
282             }
283
284             AudioRenderer ar = clazz.newInstance();
285             return ar;
286         } catch (InstantiationException ex) {
287             logger.log(Level.SEVERE, "Failed to create context", ex);
288         } catch (IllegalAccessException ex) {
289             logger.log(Level.SEVERE, "Failed to create context", ex);
290         } catch (ClassNotFoundException ex) {
291             logger.log(Level.SEVERE, "CRITICAL ERROR: Audio implementation class is missing!\n"
292                     + "Make sure jme3_lwjgl-oal or jm3_joal is on the classpath.", ex);
293         }
294         return null;
295     }
296
297     public static void initialize(AppSettings settings) {
298         if (initialized) {
299             return;
300         }
301
302         initialized = true;
303         try {
304             if (!lowPermissions) {
305                 // can only modify logging settings
306                 // if permissions are available
307 //                JmeFormatter formatter = new JmeFormatter();
308 //                Handler fileHandler = new FileHandler("jme.log");
309 //                fileHandler.setFormatter(formatter);
310 //                Logger.getLogger("").addHandler(fileHandler);
311 //                Handler consoleHandler = new ConsoleHandler();
312 //                consoleHandler.setFormatter(formatter);
313 //                Logger.getLogger("").removeHandler(Logger.getLogger("").getHandlers()[0]);
314 //                Logger.getLogger("").addHandler(consoleHandler);
315             }
316 //        } catch (IOException ex){
317 //            logger.log(Level.SEVERE, "I/O Error while creating log file", ex);
318         } catch (SecurityException ex) {
319             logger.log(Level.SEVERE, "Security error in creating log file", ex);
320         }
321         logger.log(Level.INFO, "Running on {0} chototsu", getFullName());
322
323
324         if (!lowPermissions) {
325             try {
326                 Natives.extractNativeLibs(getPlatform(), settings);
327             } catch (IOException ex) {
328                 logger.log(Level.SEVERE, "Error while copying native libraries", ex);
329             }
330         }
331     }
332
333     public static String getFullName() {
334         return "jMonkeyEngine 3.0.0 Beta";
335     }
336
337     public static InputStream getResourceAsStream(String name) {
338         return JmeSystem.class.getResourceAsStream(name);
339     }
340
341     public static URL getResource(String name) {
342         return JmeSystem.class.getResource(name);
343     }
344 }