add onDispose call to game_dispose, and implement it such that jni

doesn't leak.
This commit is contained in:
ehouse 2010-01-09 13:30:23 +00:00
parent 3db30a2995
commit 35dd738c26
7 changed files with 106 additions and 20 deletions

View file

@ -81,6 +81,14 @@ public class BoardActivity extends Activity implements XW_UtilCtxt, Runnable {
XwJNI.server_do( m_jniGamePtr );
}
protected void onDestroy()
{
XwJNI.game_dispose( m_jniGamePtr );
m_jniGamePtr = 0;
super.onDestroy();
Utils.logf( "onDestroy done" );
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate( R.menu.board_menu, menu );

View file

@ -30,7 +30,6 @@ dict_splitFaces( DictionaryCtxt* dict, const XP_U8* bytes,
ptrs[ii] = next;
*next++ = *bytes++;
*next++ = 0;
XP_LOGF( "pointing at str: %s", ptrs[ii] );
}
XP_ASSERT( next == faces + nFaces + nBytes );
@ -75,7 +74,7 @@ andCountSpecials( AndDictionaryCtxt* ctxt )
}
return result;
} /* ceCountSpecials */
} /* andCountSpecials */
static XP_Bitmap
andMakeBitmap( XP_U8** ptrp )
@ -136,10 +135,21 @@ andMakeBitmap( XP_U8** ptrp )
return (XP_Bitmap)bitmap;
} /* andMakeBitmap */
static void
andDeleteBitmap( const AndDictionaryCtxt* XP_UNUSED_DBG(ctxt),
XP_Bitmap* bitmap )
{
if ( !!bitmap ) {
XP_ASSERT(0);
/* CEBitmapInfo* bmi = (CEBitmapInfo*)bitmap; */
/* XP_FREE( ctxt->super.mpool, bmi->bits ); */
/* XP_FREE( ctxt->super.mpool, bmi ); */
}
}
static void
andLoadSpecialData( AndDictionaryCtxt* ctxt, XP_U8** ptrp )
{
LOG_FUNC();
XP_U16 nSpecials = andCountSpecials( ctxt );
XP_U8* ptr = *ptrp;
Tile ii;
@ -173,13 +183,11 @@ andLoadSpecialData( AndDictionaryCtxt* ctxt, XP_U8** ptrp )
ctxt->super.bitmaps = bitmaps;
*ptrp = ptr;
LOG_RETURN_VOID();
} /* andLoadSpecialData */
static void
parseDict( AndDictionaryCtxt* ctxt, XP_U8* ptr, XP_U32 dictLength )
{
LOG_FUNC();
while( !!ptr ) { /* lets us break.... */
XP_U32 offset;
XP_U16 numFaces, numFaceBytes = 0;
@ -302,7 +310,39 @@ parseDict( AndDictionaryCtxt* ctxt, XP_U8* ptr, XP_U32 dictLength )
static void
and_dictionary_destroy( DictionaryCtxt* dict )
{
LOG_FUNC();
AndDictionaryCtxt* ctxt = (AndDictionaryCtxt*)dict;
XP_U16 nSpecials = andCountSpecials( ctxt );
XP_U16 ii;
if ( !!ctxt->super.chars ) {
for ( ii = 0; ii < nSpecials; ++ii ) {
XP_UCHAR* text = ctxt->super.chars[ii];
if ( !!text ) {
XP_FREE( ctxt->super.mpool, text );
}
}
XP_FREE( ctxt->super.mpool, ctxt->super.chars );
}
if ( !!ctxt->super.bitmaps ) {
for ( ii = 0; ii < nSpecials; ++ii ) {
XP_ASSERT( !ctxt->super.bitmaps[ii].largeBM );
XP_ASSERT( !ctxt->super.bitmaps[ii].smallBM );
andDeleteBitmap( ctxt, ctxt->super.bitmaps[ii].largeBM );
andDeleteBitmap( ctxt, ctxt->super.bitmaps[ii].smallBM );
}
XP_FREE( ctxt->super.mpool, ctxt->super.bitmaps );
}
XP_FREE( ctxt->super.mpool, ctxt->super.faces );
XP_FREE( ctxt->super.mpool, ctxt->super.facePtrs );
XP_FREE( ctxt->super.mpool, ctxt->super.countsAndValues );
XP_FREE( ctxt->super.mpool, ctxt->super.name );
XP_FREE( ctxt->super.mpool, ctxt->bytes );
XP_FREE( ctxt->super.mpool, ctxt );
LOG_RETURN_VOID();
}
DictionaryCtxt*

View file

@ -25,6 +25,7 @@ typedef struct _AndDraw {
DrawCtxVTable* vtable;
JNIEnv *env;
jobject j_draw; /* global ref; free it! */
MPSLOT
} AndDraw;
static jobject
@ -451,11 +452,11 @@ draw_doNothing( DrawCtx* dctx, ... )
DrawCtx*
makeDraw( MPFORMAL JNIEnv *env, jobject j_draw )
{
AndDraw* draw = XP_MALLOC( mpool, sizeof(*draw) );
XP_MEMSET( draw, 0, sizeof(*draw) );
AndDraw* draw = (AndDraw*)XP_CALLOC( mpool, sizeof(*draw) );
draw->vtable = XP_MALLOC( mpool, sizeof(*draw->vtable) );
draw->j_draw = (*env)->NewGlobalRef( env, j_draw );
draw->env = env;
MPASSIGN( draw->mpool, mpool );
int ii;
for ( ii = 0; ii < sizeof(*draw->vtable)/4; ++ii ) {
@ -491,3 +492,13 @@ makeDraw( MPFORMAL JNIEnv *env, jobject j_draw )
return (DrawCtx*)draw;
}
void
destroyDraw( DrawCtx* dctx )
{
AndDraw* draw = (AndDraw*)dctx;
JNIEnv* env = draw->env;
(*env)->DeleteGlobalRef( env, draw->j_draw );
XP_FREE( draw->mpool, draw->vtable );
XP_FREE( draw->mpool, draw );
}

View file

@ -27,5 +27,7 @@
DrawCtx* makeDraw( MPFORMAL JNIEnv *env, jobject j_draw );
void destroyDraw( DrawCtx* dctx );
#endif

View file

@ -1,4 +1,4 @@
/* -*-mode: C; fill-column: 76; c-basic-offset: 4; -*- */
/* -*-mode: C; compile-command: "cd XWords4; ../scripts/ndkbuild.sh"; -*- */
/*
* Copyright 2001-2009 by Eric House (xwords@eehouse.org). All rights
* reserved.
@ -271,14 +271,12 @@ XW_UtilCtxt*
makeUtil( MPFORMAL JNIEnv *env, jobject j_util, CurGameInfo* gi,
AndGlobals* closure )
{
AndUtil* util = XP_MALLOC( mpool, sizeof(*util) );
XP_MEMSET( util, 0, sizeof(*util ) );
UtilVtable* vtable = XP_MALLOC( mpool, sizeof(*vtable) );
XP_MEMSET( vtable, 0, sizeof(*vtable ) );
AndUtil* util = (AndUtil*)XP_CALLOC( mpool, sizeof(*util) );
UtilVtable* vtable = (UtilVtable*)XP_CALLOC( mpool, sizeof(*vtable) );
util->env = env;
util->j_util = (*env)->NewGlobalRef( env, j_util );
util->util.vtable = vtable;
util->util.mpool = mpool;
MPASSIGN( util->util.mpool, mpool );
util->util.closure = closure;
util->util.gameInfo = gi;
@ -324,3 +322,13 @@ SET_PROC( turnChanged);
return (XW_UtilCtxt*)util;
} /* makeUtil */
void
destroyUtil( XW_UtilCtxt* utilc )
{
AndUtil* util = (AndUtil*)utilc;
JNIEnv *env = util->env;
(*env)->DeleteGlobalRef( env, util->j_util );
XP_FREE( util->util.mpool, util->util.vtable );
XP_FREE( util->util.mpool, util );
}

View file

@ -29,6 +29,8 @@
XW_UtilCtxt* makeUtil( MPFORMAL JNIEnv *env, jobject j_util,
CurGameInfo* gi, AndGlobals* globals );
void destroyUtil( XW_UtilCtxt* util );
bool utilTimerFired( XW_UtilCtxt* util, XWTimerReason why, int handle );

View file

@ -1,4 +1,4 @@
/* -*-mode: C; compile-command: "cd XWords4; ../scripts/ndkbuild.sh"; -*- */
#include <string.h>
#include <jni.h>
#include <android/log.h>
@ -19,8 +19,7 @@
static CurGameInfo*
makeGI( MPFORMAL JNIEnv* env, jobject j_gi )
{
CurGameInfo* gi = XP_MALLOC( mpool, sizeof(*gi) );
XP_MEMSET( gi, 0, sizeof(*gi) );
CurGameInfo* gi = (CurGameInfo*)XP_CALLOC( mpool, sizeof(*gi) );
int nPlayers, robotSmartness, boardSize;
int ii;
XP_UCHAR buf[256]; /* in case needs whole path */
@ -75,6 +74,13 @@ makeGI( MPFORMAL JNIEnv* env, jobject j_gi )
return gi;
} /* makeGI */
static void
destroyGI( MPFORMAL CurGameInfo* gi )
{
gi_disposePlayerInfo( MPPARM(mpool) gi );
XP_FREE( mpool, gi );
}
static bool
loadCommonPrefs( JNIEnv* env, CommonPrefs* cp, jobject j_cp )
{
@ -141,15 +147,24 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeNewGame
model_setDictionary( game->game.model, dict );
return (jint) game;
}
} /* makeNewGame */
JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_game_1dispose
(JNIEnv * env, jclass claz, jint gamePtr )
( JNIEnv * env, jclass claz, jint gamePtr )
{
GameAndMPool* game = (GameAndMPool*)gamePtr;
MemPoolCtx* mpool = game->mpool;
AndGlobals* globals = game->globals;
destroyGI( mpool, globals->gi );
game_dispose( &game->game );
XP_FREE( mpool, game->globals );
destroyDraw( globals->dctx );
destroyUtil( globals->util );
vtmgr_destroy( mpool, globals->vtMgr );
XP_FREE( mpool, globals );
XP_FREE( mpool, game );
mpool_destroy( mpool );
}