Home | History | Annotate | Download | only in replicaisland
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.replica.replicaisland;
     18 
     19 import android.os.SystemClock;
     20 import android.view.KeyEvent;
     21 
     22 
     23 /**
     24  * The GameThread contains the main loop for the game engine logic.  It invokes the game graph,
     25  * manages synchronization of input events, and handles the draw queue swap with the rendering
     26  * thread.
     27  */
     28 public class GameThread implements Runnable {
     29     private long mLastTime;
     30 
     31     private ObjectManager mGameRoot;
     32     private GameRenderer mRenderer;
     33     private Object mPauseLock;
     34     private boolean mFinished;
     35     private boolean mPaused = false;
     36     private int mProfileFrames;
     37     private long mProfileTime;
     38 
     39     private static final float PROFILE_REPORT_DELAY = 3.0f;
     40 
     41     public GameThread(GameRenderer renderer) {
     42         mLastTime = SystemClock.uptimeMillis();
     43         mRenderer = renderer;
     44         mPauseLock = new Object();
     45         mFinished = false;
     46         mPaused = false;
     47     }
     48 
     49     public void run() {
     50         mLastTime = SystemClock.uptimeMillis();
     51         mFinished = false;
     52         while (!mFinished) {
     53             if (mGameRoot != null) {
     54                 mRenderer.waitDrawingComplete();
     55 
     56                 final long time = SystemClock.uptimeMillis();
     57                 final long timeDelta = time - mLastTime;
     58                 long finalDelta = timeDelta;
     59                 if (timeDelta > 12) {
     60                     float secondsDelta = (time - mLastTime) * 0.001f;
     61                     if (secondsDelta > 0.1f) {
     62                         secondsDelta = 0.1f;
     63                     }
     64                     mLastTime = time;
     65 
     66                     mGameRoot.update(secondsDelta, null);
     67 
     68                     CameraSystem camera = mGameRoot.sSystemRegistry.cameraSystem;
     69                     float x = 0.0f;
     70                     float y = 0.0f;
     71                     if (camera != null) {
     72                     	x = camera.getFocusPositionX();
     73                     	y = camera.getFocusPositionY();
     74                     }
     75                     BaseObject.sSystemRegistry.renderSystem.swap(mRenderer, x, y);
     76 
     77                     final long endTime = SystemClock.uptimeMillis();
     78 
     79                     finalDelta = endTime - time;
     80 
     81                     mProfileTime += finalDelta;
     82                     mProfileFrames++;
     83                     if (mProfileTime > PROFILE_REPORT_DELAY * 1000) {
     84                         final long averageFrameTime = mProfileTime / mProfileFrames;
     85                         DebugLog.d("Game Profile", "Average: " + averageFrameTime);
     86                         mGameRoot.sSystemRegistry.hudSystem.setFPS((int)(1000 * mProfileFrames / mProfileTime));
     87                         mProfileTime = 0;
     88                         mProfileFrames = 0;
     89                     }
     90                 }
     91                 // If the game logic completed in less than 16ms, that means it's running
     92                 // faster than 60fps, which is our target frame rate.  In that case we should
     93                 // yield to the rendering thread, at least for the remaining frame.
     94 
     95                 if (finalDelta < 16) {
     96                     try {
     97                         Thread.sleep(16 - finalDelta);
     98                     } catch (InterruptedException e) {
     99                         // Interruptions here are no big deal.
    100                     }
    101                 }
    102 
    103                 synchronized(mPauseLock) {
    104                     if (mPaused) {
    105                     	SoundSystem sound = BaseObject.sSystemRegistry.soundSystem;
    106                     	if (sound != null) {
    107                     		sound.pauseAll();
    108                     		BaseObject.sSystemRegistry.inputSystem.releaseAllKeys();
    109                     	}
    110                         while (mPaused) {
    111                             try {
    112                             	mPauseLock.wait();
    113                             } catch (InterruptedException e) {
    114                                 // No big deal if this wait is interrupted.
    115                             }
    116                         }
    117                     }
    118                 }
    119             }
    120         }
    121         // Make sure our dependence on the render system is cleaned up.
    122         BaseObject.sSystemRegistry.renderSystem.emptyQueues(mRenderer);
    123     }
    124 
    125     public void stopGame() {
    126     	synchronized (mPauseLock) {
    127             mPaused = false;
    128             mFinished = true;
    129             mPauseLock.notifyAll();
    130     	}
    131     }
    132 
    133     public void pauseGame() {
    134         synchronized (mPauseLock) {
    135             mPaused = true;
    136         }
    137     }
    138 
    139     public void resumeGame() {
    140         synchronized (mPauseLock) {
    141             mPaused = false;
    142             mPauseLock.notifyAll();
    143         }
    144     }
    145 
    146     public boolean getPaused() {
    147         return mPaused;
    148     }
    149 
    150     public void setGameRoot(ObjectManager gameRoot) {
    151         mGameRoot = gameRoot;
    152     }
    153 
    154 }
    155