2 * Copyright (c) 2009-2010 jMonkeyEngine
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
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.
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.
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.
32 package com.jme3.system;
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;
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;
49 public class JmeSystem {
51 private static final Logger logger = Logger.getLogger(JmeSystem.class.getName());
52 private static boolean initialized = false;
53 private static boolean lowPermissions = false;
55 public static boolean trackDirectMemory() {
59 public static void setLowPermissions(boolean lowPerm) {
60 lowPermissions = lowPerm;
63 public static boolean isLowPermissions() {
64 return lowPermissions;
67 public static AssetManager newAssetManager(URL configFile) {
68 return new DesktopAssetManager(configFile);
71 public static AssetManager newAssetManager() {
72 return new DesktopAssetManager(null);
75 public static boolean showSettingsDialog(AppSettings sourceSettings, final boolean loadFromRegistry) {
76 if (SwingUtilities.isEventDispatchThread()) {
77 throw new IllegalStateException("Cannot run from EDT");
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());
89 final AtomicBoolean done = new AtomicBoolean();
90 final AtomicInteger result = new AtomicInteger();
91 final Object lock = new Object();
93 final SelectionListener selectionListener = new SelectionListener() {
95 public void onSelection(int selection) {
98 result.set(selection);
103 SwingUtilities.invokeLater(new Runnable() {
106 synchronized (lock) {
107 SettingsDialog dialog = new SettingsDialog(settings, iconUrl, loadFromRegistry);
108 dialog.setSelectionListener(selectionListener);
114 synchronized (lock) {
115 while (!done.get()) {
118 } catch (InterruptedException ex) {
123 sourceSettings.copyFrom(settings);
125 return result.get() == SettingsDialog.APPROVE_SELECTION;
128 private static boolean is64Bit(String arch) {
129 if (arch.equals("x86")) {
131 } else if (arch.equals("amd64")) {
133 } else if (arch.equals("x86_64")) {
135 } else if (arch.equals("ppc") || arch.equals("PowerPC")) {
137 } else if (arch.equals("ppc64")) {
139 } else if (arch.equals("i386") || arch.equals("i686")) {
141 } else if (arch.equals("universal")) {
144 throw new UnsupportedOperationException("Unsupported architecture: " + arch);
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;
161 return is64 ? Platform.MacOSX64 : Platform.MacOSX32;
163 } else if (os.contains("sunos")) {
164 return is64 ? Platform.SolarisAMD64 : Platform.SolarisX86;
166 throw new UnsupportedOperationException("The specified platform: " + os + " is not supported.");
170 private static JmeContext newContextLwjgl(AppSettings settings, JmeContext.Type type) {
172 Class<? extends JmeContext> ctxClazz = null;
175 ctxClazz = (Class<? extends JmeContext>) Class.forName("com.jme3.system.lwjgl.LwjglCanvas");
178 ctxClazz = (Class<? extends JmeContext>) Class.forName("com.jme3.system.lwjgl.LwjglDisplay");
180 case OffscreenSurface:
181 ctxClazz = (Class<? extends JmeContext>) Class.forName("com.jme3.system.lwjgl.LwjglOffscreenBuffer");
184 throw new IllegalArgumentException("Unsupported context type " + type);
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);
200 private static JmeContext newContextJogl(AppSettings settings, JmeContext.Type type) {
202 Class<? extends JmeContext> ctxClazz = null;
205 ctxClazz = (Class<? extends JmeContext>) Class.forName("com.jme3.system.jogl.JoglDisplay");
208 ctxClazz = (Class<? extends JmeContext>) Class.forName("com.jme3.system.jogl.JoglCanvas");
211 throw new IllegalArgumentException("Unsupported context type " + type);
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);
227 private static JmeContext newContextCustom(AppSettings settings, JmeContext.Type type) {
229 String className = settings.getRenderer().substring("CUSTOM".length());
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);
245 public static JmeContext newContext(AppSettings settings, JmeContext.Type contextType) {
246 initialize(settings);
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);
263 throw new UnsupportedOperationException(
264 "Unrecognizable renderer specified: "
265 + settings.getRenderer());
270 public static AudioRenderer newAudioRenderer(AppSettings settings) {
271 initialize(settings);
272 Class<? extends AudioRenderer> clazz = null;
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");
279 throw new UnsupportedOperationException(
280 "Unrecognizable audio renderer specified: "
281 + settings.getAudioRenderer());
284 AudioRenderer ar = clazz.newInstance();
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);
297 public static void initialize(AppSettings settings) {
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);
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);
321 logger.log(Level.INFO, "Running on {0} chototsu", getFullName());
324 if (!lowPermissions) {
326 Natives.extractNativeLibs(getPlatform(), settings);
327 } catch (IOException ex) {
328 logger.log(Level.SEVERE, "Error while copying native libraries", ex);
333 public static String getFullName() {
334 return "jMonkeyEngine 3.0.0 Beta";
337 public static InputStream getResourceAsStream(String name) {
338 return JmeSystem.class.getResourceAsStream(name);
341 public static URL getResource(String name) {
342 return JmeSystem.class.getResource(name);