mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-16 15:41:16 +01:00
save and restore games (though there's a global game for now).
This commit is contained in:
parent
5d9dc49bf0
commit
a91f662327
3 changed files with 191 additions and 23 deletions
|
@ -11,12 +11,16 @@ import android.view.MenuInflater;
|
||||||
import android.content.res.AssetManager;
|
import android.content.res.AssetManager;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.FileInputStream;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
|
|
||||||
import org.eehouse.android.xw4.jni.*;
|
import org.eehouse.android.xw4.jni.*;
|
||||||
|
|
||||||
public class BoardActivity extends Activity implements XW_UtilCtxt, Runnable {
|
public class BoardActivity extends Activity implements XW_UtilCtxt, Runnable {
|
||||||
|
|
||||||
|
private static final String CUR_GAME = "cur_game";
|
||||||
|
|
||||||
private BoardView m_view;
|
private BoardView m_view;
|
||||||
private int m_jniGamePtr;
|
private int m_jniGamePtr;
|
||||||
private CurGameInfo m_gi;
|
private CurGameInfo m_gi;
|
||||||
|
@ -73,12 +77,26 @@ public class BoardActivity extends Activity implements XW_UtilCtxt, Runnable {
|
||||||
}
|
}
|
||||||
// am.close(); don't close! won't work subsequently
|
// am.close(); don't close! won't work subsequently
|
||||||
|
|
||||||
Utils.logf( "calling game_makeNewGame; passing bytes: " + dictBytes.length );
|
m_jniGamePtr = XwJNI.initJNI();
|
||||||
m_jniGamePtr = XwJNI.game_makeNewGame( m_gi, this, m_view, 0,
|
|
||||||
|
byte[] stream = savedGame();
|
||||||
|
if ( null == stream ||
|
||||||
|
! XwJNI.game_makeFromStream( m_jniGamePtr, stream,
|
||||||
|
m_gi, dictBytes, this,
|
||||||
|
m_view, m_prefs,
|
||||||
|
null ) ) {
|
||||||
|
XwJNI.game_makeNewGame( m_jniGamePtr, m_gi, this, m_view, 0,
|
||||||
m_prefs, null, dictBytes );
|
m_prefs, null, dictBytes );
|
||||||
|
}
|
||||||
m_view.startHandling( this, m_jniGamePtr, m_gi );
|
m_view.startHandling( this, m_jniGamePtr, m_gi );
|
||||||
|
|
||||||
XwJNI.server_do( m_jniGamePtr );
|
XwJNI.server_do( m_jniGamePtr );
|
||||||
|
} // onCreate
|
||||||
|
|
||||||
|
protected void onPause() {
|
||||||
|
// save state here
|
||||||
|
saveGame();
|
||||||
|
super.onPause();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onDestroy()
|
protected void onDestroy()
|
||||||
|
@ -106,7 +124,6 @@ public class BoardActivity extends Activity implements XW_UtilCtxt, Runnable {
|
||||||
return draw;
|
return draw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
boolean draw = false;
|
boolean draw = false;
|
||||||
boolean handled = true;
|
boolean handled = true;
|
||||||
|
@ -152,6 +169,39 @@ public class BoardActivity extends Activity implements XW_UtilCtxt, Runnable {
|
||||||
return handled;
|
return handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void saveGame()
|
||||||
|
{
|
||||||
|
byte[] state = XwJNI.game_saveToStream( m_jniGamePtr, m_gi );
|
||||||
|
|
||||||
|
try {
|
||||||
|
FileOutputStream out = openFileOutput( CUR_GAME, MODE_PRIVATE );
|
||||||
|
out.write( state );
|
||||||
|
out.close();
|
||||||
|
} catch ( java.io.IOException ex ) {
|
||||||
|
Utils.logf( "got IOException: " + ex.toString() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] savedGame()
|
||||||
|
{
|
||||||
|
byte[] stream = null;
|
||||||
|
try {
|
||||||
|
FileInputStream in = openFileInput( CUR_GAME );
|
||||||
|
int len = in.available();
|
||||||
|
Utils.logf( "savedGame: got " + len + " bytes." );
|
||||||
|
stream = new byte[len];
|
||||||
|
in.read( stream, 0, len );
|
||||||
|
in.close();
|
||||||
|
} catch ( java.io.FileNotFoundException fnf ) {
|
||||||
|
Utils.logf( fnf.toString() );
|
||||||
|
stream = null;
|
||||||
|
} catch ( java.io.IOException io ) {
|
||||||
|
Utils.logf( io.toString() );
|
||||||
|
stream = null;
|
||||||
|
}
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
// gets called for orientation changes only if
|
// gets called for orientation changes only if
|
||||||
// android:configChanges="orientation" set in AndroidManifest.xml
|
// android:configChanges="orientation" set in AndroidManifest.xml
|
||||||
|
|
||||||
|
|
|
@ -19,9 +19,25 @@ public class XwJNI {
|
||||||
int when, int handle );
|
int when, int handle );
|
||||||
|
|
||||||
// Game methods
|
// Game methods
|
||||||
public static native int game_makeNewGame( CurGameInfo gi, XW_UtilCtxt util,
|
public static native int initJNI();
|
||||||
DrawCtx draw, int gameID, CommonPrefs cp,
|
public static native void game_makeNewGame( int gamePtr,
|
||||||
TransportProcs procs, byte[] dict );
|
CurGameInfo gi,
|
||||||
|
XW_UtilCtxt util,
|
||||||
|
DrawCtx draw, int gameID,
|
||||||
|
CommonPrefs cp,
|
||||||
|
TransportProcs procs,
|
||||||
|
byte[] dict );
|
||||||
|
public static native boolean game_makeFromStream( int gamePtr,
|
||||||
|
byte[] stream,
|
||||||
|
CurGameInfo gi,
|
||||||
|
byte[] dict,
|
||||||
|
XW_UtilCtxt util,
|
||||||
|
DrawCtx draw,
|
||||||
|
CommonPrefs cp,
|
||||||
|
TransportProcs procs );
|
||||||
|
|
||||||
|
public static native byte[] game_saveToStream( int gamePtr,
|
||||||
|
CurGameInfo gi );
|
||||||
public static native void game_dispose( int gamePtr );
|
public static native void game_dispose( int gamePtr );
|
||||||
|
|
||||||
// Board methods
|
// Board methods
|
||||||
|
|
|
@ -21,7 +21,6 @@ makeGI( MPFORMAL JNIEnv* env, jobject j_gi )
|
||||||
{
|
{
|
||||||
CurGameInfo* gi = (CurGameInfo*)XP_CALLOC( mpool, sizeof(*gi) );
|
CurGameInfo* gi = (CurGameInfo*)XP_CALLOC( mpool, sizeof(*gi) );
|
||||||
int nPlayers, robotSmartness, boardSize;
|
int nPlayers, robotSmartness, boardSize;
|
||||||
int ii;
|
|
||||||
XP_UCHAR buf[256]; /* in case needs whole path */
|
XP_UCHAR buf[256]; /* in case needs whole path */
|
||||||
|
|
||||||
bool success = getInt( env, j_gi, "nPlayers", &nPlayers )
|
bool success = getInt( env, j_gi, "nPlayers", &nPlayers )
|
||||||
|
@ -49,6 +48,7 @@ makeGI( MPFORMAL JNIEnv* env, jobject j_gi )
|
||||||
if ( getObject( env, j_gi, "players",
|
if ( getObject( env, j_gi, "players",
|
||||||
"[Lorg/eehouse/android/xw4/jni/LocalPlayer;",
|
"[Lorg/eehouse/android/xw4/jni/LocalPlayer;",
|
||||||
&jplayers ) ) {
|
&jplayers ) ) {
|
||||||
|
int ii;
|
||||||
for ( ii = 0; ii < gi->nPlayers; ++ii ) {
|
for ( ii = 0; ii < gi->nPlayers; ++ii ) {
|
||||||
LocalPlayer* lp = &gi->players[ii];
|
LocalPlayer* lp = &gi->players[ii];
|
||||||
|
|
||||||
|
@ -74,6 +74,45 @@ makeGI( MPFORMAL JNIEnv* env, jobject j_gi )
|
||||||
return gi;
|
return gi;
|
||||||
} /* makeGI */
|
} /* makeGI */
|
||||||
|
|
||||||
|
static void
|
||||||
|
setJGI( JNIEnv* env, jobject jgi, const CurGameInfo* gi )
|
||||||
|
{
|
||||||
|
// set fields
|
||||||
|
bool success = setInt( env, jgi, "nPlayers", gi->nPlayers )
|
||||||
|
&& setInt( env, jgi, "boardSize", gi->boardSize )
|
||||||
|
&& setInt( env, jgi, "robotSmartness", gi->robotSmartness )
|
||||||
|
&& setBool( env, jgi, "hintsNotAllowed", gi->hintsNotAllowed )
|
||||||
|
&& setBool( env, jgi, "timerEnabled", gi->timerEnabled )
|
||||||
|
&& setBool( env, jgi, "allowPickTiles", gi->allowPickTiles )
|
||||||
|
&& setBool( env, jgi, "allowHintRect", gi->allowHintRect )
|
||||||
|
&& setString( env, jgi, "dictName", gi->dictName )
|
||||||
|
;
|
||||||
|
XP_ASSERT( success );
|
||||||
|
|
||||||
|
jobject jplayers;
|
||||||
|
if ( getObject( env, jgi, "players",
|
||||||
|
"[Lorg/eehouse/android/xw4/jni/LocalPlayer;",
|
||||||
|
&jplayers ) ) {
|
||||||
|
int ii;
|
||||||
|
for ( ii = 0; ii < gi->nPlayers; ++ii ) {
|
||||||
|
const LocalPlayer* lp = &gi->players[ii];
|
||||||
|
|
||||||
|
jobject jlp = (*env)->GetObjectArrayElement( env, jplayers, ii );
|
||||||
|
|
||||||
|
setBool( env, jlp, "isRobot", lp->isRobot );
|
||||||
|
setBool( env, jlp, "isLocal", lp->isLocal );
|
||||||
|
setString( env, jlp, "name", lp->name );
|
||||||
|
setString( env, jlp, "password", lp->password );
|
||||||
|
setInt( env, jlp, "secondsUsed", lp->secondsUsed );
|
||||||
|
|
||||||
|
(*env)->DeleteLocalRef( env, jlp );
|
||||||
|
}
|
||||||
|
(*env)->DeleteLocalRef( env, jplayers );
|
||||||
|
} else {
|
||||||
|
XP_ASSERT(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
destroyGI( MPFORMAL CurGameInfo* gi )
|
destroyGI( MPFORMAL CurGameInfo* gi )
|
||||||
{
|
{
|
||||||
|
@ -92,11 +131,6 @@ loadCommonPrefs( JNIEnv* env, CommonPrefs* cp, jobject j_cp )
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
generated by running:
|
|
||||||
(cd /home/andy/dev/XWORDS/android/XWords4/bin/classes; javah -o /tmp/foo.h org.eehouse.android.xw4.jni.XwJNI)
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct _GameAndMPool {
|
typedef struct _GameAndMPool {
|
||||||
XWGame game;
|
XWGame game;
|
||||||
AndGlobals* globals;
|
AndGlobals* globals;
|
||||||
|
@ -104,19 +138,30 @@ typedef struct _GameAndMPool {
|
||||||
} GameAndMPool;
|
} GameAndMPool;
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL
|
JNIEXPORT jint JNICALL
|
||||||
Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeNewGame
|
Java_org_eehouse_android_xw4_jni_XwJNI_initJNI
|
||||||
( JNIEnv *env, jclass C, jobject j_gi, jobject j_util, jobject j_draw,
|
( JNIEnv* env, jclass C )
|
||||||
jint gameID, jobject j_cp, jobject j_procs, jbyteArray jDictBytes )
|
|
||||||
{
|
{
|
||||||
LOG_FUNC();
|
|
||||||
MemPoolCtx* mpool = mpool_make();
|
MemPoolCtx* mpool = mpool_make();
|
||||||
|
GameAndMPool* game = (GameAndMPool*)XP_CALLOC( mpool, sizeof(*game) );
|
||||||
GameAndMPool* game = XP_MALLOC( mpool, sizeof(*game) );
|
|
||||||
AndGlobals* globals = XP_MALLOC( mpool, sizeof( *globals ) );
|
AndGlobals* globals = XP_MALLOC( mpool, sizeof( *globals ) );
|
||||||
game->mpool = mpool;
|
game->mpool = mpool;
|
||||||
game->globals = globals;
|
game->globals = globals;
|
||||||
globals->vtMgr = make_vtablemgr(MPPARM_NOCOMMA(mpool));
|
globals->vtMgr = make_vtablemgr(MPPARM_NOCOMMA(mpool));
|
||||||
|
|
||||||
|
return (jint) game;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL
|
||||||
|
Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeNewGame
|
||||||
|
( JNIEnv* env, jclass C, jint gamePtr, jobject j_gi, jobject j_util,
|
||||||
|
jobject j_draw, jint gameID, jobject j_cp, jobject j_procs,
|
||||||
|
jbyteArray jDictBytes )
|
||||||
|
{
|
||||||
|
LOG_FUNC();
|
||||||
|
GameAndMPool* game = (GameAndMPool*)gamePtr;
|
||||||
|
MemPoolCtx* mpool = game->mpool;
|
||||||
|
AndGlobals* globals = game->globals;
|
||||||
|
|
||||||
CurGameInfo* gi = makeGI( MPPARM(mpool) env, j_gi );
|
CurGameInfo* gi = makeGI( MPPARM(mpool) env, j_gi );
|
||||||
globals->gi = gi;
|
globals->gi = gi;
|
||||||
XW_UtilCtxt* util = makeUtil( MPPARM(mpool) env, j_util, gi, globals );
|
XW_UtilCtxt* util = makeUtil( MPPARM(mpool) env, j_util, gi, globals );
|
||||||
|
@ -142,13 +187,70 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeNewGame
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
XP_ASSERT( !!dict );
|
XP_ASSERT( !!dict );
|
||||||
|
|
||||||
globals->dict = dict;
|
|
||||||
model_setDictionary( game->game.model, dict );
|
model_setDictionary( game->game.model, dict );
|
||||||
|
|
||||||
return (jint) game;
|
|
||||||
} /* makeNewGame */
|
} /* makeNewGame */
|
||||||
|
|
||||||
|
JNIEXPORT jboolean JNICALL
|
||||||
|
Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeFromStream
|
||||||
|
( JNIEnv* env, jclass C, jint gamePtr, jbyteArray jstream,
|
||||||
|
jobject /*out*/jgi, jbyteArray jdict, jobject jutil, jobject jdraw,
|
||||||
|
jobject jcp, jobject jprocs )
|
||||||
|
{
|
||||||
|
GameAndMPool* game = (GameAndMPool*)gamePtr;
|
||||||
|
MemPoolCtx* mpool = game->mpool;
|
||||||
|
AndGlobals* globals = game->globals;
|
||||||
|
|
||||||
|
globals->gi = (CurGameInfo*)XP_CALLOC( mpool, sizeof(*globals->gi) );
|
||||||
|
DictionaryCtxt* dict = makeDict( MPPARM(mpool) env, jdict );
|
||||||
|
globals->util = makeUtil( MPPARM(mpool) env, jutil, globals->gi, globals );
|
||||||
|
globals->dctx = makeDraw( MPPARM(mpool) env, jdraw );
|
||||||
|
|
||||||
|
jbyte* jelems = (*env)->GetByteArrayElements( env, jstream, NULL );
|
||||||
|
XWStreamCtxt* stream = mem_stream_make( game->mpool, globals->vtMgr,
|
||||||
|
NULL, 0, NULL );
|
||||||
|
int len = (*env)->GetArrayLength( env, jstream );
|
||||||
|
XP_LOGF( "putting %d bytes into stream", len );
|
||||||
|
stream_putBytes( stream, jelems, len );
|
||||||
|
(*env)->ReleaseByteArrayElements( env, jstream, jelems, 0 );
|
||||||
|
|
||||||
|
CommonPrefs cp;
|
||||||
|
(void)loadCommonPrefs( env, &cp, jcp );
|
||||||
|
XP_Bool result = game_makeFromStream( mpool, stream, &game->game,
|
||||||
|
globals->gi, dict,
|
||||||
|
globals->util, globals->dctx, &cp,
|
||||||
|
NULL );
|
||||||
|
stream_destroy( stream );
|
||||||
|
|
||||||
|
setJGI( env, jgi, globals->gi );
|
||||||
|
|
||||||
|
LOG_RETURNF( "%s", result?"success":"failure" );
|
||||||
|
return result;
|
||||||
|
} /* makeFromStream */
|
||||||
|
|
||||||
|
JNIEXPORT jbyteArray JNICALL
|
||||||
|
Java_org_eehouse_android_xw4_jni_XwJNI_game_1saveToStream
|
||||||
|
( JNIEnv* env, jclass C, jint gamePtr, jobject jgi )
|
||||||
|
{
|
||||||
|
GameAndMPool* game = (GameAndMPool*)gamePtr;
|
||||||
|
AndGlobals* globals = game->globals;
|
||||||
|
|
||||||
|
CurGameInfo* gi = makeGI( MPPARM(game->mpool) env, jgi );
|
||||||
|
XWStreamCtxt* stream = mem_stream_make( game->mpool, globals->vtMgr,
|
||||||
|
NULL, 0, NULL );
|
||||||
|
game_saveToStream( &game->game, gi, stream );
|
||||||
|
destroyGI( MPPARM(game->mpool) gi );
|
||||||
|
|
||||||
|
int nBytes = stream_getSize( stream );
|
||||||
|
jbyteArray jarr = (*env)->NewByteArray( env, nBytes );
|
||||||
|
jbyte* jelems = (*env)->GetByteArrayElements( env, jarr, NULL );
|
||||||
|
stream_getBytes( stream, jelems, nBytes );
|
||||||
|
(*env)->ReleaseByteArrayElements( env, jarr, jelems, 0 );
|
||||||
|
stream_destroy( stream );
|
||||||
|
|
||||||
|
(*env)->DeleteLocalRef( env, jarr );
|
||||||
|
return jarr;
|
||||||
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_game_1dispose
|
JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_game_1dispose
|
||||||
( JNIEnv * env, jclass claz, jint gamePtr )
|
( JNIEnv * env, jclass claz, jint gamePtr )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue