/**
* Copyright 2008 - 2011
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*
* @project loon
* @author cping
* @email javachenpeng@yahoo.com.cn
* @version 0.3.3
*/
package loon;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Random;
import loon.core.CallQueue;
import loon.core.event.Drawable;
import loon.core.event.Updateable;
import loon.core.geom.RectBox;
import loon.core.graphics.device.LColor;
import loon.core.graphics.opengl.FrameBuffer;
import loon.core.graphics.opengl.GL;
import loon.core.graphics.opengl.GLEx;
import loon.core.graphics.opengl.LTexture;
import loon.core.graphics.opengl.LTexture.Format;
import loon.core.resource.ConfigReader;
import loon.core.resource.Resources;
import loon.core.timer.SystemTimer;
import loon.utils.MathUtils;
import loon.utils.StringUtils;
import loon.utils.collection.IntArray;
public final class LSystem {
static GLEx _glex;
public static GLEx paint(){
return _glex;
}
static String _configFile = "assets/def.txt";
static LConfig _config;
public static LConfig getConfig() {
synchronized (LConfig.class) {
if (_config == null) {
_config = new LConfig();
_config.blend = GL.MODE_NORMAL;
try {
ConfigReader reader = ConfigReader.getInstance(_configFile);
_config.autofilterColor = reader.getBoolValue(
"auto_filter", false);
_config.autofilterAll = reader.getBoolValue(
"auto_filter_all", false);
String result = reader.get("auto_colors_files");
if (result == null) {
_config.autofilterColor = false;
} else {
HashSet<String> list = new HashSet<String>(10);
String[] files = StringUtils.split(result, ",");
if (files.length > 0) {
for (int i = 0; i < files.length; i++) {
list.add(files[i]);
}
if (list.size() > 0) {
_config.filterFiles = list
.toArray(new String[0]);
}
}
}
result = reader.get("blend");
if (result != null) {
int mode = GL.MODE_NORMAL;
if ("normal".equalsIgnoreCase(result)) {
mode = GL.MODE_NORMAL;
} else if ("alphamap".equalsIgnoreCase(result)) {
mode = GL.MODE_ALPHA_MAP;
} else if ("alphablend".equalsIgnoreCase(result)) {
mode = GL.MODE_ALPHA_BLEND;
} else if ("colormultiply".equalsIgnoreCase(result)) {
mode = GL.MODE_COLOR_MULTIPLY;
} else if ("add".equalsIgnoreCase(result)) {
mode = GL.MODE_ADD;
} else if ("screen".equalsIgnoreCase(result)) {
mode = GL.MODE_SCREEN;
} else if ("alpha".equalsIgnoreCase(result)) {
mode = GL.MODE_ALPHA;
} else if ("speed".equalsIgnoreCase(result)) {
mode = GL.MODE_SPEED;
} else if ("alphaone".equalsIgnoreCase(result)) {
mode = GL.MODE_ALPHA_ONE;
} else if ("none".equalsIgnoreCase(result)) {
mode = GL.MODE_NONE;
}
_config.blend = mode;
}
result = reader.get("auto_filter_keywords");
if (result != null) {
_config.filterkeywords = StringUtils.split(result, ",");
}
result = reader.get("auto_colors");
if (result == null) {
_config.filterColors = new int[1];
_config.filterColors[0] = LColor.black.getRGB();
} else {
String[] colors = StringUtils.split(result, ",");
if (colors.length > 0) {
IntArray ints = new IntArray();
for (int i = 0; i < colors.length; i++) {
String colorName = colors[i];
if (MathUtils.isNan(colorName)) {
ints.add(Double.valueOf(colorName)
.intValue());
} else {
int color_int = LColor.black.getRGB();
if (colorName.startsWith("#")
|| colorName.startsWith("0")) {
color_int = LColor.decode(colorName)
.getRGB();
} else {
if (colorName.equalsIgnoreCase("red")) {
color_int = LColor.red.getRGB();
} else if (colorName
.equalsIgnoreCase("white")) {
color_int = LColor.white.getRGB();
} else if (colorName
.equalsIgnoreCase("blue")) {
color_int = LColor.blue.getRGB();
} else if (colorName
.equalsIgnoreCase("gray")) {
color_int = LColor.gray.getRGB();
} else if (colorName
.equalsIgnoreCase("yellow")) {
color_int = LColor.yellow.getRGB();
} else if (colorName
.equalsIgnoreCase("green")) {
color_int = LColor.green.getRGB();
} else if (colorName
.equalsIgnoreCase("orange")) {
color_int = LColor.orange.getRGB();
} else if (colorName
.equalsIgnoreCase("wheat")) {
color_int = LColor.wheat.getRGB();
} else if (colorName
.equalsIgnoreCase("gold")) {
color_int = LColor.gold.getRGB();
}
}
if (!ints.contains(color_int)) {
ints.add(color_int);
}
}
}
_config.filterColors = ints.toArray();
}
}
} catch (IOException e) {
}
}
return _config;
}
}
public static FrameBuffer newFrameBuffer(LTexture texture) {
return new JavaSEFrameBuffer(texture);
}
public static FrameBuffer newFrameBuffer(int width, int height,
Format format) {
return new JavaSEFrameBuffer(width, height, format);
}
public static FrameBuffer newFrameBuffer(int width, int height) {
return new JavaSEFrameBuffer(width, height);
}
public static Files files = null;
public static Files files() {
if (files == null) {
files = new JavaSEFiles();
}
return files;
}
public static String getFileName(String name) {
if (name == null) {
return "";
}
int length = name.length();
int size = name.lastIndexOf(LSystem.FS) + 1;
if (size < length) {
return name.substring(size, length);
} else {
return "";
}
}
public static String getExtension(String name) {
if (name == null) {
return "";
}
int index = name.lastIndexOf(".");
if (index == -1) {
return "";
} else {
return name.substring(index + 1);
}
}
public String getLanguage() {
return java.util.Locale.getDefault().getLanguage();
}
public enum ApplicationType {
Android, JavaSE, XNA, IOS, HTML5, PSM
}
public static CallQueue global_queue;
public static ApplicationType type = ApplicationType.JavaSE;
public static float EMULATOR_BUTTIN_SCALE = 1f;
public final static int RESOLUTION_LOW = 0;
public final static int RESOLUTION_MEDIUM = 1;
public final static int RESOLUTION_HIGH = 2;
public static int getResolutionType() {
final int max = MathUtils.max(screenRect.width, screenRect.height);
if (max < 480) {
return RESOLUTION_LOW;
} else if (max <= 800 && max >= 480) {
return RESOLUTION_MEDIUM;
} else {
return RESOLUTION_HIGH;
}
}
public final static void post(Updateable update) {
if (global_queue != null) {
global_queue.invokeLater(update);
} else {
LSystem.load(update);
}
}
public final static int TRANSPARENT = 0xff000000;
public final static boolean isThreadDrawing() {
Thread thread = Thread.currentThread();
if (thread != null) {
if ("OpenGLThread".equalsIgnoreCase(thread.getName())) {
return true;
}
}
return false;
}
public static final int DEFAULT_BUFFER_SIZE = 8192;
public static final byte[] EMPTY_BYTES = new byte[0];
public static void copyStream(InputStream input, OutputStream output)
throws IOException {
copyStream(input, output, DEFAULT_BUFFER_SIZE);
}
public static void copyStream(InputStream input, OutputStream output,
int bufferSize) throws IOException {
byte[] buffer = new byte[bufferSize];
int bytesRead;
while ((bytesRead = input.read(buffer)) != -1) {
output.write(buffer, 0, bytesRead);
}
}
public static byte[] copyStreamToByteArray(InputStream input)
throws IOException {
return copyStreamToByteArray(input, input.available());
}
public static byte[] copyStreamToByteArray(InputStream input,
int estimatedSize) throws IOException {
ByteArrayOutputStream baos = new OptimizedByteArrayOutputStream(
Math.max(0, estimatedSize));
copyStream(input, baos);
return baos.toByteArray();
}
public static String copyStreamToString(InputStream input)
throws IOException {
return copyStreamToString(input, input.available());
}
public static String copyStreamToString(InputStream input,
int approxStringLength) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
StringWriter w = new StringWriter(Math.max(0, approxStringLength));
char[] buffer = new char[DEFAULT_BUFFER_SIZE];
int charsRead;
while ((charsRead = reader.read(buffer)) != -1) {
w.write(buffer, 0, charsRead);
}
return w.toString();
}
static public class OptimizedByteArrayOutputStream extends
ByteArrayOutputStream {
public OptimizedByteArrayOutputStream(int initialSize) {
super(initialSize);
}
@Override
public synchronized byte[] toByteArray() {
if (count == buf.length) {
return buf;
}
return super.toByteArray();
}
public byte[] getBuffer() {
return buf;
}
}
public final static void close(LTexture tex2d) {
if (tex2d != null) {
try {
tex2d.destroy();
tex2d = null;
} catch (Exception e) {
}
}
}
public final static void close(Closeable in) {
if (in != null) {
try {
in.close();
} catch (Exception e) {
}
}
}
public final static void load(Updateable u) {
if (LSystem.isThreadDrawing()) {
u.action(null);
} else {
LProcess process = LSystem.screenProcess;
if (process != null) {
process.addLoad(u);
}
}
}
public final static void unload(Updateable u) {
if (LSystem.isThreadDrawing()) {
u.action(null);
} else {
LProcess process = LSystem.screenProcess;
if (process != null) {
process.addUnLoad(u);
}
}
}
public final static void clearUpdate() {
LProcess process = LSystem.screenProcess;
if (process != null) {
process.removeAllDrawing();
}
}
public final static void drawing(Drawable d) {
LProcess process = LSystem.screenProcess;
if (process != null) {
process.addDrawing(d);
}
}
public final static void clearDrawing() {
LProcess process = LSystem.screenProcess;
if (process != null) {
process.removeAllDrawing();
}
}
// 框架名
final static public String FRAMEWORK = "loon";
// 包内默认的图片路径
final static public String FRAMEWORK_IMG_NAME = "assets/loon_";
// 框架版本信息
final static public String VERSION = "0.4.1";
// 秒
final static public long SECOND = 1000;
// 分
final static public long MINUTE = SECOND * 60;
// 小时
final static public long HOUR = MINUTE * 60;
// 天
final static public long DAY = HOUR * 24;
// 周
final static public long WEEK = DAY * 7;
// 理论上一年
final static public long YEAR = DAY * 365;
// 随机数
final static public Random random = new Random();
// 默认编码格式
final static public String encoding = "UTF-8";
// 行分隔符
final static public String LS = System.getProperty("line.separator", "\n");
// 文件分割符
final static public String FS = System.getProperty("file.separator", "\\");
// 默认的最大窗体宽(横屏)
public static int MAX_SCREEN_WIDTH = 480;
// 默认的最大窗体高(横屏)
public static int MAX_SCREEN_HEIGHT = 320;
public static RectBox screenRect = new RectBox(0, 0, MAX_SCREEN_WIDTH,
MAX_SCREEN_HEIGHT);
final private static Runtime systemRuntime = Runtime.getRuntime();
final static private boolean osIsLinux;
final static private boolean osIsUnix;
final static private boolean osIsMacOs;
final static private boolean osIsWindows;
final static private boolean osIsWindowsXP;
final static private boolean osIsWindows2003;
final static private boolean osBit64;
final static public String OS_NAME;
final static public int JAVA_13 = 0;
final static public int JAVA_14 = 1;
final static public int JAVA_15 = 2;
final static public int JAVA_16 = 3;
final static public int JAVA_17 = 4;
final static public int JAVA_18 = 5;
final static public int JAVA_19 = 6;
public static LProcess screenProcess;
public static float scaleWidth = 1, scaleHeight = 1;
public static int FONT_TYPE = 15;
public static int FONT_SIZE = 1;
public static String FONT_NAME = "黑体";
public static String LOG_FILE = "log.txt";
public static boolean DEFAULT_ROTATE_CACHE = true;
public static int DEFAULT_MAX_CACHE_SIZE = 30;
public static int DEFAULT_MAX_FPS = 60;
public static boolean AUTO_REPAINT = true;
public static boolean isApplet, isPaused, isLogo;
public static boolean isStringTexture = false, isBackLocked = false;
private static String javaVersion;
private static HashMap<String, Object> settings = new HashMap<String, Object>(
5);
/**
* 设定一组键值对到缓存当中
*
* @param key
* @param value
*/
public static void set(String key, Object value) {
if (key == null || "".equals(key)) {
return;
}
settings.put(key, value);
}
/**
* 获得指定键所对应的数值
*
* @param key
* @return
*/
public static Object get(String key) {
if (key == null || "".equals(key)) {
return null;
}
return settings.get(key);
}
/**
* 获得计时器
*
* @return
*/
public static SystemTimer getSystemTimer() {
return new SystemTimer();
}
static {
OS_NAME = System.getProperty("os.name").toLowerCase();
osIsLinux = OS_NAME.indexOf("linux") != -1;
osIsUnix = OS_NAME.indexOf("nix") != -1 || OS_NAME.indexOf("nux") != 1;
osIsMacOs = OS_NAME.indexOf("mac") != -1;
osIsWindows = OS_NAME.indexOf("windows") != -1;
osIsWindowsXP = OS_NAME.startsWith("Windows")
&& (OS_NAME.compareTo("5.1") >= 0);
osIsWindows2003 = "windows 2003".equals(OS_NAME);
osBit64 = System.getProperty("os.arch").equals("amd64");
javaVersion = System.getProperty("java.version");
}
public static void exit() {
if (LSystem.screenProcess != null
&& LSystem.screenProcess.getScene() != null) {
LSystem.screenProcess.getScene().exit();
} else {
System.exit(0);
}
}
public static void stopRepaint() {
LSystem.AUTO_REPAINT = false;
LSystem.isPaused = true;
}
public static void startRepaint() {
LSystem.AUTO_REPAINT = true;
LSystem.isPaused = false;
}
/**
* 清空系统缓存资源
*
*/
public static void destroy() {
JavaSEGraphicsUtils.destroyImages();
Resources.destroy();
}
/**
* 申请回收系统资源
*
*/
final public static void gc() {
try {
long maxRestoreLoops = 299;
long pauseTime = 10;
long UsedMemoryNow = nowMemory();
long UsedMemoryPrev = Long.MAX_VALUE;
for (int i = 0; i < maxRestoreLoops; i++) {
systemRuntime.runFinalization();
systemRuntime.gc();
try {
Thread.sleep(pauseTime);
} catch (InterruptedException e) {
}
if (UsedMemoryPrev > UsedMemoryNow) {
UsedMemoryPrev = UsedMemoryNow;
UsedMemoryNow = nowMemory();
} else {
break;
}
}
} catch (Throwable e) {
System.gc();
}
}
/**
* 以指定范围内的指定概率执行gc
*
* @param size
* @param rand
*/
final public static void gc(final int size, final long rand) {
if (rand > size) {
throw new RuntimeException(
("GC random probability " + rand + " > " + size).intern());
}
if (LSystem.random.nextInt(size) <= rand) {
LSystem.gc();
}
}
/**
* 以指定概率使用gc回收系统资源
*
* @param rand
*/
final public static void gc(final long rand) {
gc(100, rand);
}
/**
* 打开当前系统浏览器
*
* @param url
*/
public static void openURL(String url) {
try {
java.net.URI uri = new java.net.URI(url);
java.awt.Desktop.getDesktop().browse(uri);
} catch (Throwable e) {
try {
browse(url);
} catch (Exception err) {
try {
if (LSystem.isWindows()) {
File iexplore = new File(
"C:\\Program Files\\Internet Explorer\\iexplore.exe");
if (iexplore.exists()) {
systemRuntime.exec(iexplore.getAbsolutePath()
+ " \"" + url + "\"");
} else {
systemRuntime
.exec("rundll32 url.dll,FileProtocolHandler "
+ url);
}
} else if (LSystem.isMacOS()) {
systemRuntime.exec("open " + url);
} else if (LSystem.isUnix()) {
String[] browsers = { "epiphany", "firefox", "mozilla",
"konqueror", "netscape", "opera", "links",
"lynx" };
StringBuffer cmd = new StringBuffer();
for (int i = 0; i < browsers.length; i++) {
cmd.append((i == 0 ? "" : " || ") + browsers[i]
+ " \"" + url + "\" ");
}
systemRuntime.exec(new String[] { "sh", "-c",
cmd.toString() });
}
} catch (IOException ex) {
e.printStackTrace();
}
}
}
}
private static void browse(String url) throws Exception {
String osName = System.getProperty("os.name", "");
if (osName.startsWith("Mac OS")) {
Class<?> fileMgr = Class.forName("com.apple.eio.FileManager");
Method openURL = fileMgr.getDeclaredMethod("openURL",
new Class[] { String.class });
openURL.invoke(null, new Object[] { url });
} else if (osName.startsWith("Windows")) {
Runtime.getRuntime().exec(
"rundll32 url.dll,FileProtocolHandler " + url);
} else {
String[] browsers = { "firefox", "opera", "konqueror", "epiphany",
"mozilla", "netscape" };
String browser = null;
for (int count = 0; count < browsers.length && browser == null; count++) {
if (Runtime.getRuntime()
.exec(new String[] { "which", browsers[count] })
.waitFor() == 0) {
browser = browsers[count];
}
}
if (browser == null) {
throw new Exception("Could not find web browser");
} else {
Runtime.getRuntime().exec(new String[] { browser, url });
}
}
}
final private static long nowMemory() {
return systemRuntime.totalMemory() - systemRuntime.freeMemory();
}
public static boolean isLinux() {
return osIsLinux;
}
public static boolean isMacOS() {
return osIsMacOs;
}
public static boolean isUnix() {
return osIsUnix;
}
public static boolean isWindows() {
return osIsWindows;
}
public static boolean isWindowsXP() {
return osIsWindowsXP;
}
public static boolean isWindows2003() {
return osIsWindows2003;
}
public static boolean isBit64() {
return osBit64;
}
public static boolean isSun() {
return System.getProperty("java.vm.vendor").indexOf("Sun") != -1
|| System.getProperty("java.vm.vendor").indexOf("Oracle") != -1;
}
public static boolean isApple() {
return System.getProperty("java.vm.vendor").indexOf("Apple") != -1;
}
public static boolean isHPUX() {
return System.getProperty("java.vm.vendor").indexOf(
"Hewlett-Packard Company") != -1;
}
public static boolean isIBM() {
return System.getProperty("java.vm.vendor").indexOf("IBM") != -1;
}
public static boolean isBlackdown() {
return System.getProperty("java.vm.vendor").indexOf("Blackdown") != -1;
}
public static boolean isBEAWithUnsafeSupport() {
if (System.getProperty("java.vm.vendor").indexOf("BEA") != -1) {
String vmVersion = System.getProperty("java.vm.version");
if (StringUtils.startsWith(vmVersion, 'R')) {
return true;
}
String vmInfo = System.getProperty("java.vm.info");
if (vmInfo != null) {
return (vmInfo.startsWith("R25.1") || vmInfo
.startsWith("R25.2"));
}
}
return false;
}
public static String getJavaVersion() {
return javaVersion;
}
/**
* 写入整型数据到OutputStream
*
* @param out
* @param number
*/
public final static void writeInt(final OutputStream out, final int number) {
byte[] bytes = new byte[4];
try {
for (int i = 0; i < 4; i++) {
bytes[i] = (byte) ((number >> (i * 8)) & 0xff);
}
out.write(bytes);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
/**
* 从InputStream中获得整型数据
*
* @param in
* @return
*/
final static public int readInt(final InputStream in) {
int data = -1;
try {
data = (in.read() & 0xff);
data |= ((in.read() & 0xff) << 8);
data |= ((in.read() & 0xff) << 16);
data |= ((in.read() & 0xff) << 24);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
return data;
}
/**
* 合并hashCode和指定类型的数值生成新的Code值(以下同)
*
* @param hashCode
* @param value
* @return
*/
public static int unite(int hashCode, boolean value) {
int v = value ? 1231 : 1237;
return unite(hashCode, v);
}
public static int unite(int hashCode, long value) {
int v = (int) (value ^ (value >>> 32));
return unite(hashCode, v);
}
public static int unite(int hashCode, float value) {
int v = Float.floatToIntBits(value);
return unite(hashCode, v);
}
public static int unite(int hashCode, double value) {
long v = Double.doubleToLongBits(value);
return unite(hashCode, v);
}
public static int unite(int hashCode, Object value) {
return unite(hashCode, value.hashCode());
}
public static int unite(int hashCode, int value) {
return 31 * hashCode + value;
}
}