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;
42 import java.io.IOException;
43 import java.io.InputStream;
45 import java.util.concurrent.atomic.AtomicBoolean;
46 import java.util.concurrent.atomic.AtomicInteger;
47 import java.util.logging.Level;
48 import java.util.logging.Logger;
50 public class JmeSystemDelegateImpl implements JmeSystemDelegate{
52 private static final Logger logger = Logger.getLogger(JmeSystemDelegateImpl.class.getName());
53 private boolean initialized = false;
54 private boolean lowPermissions = false;
56 public boolean trackDirectMemory() {
60 public void setLowPermissions(boolean lowPerm) {
61 lowPermissions = lowPerm;
64 public boolean isLowPermissions() {
65 return lowPermissions;
68 public AssetManager newAssetManager(URL configFile) {
69 return new DesktopAssetManager(configFile);
72 public AssetManager newAssetManager() {
73 return new DesktopAssetManager(null);
76 public boolean showSettingsDialog(AppSettings sourceSettings, final boolean loadFromRegistry) {
77 if (SwingUtilities.isEventDispatchThread()) {
78 throw new IllegalStateException("Cannot run from EDT");
82 final AppSettings settings = new AppSettings(false);
83 settings.copyFrom(sourceSettings);
84 String iconPath = sourceSettings.getSettingsDialogImage();
85 final URL iconUrl = JmeSystem.class.getResource(iconPath.startsWith("/") ? iconPath : "/" + iconPath);
86 if (iconUrl == null) {
87 throw new AssetNotFoundException(sourceSettings.getSettingsDialogImage());
90 final AtomicBoolean done = new AtomicBoolean();
91 final AtomicInteger result = new AtomicInteger();
92 final Object lock = new Object();
94 final SelectionListener selectionListener = new SelectionListener() {
96 public void onSelection(int selection) {
99 result.set(selection);
104 SwingUtilities.invokeLater(new Runnable() {
107 synchronized (lock) {
108 SettingsDialog dialog = new SettingsDialog(settings, iconUrl, loadFromRegistry);
109 dialog.setSelectionListener(selectionListener);
115 synchronized (lock) {
116 while (!done.get()) {
119 } catch (InterruptedException ex) {
124 sourceSettings.copyFrom(settings);
126 return result.get() == SettingsDialog.APPROVE_SELECTION;
129 private boolean is64Bit(String arch) {
130 if (arch.equals("x86")) {
132 } else if (arch.equals("amd64")) {
134 } else if (arch.equals("x86_64")) {
136 } else if (arch.equals("ppc") || arch.equals("PowerPC")) {
138 } else if (arch.equals("ppc64")) {
140 } else if (arch.equals("i386") || arch.equals("i686")) {
142 } else if (arch.equals("universal")) {
145 throw new UnsupportedOperationException("Unsupported architecture: " + arch);
149 public Platform getPlatform() {
150 String os = System.getProperty("os.name").toLowerCase();
151 String arch = System.getProperty("os.arch").toLowerCase();
152 logger.log(Level.INFO,"os = "+os+" arch = "+arch);
153 boolean is64 = is64Bit(arch);
154 if (os.contains("windows")) {
155 return is64 ? Platform.Windows64 : Platform.Windows32;
156 } else if (os.contains("linux") || os.contains("freebsd")) {
157 return is64 ? Platform.Linux64 : Platform.Linux32;
158 } else if (os.contains("mac os x") || os.contains("darwin")) {
159 if (arch.startsWith("ppc")) {
160 return is64 ? Platform.MacOSX_PPC64 : Platform.MacOSX_PPC32;
162 return is64 ? Platform.MacOSX64 : Platform.MacOSX32;
164 } else if (os.contains("sunos")) {
165 return is64 ? Platform.SolarisAMD64 : Platform.SolarisX86;
167 throw new UnsupportedOperationException("The specified platform: " + os + " is not supported.");
171 private JmeContext newContextLwjgl(AppSettings settings, JmeContext.Type type) {
173 Class<? extends JmeContext> ctxClazz = null;
176 ctxClazz = (Class<? extends JmeContext>) Class.forName("com.jme3.system.lwjgl.LwjglCanvas");
179 ctxClazz = (Class<? extends JmeContext>) Class.forName("com.jme3.system.lwjgl.LwjglDisplay");
181 case OffscreenSurface:
182 ctxClazz = (Class<? extends JmeContext>) Class.forName("com.jme3.system.lwjgl.LwjglOffscreenBuffer");
185 throw new IllegalArgumentException("Unsupported context type " + type);
188 return ctxClazz.newInstance();
189 } catch (InstantiationException ex) {
190 logger.log(Level.SEVERE, "Failed to create context", ex);
191 } catch (IllegalAccessException ex) {
192 logger.log(Level.SEVERE, "Failed to create context", ex);
193 } catch (ClassNotFoundException ex) {
194 logger.log(Level.SEVERE, "CRITICAL ERROR: Context class is missing!\n"
195 + "Make sure jme3_lwjgl-ogl is on the classpath.", ex);
201 private JmeContext newContextJogl(AppSettings settings, JmeContext.Type type) {
203 Class<? extends JmeContext> ctxClazz = null;
206 ctxClazz = (Class<? extends JmeContext>) Class.forName("com.jme3.system.jogl.JoglDisplay");
209 ctxClazz = (Class<? extends JmeContext>) Class.forName("com.jme3.system.jogl.JoglCanvas");
212 throw new IllegalArgumentException("Unsupported context type " + type);
215 return ctxClazz.newInstance();
216 } catch (InstantiationException ex) {
217 logger.log(Level.SEVERE, "Failed to create context", ex);
218 } catch (IllegalAccessException ex) {
219 logger.log(Level.SEVERE, "Failed to create context", ex);
220 } catch (ClassNotFoundException ex) {
221 logger.log(Level.SEVERE, "CRITICAL ERROR: Context class is missing!\n"
222 + "Make sure jme3_jogl is on the classpath.", ex);
228 private JmeContext newContextCustom(AppSettings settings, JmeContext.Type type) {
230 String className = settings.getRenderer().substring("CUSTOM".length());
232 Class<? extends JmeContext> ctxClazz = null;
233 ctxClazz = (Class<? extends JmeContext>) Class.forName(className);
234 return ctxClazz.newInstance();
235 } catch (InstantiationException ex) {
236 logger.log(Level.SEVERE, "Failed to create context", ex);
237 } catch (IllegalAccessException ex) {
238 logger.log(Level.SEVERE, "Failed to create context", ex);
239 } catch (ClassNotFoundException ex) {
240 logger.log(Level.SEVERE, "CRITICAL ERROR: Context class is missing!", ex);
246 public JmeContext newContext(AppSettings settings, JmeContext.Type contextType) {
247 initialize(settings);
249 if (settings.getRenderer() == null
250 || settings.getRenderer().equals("NULL")
251 || contextType == JmeContext.Type.Headless) {
252 ctx = new NullContext();
253 ctx.setSettings(settings);
254 } else if (settings.getRenderer().startsWith("LWJGL")) {
255 ctx = newContextLwjgl(settings, contextType);
256 ctx.setSettings(settings);
257 } else if (settings.getRenderer().startsWith("JOGL")) {
258 ctx = newContextJogl(settings, contextType);
259 ctx.setSettings(settings);
260 } else if (settings.getRenderer().startsWith("CUSTOM")) {
261 ctx = newContextCustom(settings, contextType);
262 ctx.setSettings(settings);
264 throw new UnsupportedOperationException(
265 "Unrecognizable renderer specified: "
266 + settings.getRenderer());
271 public AudioRenderer newAudioRenderer(AppSettings settings) {
272 initialize(settings);
273 Class<? extends AudioRenderer> clazz = null;
275 if (settings.getAudioRenderer().startsWith("LWJGL")) {
276 clazz = (Class<? extends AudioRenderer>) Class.forName("com.jme3.audio.lwjgl.LwjglAudioRenderer");
277 } else if (settings.getAudioRenderer().startsWith("JOAL")) {
278 clazz = (Class<? extends AudioRenderer>) Class.forName("com.jme3.audio.joal.JoalAudioRenderer");
280 throw new UnsupportedOperationException(
281 "Unrecognizable audio renderer specified: "
282 + settings.getAudioRenderer());
285 AudioRenderer ar = clazz.newInstance();
287 } catch (InstantiationException ex) {
288 logger.log(Level.SEVERE, "Failed to create context", ex);
289 } catch (IllegalAccessException ex) {
290 logger.log(Level.SEVERE, "Failed to create context", ex);
291 } catch (ClassNotFoundException ex) {
292 logger.log(Level.SEVERE, "CRITICAL ERROR: Audio implementation class is missing!\n"
293 + "Make sure jme3_lwjgl-oal or jm3_joal is on the classpath.", ex);
298 public void initialize(AppSettings settings) {
305 if (!lowPermissions) {
306 // can only modify logging settings
307 // if permissions are available
308 // JmeFormatter formatter = new JmeFormatter();
309 // Handler fileHandler = new FileHandler("jme.log");
310 // fileHandler.setFormatter(formatter);
311 // Logger.getLogger("").addHandler(fileHandler);
312 // Handler consoleHandler = new ConsoleHandler();
313 // consoleHandler.setFormatter(formatter);
314 // Logger.getLogger("").removeHandler(Logger.getLogger("").getHandlers()[0]);
315 // Logger.getLogger("").addHandler(consoleHandler);
317 // } catch (IOException ex){
318 // logger.log(Level.SEVERE, "I/O Error while creating log file", ex);
319 } catch (SecurityException ex) {
320 logger.log(Level.SEVERE, "Security error in creating log file", ex);
322 logger.log(Level.INFO, "Running on {0} chototsu", getFullName());
325 if (!lowPermissions) {
327 Natives.extractNativeLibs(getPlatform(), settings);
328 } catch (IOException ex) {
329 logger.log(Level.SEVERE, "Error while copying native libraries", ex);
334 public String getFullName() {
335 return "jMonkeyEngine 3.0.0 Beta";
338 public InputStream getResourceAsStream(String name) {
339 return JmeSystem.class.getResourceAsStream(name);
342 public URL getResource(String name) {
343 return JmeSystem.class.getResource(name);