OSDN Git Service

Change build system ant to sbt.
[mikumikustudio/MikuMikuStudio.git] / desktop / src / main / java / com / jme3 / system / JmeSystemDelegateImpl.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
41 import javax.swing.*;
42 import java.io.IOException;
43 import java.io.InputStream;
44 import java.net.URL;
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;
49
50 public class JmeSystemDelegateImpl implements JmeSystemDelegate{
51
52     private static final Logger logger = Logger.getLogger(JmeSystemDelegateImpl.class.getName());
53     private boolean initialized = false;
54     private boolean lowPermissions = false;
55
56     public boolean trackDirectMemory() {
57         return false;
58     }
59
60     public void setLowPermissions(boolean lowPerm) {
61         lowPermissions = lowPerm;
62     }
63
64     public boolean isLowPermissions() {
65         return lowPermissions;
66     }
67
68     public AssetManager newAssetManager(URL configFile) {
69         return new DesktopAssetManager(configFile);
70     }
71
72     public AssetManager newAssetManager() {
73         return new DesktopAssetManager(null);
74     }
75
76     public boolean showSettingsDialog(AppSettings sourceSettings, final boolean loadFromRegistry) {
77         if (SwingUtilities.isEventDispatchThread()) {
78             throw new IllegalStateException("Cannot run from EDT");
79         }
80
81
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());
88         }
89
90         final AtomicBoolean done = new AtomicBoolean();
91         final AtomicInteger result = new AtomicInteger();
92         final Object lock = new Object();
93
94         final SelectionListener selectionListener = new SelectionListener() {
95
96             public void onSelection(int selection) {
97                 synchronized (lock) {
98                     done.set(true);
99                     result.set(selection);
100                     lock.notifyAll();
101                 }
102             }
103         };
104         SwingUtilities.invokeLater(new Runnable() {
105
106             public void run() {
107                 synchronized (lock) {
108                     SettingsDialog dialog = new SettingsDialog(settings, iconUrl, loadFromRegistry);
109                     dialog.setSelectionListener(selectionListener);
110                     dialog.showDialog();
111                 }
112             }
113         });
114
115         synchronized (lock) {
116             while (!done.get()) {
117                 try {
118                     lock.wait();
119                 } catch (InterruptedException ex) {
120                 }
121             }
122         }
123
124         sourceSettings.copyFrom(settings);
125
126         return result.get() == SettingsDialog.APPROVE_SELECTION;
127     }
128
129     private boolean is64Bit(String arch) {
130         if (arch.equals("x86")) {
131             return false;
132         } else if (arch.equals("amd64")) {
133             return true;
134         } else if (arch.equals("x86_64")) {
135             return true;
136         } else if (arch.equals("ppc") || arch.equals("PowerPC")) {
137             return false;
138         } else if (arch.equals("ppc64")) {
139             return true;
140         } else if (arch.equals("i386") || arch.equals("i686")) {
141             return false;
142         } else if (arch.equals("universal")) {
143             return false;
144         } else {
145             throw new UnsupportedOperationException("Unsupported architecture: " + arch);
146         }
147     }
148
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;
161             } else {
162                 return is64 ? Platform.MacOSX64 : Platform.MacOSX32;
163             }
164         } else if (os.contains("sunos")) {
165             return is64 ? Platform.SolarisAMD64 : Platform.SolarisX86;
166         } else {
167             throw new UnsupportedOperationException("The specified platform: " + os + " is not supported.");
168         }
169     }
170
171     private JmeContext newContextLwjgl(AppSettings settings, JmeContext.Type type) {
172         try {
173             Class<? extends JmeContext> ctxClazz = null;
174             switch (type) {
175                 case Canvas:
176                     ctxClazz = (Class<? extends JmeContext>) Class.forName("com.jme3.system.lwjgl.LwjglCanvas");
177                     break;
178                 case Display:
179                     ctxClazz = (Class<? extends JmeContext>) Class.forName("com.jme3.system.lwjgl.LwjglDisplay");
180                     break;
181                 case OffscreenSurface:
182                     ctxClazz = (Class<? extends JmeContext>) Class.forName("com.jme3.system.lwjgl.LwjglOffscreenBuffer");
183                     break;
184                 default:
185                     throw new IllegalArgumentException("Unsupported context type " + type);
186             }
187
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);
196         }
197
198         return null;
199     }
200
201     private JmeContext newContextJogl(AppSettings settings, JmeContext.Type type) {
202         try {
203             Class<? extends JmeContext> ctxClazz = null;
204             switch (type) {
205                 case Display:
206                     ctxClazz = (Class<? extends JmeContext>) Class.forName("com.jme3.system.jogl.JoglDisplay");
207                     break;
208                 case Canvas:
209                     ctxClazz = (Class<? extends JmeContext>) Class.forName("com.jme3.system.jogl.JoglCanvas");
210                     break;
211                 default:
212                     throw new IllegalArgumentException("Unsupported context type " + type);
213             }
214
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);
223         }
224
225         return null;
226     }
227
228     private JmeContext newContextCustom(AppSettings settings, JmeContext.Type type) {
229         try {
230             String className = settings.getRenderer().substring("CUSTOM".length());
231
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);
241         }
242
243         return null;
244     }
245
246     public JmeContext newContext(AppSettings settings, JmeContext.Type contextType) {
247         initialize(settings);
248         JmeContext ctx;
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);
263         } else {
264             throw new UnsupportedOperationException(
265                     "Unrecognizable renderer specified: "
266                     + settings.getRenderer());
267         }
268         return ctx;
269     }
270
271     public AudioRenderer newAudioRenderer(AppSettings settings) {
272         initialize(settings);
273         Class<? extends AudioRenderer> clazz = null;
274         try {
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");
279             } else {
280                 throw new UnsupportedOperationException(
281                         "Unrecognizable audio renderer specified: "
282                         + settings.getAudioRenderer());
283             }
284
285             AudioRenderer ar = clazz.newInstance();
286             return ar;
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);
294         }
295         return null;
296     }
297
298     public void initialize(AppSettings settings) {
299         if (initialized) {
300             return;
301         }
302
303         initialized = true;
304         try {
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);
316             }
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);
321         }
322         logger.log(Level.INFO, "Running on {0} chototsu", getFullName());
323
324
325         if (!lowPermissions) {
326             try {
327                 Natives.extractNativeLibs(getPlatform(), settings);
328             } catch (IOException ex) {
329                 logger.log(Level.SEVERE, "Error while copying native libraries", ex);
330             }
331         }
332     }
333
334     public String getFullName() {
335         return "jMonkeyEngine 3.0.0 Beta";
336     }
337
338     public InputStream getResourceAsStream(String name) {
339         return JmeSystem.class.getResourceAsStream(name);
340     }
341
342     public URL getResource(String name) {
343         return JmeSystem.class.getResource(name);
344     }
345 }