mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2024-12-28 09:58:30 +01:00
add basic framework to collect metadata prior to saving open game
(e.g. number of moves) and display it in game list. What to save and how to display it still not finalized but it works.
This commit is contained in:
parent
aa8b6ac7e6
commit
812262e41d
9 changed files with 222 additions and 22 deletions
|
@ -917,6 +917,20 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1receiveMessage
|
|||
return result;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_game_1summarize
|
||||
( JNIEnv* env, jclass C, jint gamePtr, jobject jsummary )
|
||||
{
|
||||
LOG_FUNC();
|
||||
XWJNI_START();
|
||||
XP_S16 nMoves = model_getNMoves( state->game.model );
|
||||
setInt( env, jsummary, "nMoves", nMoves );
|
||||
setBool( env, jsummary, "gameOver",
|
||||
server_getGameIsOver( state->game.server ) );
|
||||
XWJNI_END();
|
||||
LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_board_1prefsChanged
|
||||
( JNIEnv* env, jclass C, jint gamePtr, jobject jcp )
|
||||
|
|
|
@ -351,6 +351,13 @@ public class BoardActivity extends Activity implements UtilCtxt {
|
|||
return super.onKeyUp( keyCode, event );
|
||||
}
|
||||
|
||||
|
||||
// onDestroy may be the wrong place to do this.
|
||||
// onWindowFocusChanged seems to be getting called in GamesList
|
||||
// before this function, and so the list item corresponding to
|
||||
// this game isn't necessarily up-to-date. But if move e.g. to
|
||||
// onStop() then onStart() needs to be prepared to reconstitute
|
||||
// everything.
|
||||
@Override
|
||||
protected void onDestroy()
|
||||
{
|
||||
|
@ -366,8 +373,11 @@ public class BoardActivity extends Activity implements UtilCtxt {
|
|||
|
||||
// This has to happen after the drawing thread is killed
|
||||
// to avoid the possibility of reentering the jni world.
|
||||
GameSummary summary = new GameSummary();
|
||||
XwJNI.game_summarize( m_jniGamePtr, summary );
|
||||
byte[] state = XwJNI.game_saveToStream( m_jniGamePtr, null );
|
||||
Utils.saveGame( this, state, m_path );
|
||||
Utils.saveSummary( m_path, summary );
|
||||
|
||||
XwJNI.game_dispose( m_jniGamePtr );
|
||||
m_jniGamePtr = 0;
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
/* -*- compile-command: "cd ../../../../../; ant install"; -*- */
|
||||
/*
|
||||
* Copyright 2009-2010 by Eric House (xwords@eehouse.org). All
|
||||
* rights reserved.
|
||||
*
|
||||
* 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 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
package org.eehouse.android.xw4;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
|
||||
public class DBHelper extends SQLiteOpenHelper {
|
||||
|
||||
public static final String TABLE_NAME = "summaries";
|
||||
private static final String DB_NAME = "xwdb";
|
||||
private static final int DB_VERSION = 1;
|
||||
|
||||
public static final String FILE_NAME = "FILE_NAME";
|
||||
public static final String NUM_MOVES = "NUM_MOVES";
|
||||
public static final String GAME_OVER = "GAME_OVER";
|
||||
public static final String SNAPSHOT = "SNAPSHOT";
|
||||
|
||||
public DBHelper( Context context )
|
||||
{
|
||||
super( context, DB_NAME, null, DB_VERSION );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate( SQLiteDatabase db )
|
||||
{
|
||||
db.execSQL( "CREATE TABLE " + TABLE_NAME + " ("
|
||||
+ FILE_NAME + " TEXT PRIMARY KEY,"
|
||||
+ NUM_MOVES + " INTEGER,"
|
||||
+ GAME_OVER + " INTEGER,"
|
||||
+ SNAPSHOT + " BLOB,"
|
||||
+ ");" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade( SQLiteDatabase db, int oldVersion, int newVersion )
|
||||
{
|
||||
Utils.logf( "onUpgrade: old: %d; new: %d", oldVersion, newVersion );
|
||||
}
|
||||
}
|
|
@ -522,8 +522,8 @@ public class GameConfig extends Activity implements View.OnClickListener {
|
|||
boolean consumed = false;
|
||||
if ( keyCode == KeyEvent.KEYCODE_BACK ) {
|
||||
saveChanges();
|
||||
if ( 0 < m_nMoves && (m_giOrig.changesMatter(m_gi)
|
||||
|| m_carOrig.changesMatter(m_car) ) ) {
|
||||
if ( 0 <= m_nMoves && (m_giOrig.changesMatter(m_gi)
|
||||
|| m_carOrig.changesMatter(m_car) ) ) {
|
||||
showDialog( CONFIRM_CHANGE );
|
||||
consumed = true;
|
||||
} else {
|
||||
|
@ -782,6 +782,11 @@ public class GameConfig extends Activity implements View.OnClickListener {
|
|||
}
|
||||
|
||||
Utils.saveGame( this, gamePtr, m_gi, m_path );
|
||||
|
||||
GameSummary summary = new GameSummary();
|
||||
XwJNI.game_summarize( gamePtr, summary );
|
||||
Utils.saveSummary( m_path, summary );
|
||||
|
||||
XwJNI.game_dispose( gamePtr );
|
||||
}
|
||||
|
||||
|
|
|
@ -51,14 +51,35 @@ public class GameListAdapter implements ListAdapter {
|
|||
return Utils.gamesList(m_context).length;
|
||||
}
|
||||
|
||||
public Object getItem( int position ) {
|
||||
public Object getItem( int position )
|
||||
{
|
||||
TextView view = new TextView(m_context);
|
||||
byte[] stream = open( Utils.gamesList(m_context)[position] );
|
||||
String path = Utils.gamesList(m_context)[position];
|
||||
byte[] stream = open( path );
|
||||
if ( null != stream ) {
|
||||
CurGameInfo gi = new CurGameInfo( m_context );
|
||||
XwJNI.gi_from_stream( gi, stream );
|
||||
|
||||
view.setText( gi.summary(m_context) );
|
||||
String summaryTxt = gi.summary( m_context );
|
||||
|
||||
GameSummary summary = Utils.getSummary( m_context, path );
|
||||
if ( null != summary ) {
|
||||
String state = "\nState: ";
|
||||
if ( summary.nMoves < 0 ) {
|
||||
state += "Configured";
|
||||
} else if ( summary.gameOver ) {
|
||||
state += "Game over";
|
||||
} else {
|
||||
state += "In play";
|
||||
}
|
||||
summaryTxt += state;
|
||||
|
||||
if ( summary.nMoves >= 0 ) {
|
||||
summaryTxt += String.format( " Moves played: %d",
|
||||
summary.nMoves );
|
||||
}
|
||||
}
|
||||
view.setText( summaryTxt );
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
|
|
@ -42,8 +42,6 @@ import junit.framework.Assert;
|
|||
|
||||
import org.eehouse.android.xw4.jni.*;
|
||||
|
||||
import org.eehouse.android.xw4.XWords4.Games; // for constants
|
||||
|
||||
public class GamesList extends ListActivity implements View.OnClickListener {
|
||||
private GameListAdapter m_adapter;
|
||||
|
||||
|
@ -102,13 +100,6 @@ public class GamesList extends ListActivity implements View.OnClickListener {
|
|||
Button newGameB = (Button)findViewById(R.id.new_game);
|
||||
newGameB.setOnClickListener( this );
|
||||
|
||||
// If no data was given in the intent (because we were started
|
||||
// as a MAIN activity), then use our default content provider.
|
||||
Intent intent = getIntent();
|
||||
if (intent.getData() == null) {
|
||||
intent.setData(Games.CONTENT_URI);
|
||||
}
|
||||
|
||||
m_adapter = new GameListAdapter( this );
|
||||
setListAdapter( m_adapter );
|
||||
}
|
||||
|
@ -124,7 +115,8 @@ public class GamesList extends ListActivity implements View.OnClickListener {
|
|||
|
||||
@Override
|
||||
public void onCreateContextMenu( ContextMenu menu, View view,
|
||||
ContextMenuInfo menuInfo ) {
|
||||
ContextMenuInfo menuInfo )
|
||||
{
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate( R.menu.games_list_item_menu, menu );
|
||||
}
|
||||
|
@ -147,6 +139,7 @@ public class GamesList extends ListActivity implements View.OnClickListener {
|
|||
int id = item.getItemId();
|
||||
|
||||
if ( R.id.list_item_delete == id ) {
|
||||
Utils.saveSummary( path, null );
|
||||
if ( ! deleteFile( path ) ) {
|
||||
Utils.logf( "unable to delete " + path );
|
||||
}
|
||||
|
@ -169,14 +162,17 @@ public class GamesList extends ListActivity implements View.OnClickListener {
|
|||
|
||||
case R.id.list_item_reset:
|
||||
Utils.resetGame( this, path, path );
|
||||
Utils.saveSummary( path, null );
|
||||
break;
|
||||
case R.id.list_item_new_from:
|
||||
Utils.resetGame( this, path );
|
||||
String newName = Utils.resetGame( this, path );
|
||||
Utils.saveSummary( newName, null );
|
||||
break;
|
||||
|
||||
case R.id.list_item_copy:
|
||||
stream = Utils.savedGame( this, path );
|
||||
Utils.saveGame( this, stream );
|
||||
newName = Utils.saveGame( this, stream );
|
||||
Utils.saveSummary( newName, Utils.getSummary( this, path ) );
|
||||
break;
|
||||
|
||||
// These require some notion of predictable sort order.
|
||||
|
|
|
@ -32,6 +32,7 @@ import java.io.BufferedInputStream;
|
|||
import java.io.BufferedOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import android.content.res.AssetManager;
|
||||
import android.content.ContentValues;
|
||||
import android.os.Environment;
|
||||
import java.io.InputStream;
|
||||
import android.widget.CheckBox;
|
||||
|
@ -46,6 +47,9 @@ import java.util.Formatter;
|
|||
import android.view.LayoutInflater;
|
||||
import android.net.Uri;
|
||||
import junit.framework.Assert;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.database.Cursor;
|
||||
|
||||
import org.eehouse.android.xw4.jni.*;
|
||||
|
||||
|
@ -54,8 +58,10 @@ public class Utils {
|
|||
|
||||
static final int DIALOG_ABOUT = 1;
|
||||
static final int DIALOG_LAST = DIALOG_ABOUT;
|
||||
static final String DB_PATH = "XW_GAMES";
|
||||
|
||||
private static Time s_time = new Time();
|
||||
private static SQLiteOpenHelper m_dbHelper = null;
|
||||
|
||||
private Utils() {}
|
||||
|
||||
|
@ -164,9 +170,11 @@ public class Utils {
|
|||
return al.toArray( new String[al.size()] );
|
||||
}
|
||||
|
||||
public static void resetGame( Context context, String pathIn )
|
||||
public static String resetGame( Context context, String pathIn )
|
||||
{
|
||||
resetGame( context, pathIn, newName( context ) );
|
||||
String newName = newName( context );
|
||||
resetGame( context, pathIn, newName );
|
||||
return newName;
|
||||
}
|
||||
|
||||
public static void loadMakeGame( Context context, int gamePtr,
|
||||
|
@ -211,9 +219,11 @@ public class Utils {
|
|||
}
|
||||
}
|
||||
|
||||
public static void saveGame( Context context, byte[] bytes )
|
||||
public static String saveGame( Context context, byte[] bytes )
|
||||
{
|
||||
saveGame( context, bytes, newName( context ) );
|
||||
String name = newName( context );
|
||||
saveGame( context, bytes, name );
|
||||
return name;
|
||||
}
|
||||
|
||||
public static boolean gameDictHere( Context context, String path,
|
||||
|
@ -436,6 +446,30 @@ public class Utils {
|
|||
}
|
||||
}
|
||||
|
||||
public static GameSummary getSummary( Context context, String file )
|
||||
{
|
||||
initDB( context );
|
||||
|
||||
GameSummary summary = new GameSummary();
|
||||
SQLiteDatabase db = m_dbHelper.getReadableDatabase();
|
||||
|
||||
String[] columns = { DBHelper.NUM_MOVES, DBHelper.GAME_OVER };
|
||||
String selection = DBHelper.FILE_NAME + "=\"" + file + "\"";
|
||||
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME, columns, selection,
|
||||
null, null, null, null );
|
||||
if ( 1 == cursor.getCount() && cursor.moveToFirst() ) {
|
||||
summary = new GameSummary();
|
||||
summary.nMoves = cursor.getInt(cursor.
|
||||
getColumnIndex(DBHelper.NUM_MOVES));
|
||||
int tmp = cursor.getInt(cursor.
|
||||
getColumnIndex(DBHelper.GAME_OVER));
|
||||
summary.gameOver = tmp == 0 ? false : true;
|
||||
}
|
||||
db.close();
|
||||
return summary;
|
||||
}
|
||||
|
||||
private static boolean isGame( String file )
|
||||
{
|
||||
return file.endsWith( XWConstants.GAME_EXTN );
|
||||
|
@ -446,4 +480,35 @@ public class Utils {
|
|||
return file.endsWith( XWConstants.DICT_EXTN );
|
||||
}
|
||||
|
||||
private static void initDB( Context context )
|
||||
{
|
||||
if ( null == m_dbHelper ) {
|
||||
m_dbHelper = new DBHelper( context );
|
||||
}
|
||||
}
|
||||
|
||||
public static void saveSummary( String path, GameSummary summary )
|
||||
{
|
||||
SQLiteDatabase db = m_dbHelper.getWritableDatabase();
|
||||
|
||||
if ( null == summary ) {
|
||||
String selection = DBHelper.FILE_NAME + "=\"" + path + "\"";
|
||||
db.delete( DBHelper.TABLE_NAME, selection, null );
|
||||
} else {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put( DBHelper.FILE_NAME, path );
|
||||
values.put( DBHelper.NUM_MOVES, summary.nMoves );
|
||||
values.put( DBHelper.GAME_OVER, summary.gameOver );
|
||||
|
||||
Utils.logf( "saveSummary: nMoves=%d", summary.nMoves );
|
||||
|
||||
try {
|
||||
long result = db.replaceOrThrow( DBHelper.TABLE_NAME, "", values );
|
||||
} catch ( Exception ex ) {
|
||||
Utils.logf( "ex: %s", ex.toString() );
|
||||
}
|
||||
}
|
||||
db.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/* -*- compile-command: "cd ../../../../../../; ant install"; -*- */
|
||||
/*
|
||||
* Copyright 2009-2010 by Eric House (xwords@eehouse.org). All
|
||||
* rights reserved.
|
||||
*
|
||||
* 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 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
package org.eehouse.android.xw4.jni;
|
||||
|
||||
/** Info we want to access when the game's closed that's not available
|
||||
* in CurGameInfo
|
||||
*/
|
||||
public class GameSummary {
|
||||
public int nMoves;
|
||||
public boolean gameOver;
|
||||
}
|
|
@ -84,8 +84,9 @@ public class XwJNI {
|
|||
|
||||
public static native boolean game_receiveMessage( int gamePtr,
|
||||
byte[] stream );
|
||||
public static native void game_summarize( int gamePtr, GameSummary summary );
|
||||
public static native byte[] game_saveToStream( int gamePtr,
|
||||
CurGameInfo gi );
|
||||
CurGameInfo gi );
|
||||
public static native boolean game_hasComms( int gamePtr );
|
||||
public static native void game_dispose( int gamePtr );
|
||||
|
||||
|
|
Loading…
Reference in a new issue