Android Open Source - droidoflife Main Activity






From Project

Back to project page droidoflife.

License

The source code is released under:

GNU General Public License

If you think the Android project droidoflife listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/******************************************************************************
 *  Droid of Life, an open source Android game based on Conway's Game of Life *
 *  Copyright (C) 2012  Christian Ulrich <chrulri@gmail.com>                  *
 *                                                                            *
 *  This program is free software: you can redistribute it and/or modify      *
 *  it under the terms of the GNU General Public License as published by      *
 *  the Free Software Foundation, either version 3 of the License, or         *
 *  (at your option) any later version.                                       *
 *                                                                            *
 *  This program is distributed in the hope that it will be useful,           *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of            *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
 *  GNU General Public License for more details.                              *
 *                                                                            *
 *  You should have received a copy of the GNU General Public License         *
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.     *
 ******************************************************************************/
package com.chrulri.droidoflife;
/* ww w.  j a va2s.c  om*/
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.PowerManager;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.Menu;
import android.support.v4.view.MenuItem;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;

import com.chrulri.droidoflife.LifeRuntime.LifeRuntimeException;

public class MainActivity extends FragmentActivity {
  static final String TAG = MainActivity.class.getSimpleName();

  static final int RESULT_SETTINGS = 0xF0;

  static final long ITERATION_DELAY_MS = 100;

  private IterationTask iterationTask;
  private SurfaceHolder surface;
  private Bitmap bitmap;
  private int settingsCache;

  private void refreshTitle() {
    String title = "" + getText(R.string.app_name);
    // append iteration
    int iteration = LifeRuntime.getIteration();
    if (iteration > 0) {
      title += " (#" + iteration + ")";
    }
    // append automatic mode
    if (iterationTask != null) {
      title += " - " + getText(R.string.auto_short);
    }
    setTitle(title);
  }
  
  private void restartRuntime() {
    if(bitmap != null) {
      LifeRuntime.destroy();
    }

    // TODO ask for width/height
    final int width = 200;
    final int height = 100;

    try {
      LifeRuntime.create(width, height);
    } catch (LifeRuntimeException e) {
      e.printStackTrace();
      // TODO show error

      // emergency exit
      finish();
      return;
    }

    bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

    refreshTitle();
  }

  private boolean doIteration() {
    try {
      LifeRuntime.iterate();
      doRender();
    } catch (IllegalAccessException e) {
      Log.e(TAG, "error on iteration", e);
      return false;
    }
    return true;
  }

  private void doRender() {
    if(bitmap == null) {
      // bitmap not ready yet, wtf?!
      Log.w(TAG, "bitmap is null");
      return;
    }

    Canvas canvas = surface.lockCanvas();
    if(canvas == null) {
      // surface not ready yet, nothing to do!
      return;
    }

    LifeRuntime.render(bitmap, settingsCache);

    Rect dst = surface.getSurfaceFrame();
    canvas.drawBitmap(bitmap, null, dst, null);

    surface.unlockCanvasAndPost(canvas);
  }

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    getSupportActionBar().setDisplayShowHomeEnabled(false);

    settingsCache = SettingsActivity.loadSettings(this);

    SurfaceView view = (SurfaceView) findViewById(R.id.main_surfaceView);
    surface = view.getHolder();

    restartRuntime();

    view.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
        // disable iteration task for manual mode
        if (iterationTask != null) {
          iterationTask.cancel(false);
          iterationTask = null;
        } else {
          doIteration();
        }
        refreshTitle();
      }
    });
    surface.addCallback(new SurfaceHolder.Callback() {
      @Override
      public void surfaceChanged(SurfaceHolder holder, int format,
          int width, int height) {
        doRender();
      }

      @Override
      public void surfaceCreated(SurfaceHolder holder) {
        doRender();
      }

      @Override
      public void surfaceDestroyed(SurfaceHolder holder) {
        // ignore
      }
      
    });

    refreshTitle();

    // Manual
    // TODO show manual
  }

  @Override
  protected void onResume() {
    super.onResume();
    // restart iteration
    if (iterationTask != null) {
      iterationTask = new IterationTask();
      iterationTask.execute();
    }
  }

  @Override
  protected void onPause() {
    super.onPause();
    // pause iteration
    if (iterationTask != null) {
      iterationTask.cancel(false);
    }
  }

  @Override
  protected void onDestroy() {
    super.onDestroy();
    // remove iteration task
    iterationTask = null;
    surface = null;
    bitmap = null;
    // destroy life with a nuclear bomb (!!)
    LifeRuntime.destroy();
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return super.onCreateOptionsMenu(menu);
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch(item.getItemId()) {
    case R.id.mi_automatic:
      // toggle automatic mode
      if (iterationTask == null) {
        iterationTask = new IterationTask();
        iterationTask.execute();
      } else {
        iterationTask.cancel(false);
        iterationTask = null;
      }
      refreshTitle();
      return true;
    case R.id.mi_restart:
      // restart game of life
      restartRuntime();
      doRender();
      return true;
    case R.id.mi_settings:
      // open settings activity
      startActivityForResult(new Intent(this, SettingsActivity.class), RESULT_SETTINGS);
      return true;
    case R.id.mi_help:
      // open help dialog
      DialogFragment help = new HelpDialogFragment();
      help.show(getSupportFragmentManager(), null);
      return true;
    case R.id.mi_about:
      // open about dialog
      DialogFragment about = new AboutDialogFragment();
      about.show(getSupportFragmentManager(), null);
      return true;
    }
    return super.onOptionsItemSelected(item);
  }

  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch(requestCode) {
    case RESULT_SETTINGS:
      settingsCache = SettingsActivity.loadSettings(this);
      break;
    default:
      super.onActivityResult(requestCode, resultCode, data);
    }
  }

  class IterationTask extends AsyncTask<Void, Void, Void> {
    
    @Override
    protected void onProgressUpdate(Void... values) {
      refreshTitle();
    }

    @Override
    protected Void doInBackground(Void... params) {
      PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
      PowerManager.WakeLock wakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, TAG);
      wakeLock.acquire();
      try {
        while (!isCancelled()) {
          // new generation ready, hurray!
          if(!doIteration()) {
            // exit on error
            return null;
          }
          // tell everyone
          publishProgress();
          // sleep for next generation
          try {
            Thread.sleep(ITERATION_DELAY_MS);
          } catch (InterruptedException e) {
            // ignore
          }
        }
        return null;
      } finally {
        wakeLock.release();
      }
    }

    @Override
    protected void onPostExecute(Void result) {
      // clean exit on error
      iterationTask = null;
    }
  }
}




Java Source Code List

com.chrulri.droidoflife.AboutDialogFragment.java
com.chrulri.droidoflife.HelpDialogFragment.java
com.chrulri.droidoflife.LifeRuntime.java
com.chrulri.droidoflife.MainActivity.java
com.chrulri.droidoflife.SettingsActivity.java