/** * 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 * @version 0.1 */ package loon; import java.util.ArrayList; import java.util.LinkedList; import loon.core.Director; import loon.core.EmulatorButtons; import loon.core.EmulatorListener; import loon.core.event.Drawable; import loon.core.event.Updateable; import loon.core.graphics.Screen; import loon.core.graphics.device.LColor; import loon.core.graphics.device.LImage; import loon.core.graphics.opengl.GLEx; import loon.core.graphics.opengl.GLLoader; import loon.core.graphics.opengl.GLMesh; import loon.core.graphics.opengl.LTexture; import loon.core.graphics.opengl.LTextureBatch; import loon.core.graphics.opengl.LTextures; import loon.core.graphics.opengl.ScreenUtils; import loon.core.processes.RealtimeProcess; import loon.core.processes.RealtimeProcessManager; import loon.core.timer.LTimerContext; import loon.utils.MathUtils; public class LProcess extends Director{ private JavaSEApp scene; ArrayList<Updateable> loads; ArrayList<Updateable> unloads; ArrayList<Drawable> drawings; EmulatorListener emulatorListener; EmulatorButtons emulatorButtons; private LinkedList<Screen> screens; private Screen currentControl, loading_Control; private boolean isInstance; private int id, width, height; private JavaSEInputFactory currentInput; private LTransition transition; private boolean waitTransition; private boolean running; LProcess(LGame scene, int width, int height) { LSystem.global_queue = scene; this.width = width; this.height = height; this.scene = scene; this.screens = new LinkedList<Screen>(); this.currentInput = new JavaSEInputFactory(this); this.clear(); } public void clear() { if (loads == null) { loads = new ArrayList<Updateable>(10); } else { loads.clear(); } if (unloads == null) { unloads = new ArrayList<Updateable>(10); } else { unloads.clear(); } if (drawings == null) { drawings = new ArrayList<Drawable>(10); } else { drawings.clear(); } } public void begin() { if (!running) { if (loading_Control != null) { setScreen(loading_Control); } running = true; } } public void resize(int w, int h) { if (isInstance) { currentControl.resize(w, h); } } public void end() { if (running) { running = false; } } public void calls() { if (isInstance) { LTextureBatch.clearBatchCaches(); } } public void onResume() { if (isInstance) { currentControl.onResume(); } } public void onPause() { if (isInstance) { currentControl.onPause(); } } public boolean next() { if (isInstance) { if (currentControl.next()) { return true; } } return false; } public void runTimer(LTimerContext context) { if (isInstance) { if (waitTransition) { if (transition != null) { switch (transition.code) { default: if (!currentControl.isOnLoadComplete()) { transition.update(context.timeSinceLastUpdate); } break; case 1: if (!transition.completed()) { transition.update(context.timeSinceLastUpdate); } else { endTransition(); } break; } } } else { currentControl.runTimer(context); currentInput.runTimer(context); return; } } } private final static void callUpdateable(final ArrayList<Updateable> list) { LSystem.AUTO_REPAINT = false; ArrayList<Updateable> loadCache; synchronized (list) { loadCache = new ArrayList<Updateable>(list); list.clear(); } for (int i = 0; i < loadCache.size(); i++) { Updateable running = loadCache.get(i); synchronized (running) { running.action(null); } } loadCache = null; LSystem.AUTO_REPAINT = true; } // --- Load start ---// public void addLoad(Updateable u) { synchronized (loads) { loads.add(u); } } public void removeLoad(Updateable u) { synchronized (loads) { loads.remove(u); } } public void removeAllLoad() { synchronized (loads) { loads.clear(); } } public void load() { if (isInstance) { final int count = loads.size(); if (count > 0) { callUpdateable(loads); } } } // --- Load end ---// // --- UnLoad start ---// public void addUnLoad(Updateable u) { synchronized (unloads) { unloads.add(u); } } public void removeUnLoad(Updateable u) { synchronized (unloads) { unloads.remove(u); } } public void removeAllUnLoad() { synchronized (unloads) { unloads.clear(); } } public void unload() { if (isInstance) { final int count = unloads.size(); if (count > 0) { callUpdateable(unloads); } } } // --- UnLoad end ---// // --- Drawable start ---// public void addDrawing(Drawable d) { synchronized (drawings) { drawings.add(d); } } public void removeDrawing(Drawable d) { synchronized (drawings) { drawings.remove(d); } } public void removeAllDrawing() { synchronized (drawings) { drawings.clear(); } } public void drawable(long elapsedTime) { if (isInstance) { final int count = drawings.size(); if (count > 0) { for (int i = 0; i < count; i++) { drawings.get(i).action(elapsedTime); } // not delete // drawings.clear(); } } } // --- Drawable end ---// public void draw(GLEx g) { if (isInstance) { if (waitTransition) { if (transition != null) { if (transition.isDisplayGameUI) { currentControl.createUI(g); } switch (transition.code) { default: if (!currentControl.isOnLoadComplete()) { transition.draw(g); } break; case 1: if (!transition.completed()) { transition.draw(g); } break; } } } else { currentControl.createUI(g); return; } } } public void drawEmulator(GLEx gl) { if (emulatorButtons != null) { emulatorButtons.draw(gl); } } public LColor getColor() { if (isInstance) { return currentControl.getColor(); } return null; } public LTexture getBackground() { if (isInstance) { return currentControl.getBackground(); } return null; } public int getRepaintMode() { if (isInstance) { return currentControl.getRepaintMode(); } return Screen.SCREEN_CANVAS_REPAINT; } /** * 设定模拟按钮监听器 * * @param emulatorListener */ public void setEmulatorListener(EmulatorListener emulator) { this.emulatorListener = emulator; if (emulatorListener != null) { if (emulatorButtons == null) { emulatorButtons = new EmulatorButtons(emulatorListener, LSystem.screenRect.width, LSystem.screenRect.height); } else { emulatorButtons.setEmulatorListener(emulator); } } else { emulatorButtons = null; } } /** * 获得模拟器监听 * * @return */ public EmulatorListener getEmulatorListener() { return emulatorListener; } /** * 获得模拟器按钮 * * @return */ public EmulatorButtons getEmulatorButtons() { return emulatorButtons; } public void setID(int id) { this.id = id; } public int getID() { return id; } public final void setTransition(LTransition t) { this.transition = t; } public final LTransition getTransition() { return this.transition; } private final void startTransition() { if (transition != null) { waitTransition = true; if (isInstance) { currentControl.setLock(true); } } } private final void endTransition() { if (transition != null) { switch (transition.code) { default: waitTransition = false; transition.dispose(); break; case 1: if (transition.completed()) { waitTransition = false; transition.dispose(); } break; } if (isInstance) { currentControl.setLock(false); } } else { waitTransition = false; } } public float getX() { if (isInstance) { return currentControl.getX(); } return 0; } public float getY() { if (isInstance) { return currentControl.getY(); } return 0; } public synchronized Screen getScreen() { return currentControl; } public void runFirstScreen() { int size = screens.size(); if (size > 0) { Object o = screens.getFirst(); if (o != currentControl) { setScreen((Screen) o, false); } } } public void runLastScreen() { int size = screens.size(); if (size > 0) { Object o = screens.getLast(); if (o != currentControl) { setScreen((Screen) o, false); } } } public void runPreviousScreen() { int size = screens.size(); if (size > 0) { for (int i = 0; i < size; i++) { if (currentControl == screens.get(i)) { if (i - 1 > -1) { setScreen(screens.get(i - 1), false); return; } } } } } public void runNextScreen() { int size = screens.size(); if (size > 0) { for (int i = 0; i < size; i++) { if (currentControl == screens.get(i)) { if (i + 1 < size) { setScreen(screens.get(i + 1), false); return; } } } } } public void runIndexScreen(int index) { int size = screens.size(); if (size > 0 && index > -1 && index < size) { Object o = screens.get(index); if (currentControl != o) { setScreen(screens.get(index), false); } } } public void addScreen(final Screen screen) { if (screen == null) { throw new RuntimeException("Cannot create a [IScreen] instance !"); } screens.add(screen); } public LinkedList<Screen> getScreens() { return screens; } public int getScreenCount() { return screens.size(); } public void setScreen(final Screen screen) { if (GLEx.gl == null || LSystem.isLogo) { loading_Control = screen; } else { setScreen(screen, true); } } private void setScreen(final Screen screen, boolean put) { if (currentControl != null && currentControl.isOnLoadComplete()) { return; } synchronized (this) { if (screen == null) { this.isInstance = false; throw new RuntimeException( "Cannot create a [Screen] instance !"); } GLLoader.destory(); if (!LSystem.isLogo) { if (currentControl != null) { setTransition(screen.onTransition()); } else { LTransition transition = screen.onTransition(); if (transition == null) { switch (MathUtils.random(0, 3)) { case 0: transition = LTransition.newFadeIn(); break; case 1: transition = LTransition.newArc(); break; case 2: transition = LTransition .newSplitRandom(LColor.black); break; case 3: transition = LTransition .newCrossRandom(LColor.black); break; } } setTransition(transition); } } screen.setOnLoadState(false); if (currentControl == null) { currentControl = screen; } else { synchronized (currentControl) { currentControl.destroy(); currentControl = screen; } } this.isInstance = true; if (screen instanceof EmulatorListener) { setEmulatorListener((EmulatorListener) screen); } else { setEmulatorListener(null); } screen.onCreate(LSystem.screenRect.width, LSystem.screenRect.height); RealtimeProcess process = new RealtimeProcess() { @Override public void run() { if (!LSystem.isLogo) { startTransition(); screen.setClose(false); screen.onLoad(); screen.onLoaded(); screen.setOnLoadState(true); endTransition(); kill(); } } }; process.setDelay(60); RealtimeProcessManager.get().addProcess(process); if (put) { screens.add(screen); } loading_Control = null; } } public void keyDown(LKey e) { if (isInstance) { currentControl.keyPressed(e); } } public void keyUp(LKey e) { if (isInstance) { currentControl.keyReleased(e); } } public void keyTyped(LKey e) { if (isInstance) { currentControl.keyTyped(e); } } public void mousePressed(LTouch e) { if (isInstance) { currentControl.mousePressed(e); } } public void mouseReleased(LTouch e) { if (isInstance) { currentControl.mouseReleased(e); } } public void mouseMoved(LTouch e) { if (isInstance) { currentControl.mouseMoved(e); } } public void mouseDragged(LTouch e) { if (isInstance) { currentControl.mouseDragged(e); } } public JavaSEApp getScene() { return scene; } public void setScene(JavaSEApp scene) { this.scene = scene; } public int getHeight() { return height; } public int getWidth() { return width; } public void onDestroy() { endTransition(); if (isInstance) { isInstance = false; unloads.clear(); drawings.clear(); if (currentControl != null) { currentControl.destroy(); currentControl = null; } LTextures.disposeAll(); LImage.disposeAll(); ScreenUtils.disposeAll(); GLMesh.disposeAll(); } } public void setCurrentScreen(final Screen screen) { if (screen != null) { this.isInstance = false; if (currentControl != null) { currentControl.destroy(); } this.currentControl = screen; currentControl.setLock(false); currentControl.setLocation(0, 0); currentControl.setClose(false); currentControl.setOnLoadState(true); if (screen.getBackground() != null) { currentControl.setRepaintMode(Screen.SCREEN_BITMAP_REPAINT); } this.isInstance = true; if (screen instanceof EmulatorListener) { setEmulatorListener((EmulatorListener) screen); } else { setEmulatorListener(null); } this.screens.add(screen); } } public JavaSEInputFactory getInput() { return currentInput; } }