mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2024-12-28 09:58:30 +01:00
add jni methods, and modify common code, so a CurGameInfo struct alone
can be read from and stored to a game file.
This commit is contained in:
parent
a3a313fdb4
commit
3beba51b6f
3 changed files with 144 additions and 58 deletions
|
@ -18,6 +18,10 @@ public class XwJNI {
|
|||
public static native boolean timerFired( int gamePtr, int why,
|
||||
int when, int handle );
|
||||
|
||||
// Stateless methods
|
||||
public static native byte[] gi_to_stream( CurGameInfo gi );
|
||||
public static native void gi_from_stream( CurGameInfo gi, byte[] stream );
|
||||
|
||||
// Game methods
|
||||
public static native int initJNI();
|
||||
public static native void game_makeNewGame( int gamePtr,
|
||||
|
|
|
@ -132,6 +132,77 @@ loadCommonPrefs( JNIEnv* env, CommonPrefs* cp, jobject j_cp )
|
|||
return success;
|
||||
}
|
||||
|
||||
/****************************************************
|
||||
* These two methods are stateless: no gamePtr
|
||||
****************************************************/
|
||||
JNIEXPORT jbyteArray JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_gi_1to_1stream
|
||||
(JNIEnv* env, jclass C, jobject jgi )
|
||||
{
|
||||
LOG_FUNC();
|
||||
jbyteArray result;
|
||||
#ifdef MEM_DEBUG
|
||||
MemPoolCtx* mpool = mpool_make();
|
||||
#endif
|
||||
CurGameInfo* gi = makeGI( MPPARM(mpool) env, jgi );
|
||||
VTableMgr* vtMgr = make_vtablemgr( MPPARM_NOCOMMA(mpool) );
|
||||
XWStreamCtxt* stream = mem_stream_make( MPPARM(mpool) vtMgr,
|
||||
NULL, 0, NULL );
|
||||
|
||||
game_saveToStream( NULL, gi, stream );
|
||||
destroyGI( MPPARM(mpool) gi );
|
||||
|
||||
int nBytes = stream_getSize( stream );
|
||||
result = (*env)->NewByteArray( env, nBytes );
|
||||
jbyte* jelems = (*env)->GetByteArrayElements( env, result, NULL );
|
||||
stream_getBytes( stream, jelems, nBytes );
|
||||
(*env)->ReleaseByteArrayElements( env, result, jelems, 0 );
|
||||
stream_destroy( stream );
|
||||
|
||||
vtmgr_destroy( MPPARM(mpool) vtMgr );
|
||||
#ifdef MEM_DEBUG
|
||||
mpool_destroy( mpool );
|
||||
#endif
|
||||
LOG_RETURN_VOID();
|
||||
return result;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_gi_1from_1stream
|
||||
( JNIEnv* env, jclass C, jobject jgi, jbyteArray jstream )
|
||||
{
|
||||
LOG_FUNC();
|
||||
#ifdef MEM_DEBUG
|
||||
MemPoolCtx* mpool = mpool_make();
|
||||
#endif
|
||||
VTableMgr* vtMgr = make_vtablemgr( MPPARM_NOCOMMA(mpool) );
|
||||
|
||||
jbyte* jelems = (*env)->GetByteArrayElements( env, jstream, NULL );
|
||||
XWStreamCtxt* stream = mem_stream_make( MPPARM(mpool) vtMgr,
|
||||
NULL, 0, NULL );
|
||||
int len = (*env)->GetArrayLength( env, jstream );
|
||||
stream_putBytes( stream, jelems, len );
|
||||
(*env)->ReleaseByteArrayElements( env, jstream, jelems, 0 );
|
||||
|
||||
CurGameInfo gi;
|
||||
XP_MEMSET( &gi, 0, sizeof(gi) );
|
||||
if ( game_makeFromStream( MPPARM(mpool) stream, NULL,
|
||||
&gi, NULL, NULL, NULL, NULL, NULL ) ) {
|
||||
setJGI( env, jgi, &gi );
|
||||
} else {
|
||||
XP_LOGF( "%s: game_makeFromStream failed", __func__ );
|
||||
}
|
||||
|
||||
gi_disposePlayerInfo( MPPARM(mpool) &gi );
|
||||
|
||||
stream_destroy( stream );
|
||||
vtmgr_destroy( MPPARM(mpool) vtMgr );
|
||||
#ifdef MEM_DEBUG
|
||||
mpool_destroy( mpool );
|
||||
#endif
|
||||
LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
typedef struct _JNIState {
|
||||
XWGame game;
|
||||
JNIEnv* env;
|
||||
|
@ -140,12 +211,12 @@ typedef struct _JNIState {
|
|||
} JNIState;
|
||||
|
||||
#define XWJNI_START() { \
|
||||
XP_LOGF( "%s(env=%x)", __func__, env ); \
|
||||
XP_ASSERT( 0 != gamePtr ); \
|
||||
JNIState* state = (JNIState*)gamePtr; \
|
||||
MPSLOT; \
|
||||
MPASSIGN( mpool, state->mpool); \
|
||||
AndGlobals* globals = &state->globals; \
|
||||
LOG_FUNC(); \
|
||||
/* if reentrant must be from same thread */ \
|
||||
XP_ASSERT( state->env == 0 || state->env == env ); \
|
||||
JNIEnv* _oldEnv = state->env; \
|
||||
|
@ -183,16 +254,13 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeNewGame
|
|||
XWJNI_START();
|
||||
CurGameInfo* gi = makeGI( MPPARM(mpool) env, j_gi );
|
||||
globals->gi = gi;
|
||||
XW_UtilCtxt* util = makeUtil( MPPARM(mpool) &state->env, j_util, gi, globals );
|
||||
XW_UtilCtxt* util = makeUtil( MPPARM(mpool) &state->env, j_util, gi,
|
||||
globals );
|
||||
globals->util = util;
|
||||
DrawCtx* dctx = makeDraw( MPPARM(mpool) &state->env, j_draw );
|
||||
globals->dctx = dctx;
|
||||
CommonPrefs cp;
|
||||
(void)loadCommonPrefs( env, &cp, j_cp );
|
||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||
/* TransportProcs proc; */
|
||||
/* loadTransportProcs( &procs, j_procs ); */
|
||||
#endif
|
||||
|
||||
XP_LOGF( "calling game_makeNewGame" );
|
||||
game_makeNewGame( MPPARM(mpool) &state->game, gi, util, dctx, gameID,
|
||||
|
@ -234,7 +302,7 @@ JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_game_1dispose
|
|||
XP_FREE( mpool, state );
|
||||
mpool_destroy( mpool );
|
||||
LOG_RETURN_VOID();
|
||||
}
|
||||
} /* game_dispose */
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeFromStream
|
||||
|
@ -254,7 +322,6 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeFromStream
|
|||
XWStreamCtxt* stream = mem_stream_make( MPPARM(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 );
|
||||
|
||||
|
@ -266,7 +333,11 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeFromStream
|
|||
NULL );
|
||||
stream_destroy( stream );
|
||||
|
||||
setJGI( env, jgi, globals->gi );
|
||||
if ( result ) {
|
||||
setJGI( env, jgi, globals->gi );
|
||||
} else {
|
||||
XP_LOGF( "%s: need to free stuff allocated above", __func__ );
|
||||
}
|
||||
|
||||
XWJNI_END();
|
||||
return result;
|
||||
|
|
|
@ -179,48 +179,57 @@ game_makeFromStream( MPFORMAL XWStreamCtxt* stream, XWGame* game,
|
|||
strVersion = stream_getU8( stream );
|
||||
XP_DEBUGF( "strVersion = %d", (XP_U16)strVersion );
|
||||
|
||||
if ( strVersion <= CUR_STREAM_VERS ) {
|
||||
stream_setVersion( stream, strVersion );
|
||||
|
||||
gi_readFromStream( MPPARM(mpool) stream, gi );
|
||||
|
||||
/* Previous stream versions didn't save anything if built
|
||||
* standalone. Now we always save something. But we need to know
|
||||
* if the previous version didn't save. PREV_WAS_STANDALONE_ONLY
|
||||
* tells us that.
|
||||
*/
|
||||
hasComms = XP_FALSE;
|
||||
if ( STREAM_VERS_ALWAYS_MULTI <= strVersion /* new stream */
|
||||
#ifndef PREV_WAS_STANDALONE_ONLY
|
||||
|| XP_TRUE /* old, but saved this anyway */
|
||||
#endif
|
||||
) {
|
||||
hasComms = stream_getU8( stream );
|
||||
}
|
||||
|
||||
if ( hasComms ) {
|
||||
game->comms = comms_makeFromStream( MPPARM(mpool) stream, util,
|
||||
procs );
|
||||
} else {
|
||||
game->comms = NULL;
|
||||
}
|
||||
|
||||
XP_ASSERT( !!dict );
|
||||
game->model = model_makeFromStream( MPPARM(mpool) stream, dict, util );
|
||||
|
||||
game->server = server_makeFromStream( MPPARM(mpool) stream,
|
||||
game->model, game->comms,
|
||||
util, gi->nPlayers );
|
||||
|
||||
game->board = board_makeFromStream( MPPARM(mpool) stream, game->model,
|
||||
game->server, draw, util,
|
||||
gi->nPlayers );
|
||||
server_prefsChanged( game->server, cp );
|
||||
board_prefsChanged( game->board, cp );
|
||||
draw_dictChanged( draw, dict );
|
||||
success = XP_TRUE;
|
||||
} else {
|
||||
if ( strVersion > CUR_STREAM_VERS ) {
|
||||
XP_LOGF( "%s: aborting; stream version too new!", __func__ );
|
||||
} else {
|
||||
do { /* do..while so can break */
|
||||
stream_setVersion( stream, strVersion );
|
||||
|
||||
gi_readFromStream( MPPARM(mpool) stream, gi );
|
||||
if ( !game ) {
|
||||
success = XP_TRUE;
|
||||
break;
|
||||
} else if ( stream_getSize(stream) == 0 ) {
|
||||
XP_LOGF( "%s: gi was all we got; failing." );
|
||||
break;
|
||||
}
|
||||
|
||||
/* Previous stream versions didn't save anything if built
|
||||
* standalone. Now we always save something. But we need to know
|
||||
* if the previous version didn't save. PREV_WAS_STANDALONE_ONLY
|
||||
* tells us that.
|
||||
*/
|
||||
hasComms = XP_FALSE;
|
||||
if ( STREAM_VERS_ALWAYS_MULTI <= strVersion /* new stream */
|
||||
#ifndef PREV_WAS_STANDALONE_ONLY
|
||||
|| XP_TRUE /* old, but saved this anyway */
|
||||
#endif
|
||||
) {
|
||||
hasComms = stream_getU8( stream );
|
||||
}
|
||||
|
||||
if ( hasComms ) {
|
||||
game->comms = comms_makeFromStream( MPPARM(mpool) stream, util,
|
||||
procs );
|
||||
} else {
|
||||
game->comms = NULL;
|
||||
}
|
||||
|
||||
XP_ASSERT( !!dict );
|
||||
game->model = model_makeFromStream( MPPARM(mpool) stream, dict, util );
|
||||
|
||||
game->server = server_makeFromStream( MPPARM(mpool) stream,
|
||||
game->model, game->comms,
|
||||
util, gi->nPlayers );
|
||||
|
||||
game->board = board_makeFromStream( MPPARM(mpool) stream, game->model,
|
||||
game->server, draw, util,
|
||||
gi->nPlayers );
|
||||
server_prefsChanged( game->server, cp );
|
||||
board_prefsChanged( game->board, cp );
|
||||
draw_dictChanged( draw, dict );
|
||||
success = XP_TRUE;
|
||||
} while( XP_FALSE );
|
||||
}
|
||||
return success;
|
||||
} /* game_makeFromStream */
|
||||
|
@ -233,17 +242,19 @@ game_saveToStream( const XWGame* game, const CurGameInfo* gi,
|
|||
|
||||
gi_writeToStream( stream, gi );
|
||||
|
||||
stream_putU8( stream, (XP_U8)!!game->comms );
|
||||
if ( !!game ) {
|
||||
stream_putU8( stream, (XP_U8)!!game->comms );
|
||||
#ifdef XWFEATURE_STANDALONE_ONLY
|
||||
XP_ASSERT( !game->comms );
|
||||
XP_ASSERT( !game->comms );
|
||||
#endif
|
||||
if ( !!game->comms ) {
|
||||
comms_writeToStream( game->comms, stream );
|
||||
}
|
||||
if ( !!game->comms ) {
|
||||
comms_writeToStream( game->comms, stream );
|
||||
}
|
||||
|
||||
model_writeToStream( game->model, stream );
|
||||
server_writeToStream( game->server, stream );
|
||||
board_writeToStream( game->board, stream );
|
||||
model_writeToStream( game->model, stream );
|
||||
server_writeToStream( game->server, stream );
|
||||
board_writeToStream( game->board, stream );
|
||||
}
|
||||
} /* game_saveToStream */
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in a new issue