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 java.io.InputStream;
|
||||
import android.os.Handler;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileInputStream;
|
||||
import android.content.res.Configuration;
|
||||
|
||||
import org.eehouse.android.xw4.jni.*;
|
||||
|
||||
public class BoardActivity extends Activity implements XW_UtilCtxt, Runnable {
|
||||
|
||||
private static final String CUR_GAME = "cur_game";
|
||||
|
||||
private BoardView m_view;
|
||||
private int m_jniGamePtr;
|
||||
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
|
||||
|
||||
Utils.logf( "calling game_makeNewGame; passing bytes: " + dictBytes.length );
|
||||
m_jniGamePtr = XwJNI.game_makeNewGame( m_gi, this, m_view, 0,
|
||||
m_jniGamePtr = XwJNI.initJNI();
|
||||
|
||||
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_view.startHandling( this, m_jniGamePtr, m_gi );
|
||||
|
||||
XwJNI.server_do( m_jniGamePtr );
|
||||
} // onCreate
|
||||
|
||||
protected void onPause() {
|
||||
// save state here
|
||||
saveGame();
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
protected void onDestroy()
|
||||
|
@ -106,7 +124,6 @@ public class BoardActivity extends Activity implements XW_UtilCtxt, Runnable {
|
|||
return draw;
|
||||
}
|
||||
|
||||
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
boolean draw = false;
|
||||
boolean handled = true;
|
||||
|
@ -152,6 +169,39 @@ public class BoardActivity extends Activity implements XW_UtilCtxt, Runnable {
|
|||
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
|
||||
// android:configChanges="orientation" set in AndroidManifest.xml
|
||||
|
||||
|
|
|
@ -19,9 +19,25 @@ public class XwJNI {
|
|||
int when, int handle );
|
||||
|
||||
// Game methods
|
||||
public static native int game_makeNewGame( CurGameInfo gi, XW_UtilCtxt util,
|
||||
DrawCtx draw, int gameID, CommonPrefs cp,
|
||||
TransportProcs procs, byte[] dict );
|
||||
public static native int initJNI();
|
||||
public static native void game_makeNewGame( int gamePtr,
|
||||
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 );
|
||||
|
||||
// Board methods
|
||||
|
|
|
@ -21,7 +21,6 @@ makeGI( MPFORMAL JNIEnv* env, jobject j_gi )
|
|||
{
|
||||
CurGameInfo* gi = (CurGameInfo*)XP_CALLOC( mpool, sizeof(*gi) );
|
||||
int nPlayers, robotSmartness, boardSize;
|
||||
int ii;
|
||||
XP_UCHAR buf[256]; /* in case needs whole path */
|
||||
|
||||
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",
|
||||
"[Lorg/eehouse/android/xw4/jni/LocalPlayer;",
|
||||
&jplayers ) ) {
|
||||
int ii;
|
||||
for ( ii = 0; ii < gi->nPlayers; ++ii ) {
|
||||
LocalPlayer* lp = &gi->players[ii];
|
||||
|
||||
|
@ -74,6 +74,45 @@ makeGI( MPFORMAL JNIEnv* env, jobject j_gi )
|
|||
return gi;
|
||||
} /* 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
|
||||
destroyGI( MPFORMAL CurGameInfo* gi )
|
||||
{
|
||||
|
@ -92,11 +131,6 @@ loadCommonPrefs( JNIEnv* env, CommonPrefs* cp, jobject j_cp )
|
|||
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 {
|
||||
XWGame game;
|
||||
AndGlobals* globals;
|
||||
|
@ -104,19 +138,30 @@ typedef struct _GameAndMPool {
|
|||
} GameAndMPool;
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeNewGame
|
||||
( JNIEnv *env, jclass C, jobject j_gi, jobject j_util, jobject j_draw,
|
||||
jint gameID, jobject j_cp, jobject j_procs, jbyteArray jDictBytes )
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_initJNI
|
||||
( JNIEnv* env, jclass C )
|
||||
{
|
||||
LOG_FUNC();
|
||||
MemPoolCtx* mpool = mpool_make();
|
||||
|
||||
GameAndMPool* game = XP_MALLOC( mpool, sizeof(*game) );
|
||||
GameAndMPool* game = (GameAndMPool*)XP_CALLOC( mpool, sizeof(*game) );
|
||||
AndGlobals* globals = XP_MALLOC( mpool, sizeof( *globals ) );
|
||||
game->mpool = mpool;
|
||||
game->globals = globals;
|
||||
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 );
|
||||
globals->gi = gi;
|
||||
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
|
||||
XP_ASSERT( !!dict );
|
||||
|
||||
globals->dict = dict;
|
||||
model_setDictionary( game->game.model, dict );
|
||||
|
||||
return (jint) game;
|
||||
} /* 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
|
||||
( JNIEnv * env, jclass claz, jint gamePtr )
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue