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 ); 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) { public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater(); MenuInflater inflater = getMenuInflater();
inflater.inflate( R.menu.board_menu, menu ); inflater.inflate( R.menu.board_menu, menu );

View file

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

View file

@ -25,6 +25,7 @@ typedef struct _AndDraw {
DrawCtxVTable* vtable; DrawCtxVTable* vtable;
JNIEnv *env; JNIEnv *env;
jobject j_draw; /* global ref; free it! */ jobject j_draw; /* global ref; free it! */
MPSLOT
} AndDraw; } AndDraw;
static jobject static jobject
@ -451,11 +452,11 @@ draw_doNothing( DrawCtx* dctx, ... )
DrawCtx* DrawCtx*
makeDraw( MPFORMAL JNIEnv *env, jobject j_draw ) makeDraw( MPFORMAL JNIEnv *env, jobject j_draw )
{ {
AndDraw* draw = XP_MALLOC( mpool, sizeof(*draw) ); AndDraw* draw = (AndDraw*)XP_CALLOC( mpool, sizeof(*draw) );
XP_MEMSET( draw, 0, sizeof(*draw) );
draw->vtable = XP_MALLOC( mpool, sizeof(*draw->vtable) ); draw->vtable = XP_MALLOC( mpool, sizeof(*draw->vtable) );
draw->j_draw = (*env)->NewGlobalRef( env, j_draw ); draw->j_draw = (*env)->NewGlobalRef( env, j_draw );
draw->env = env; draw->env = env;
MPASSIGN( draw->mpool, mpool );
int ii; int ii;
for ( ii = 0; ii < sizeof(*draw->vtable)/4; ++ii ) { for ( ii = 0; ii < sizeof(*draw->vtable)/4; ++ii ) {
@ -491,3 +492,13 @@ makeDraw( MPFORMAL JNIEnv *env, jobject j_draw )
return (DrawCtx*)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 ); DrawCtx* makeDraw( MPFORMAL JNIEnv *env, jobject j_draw );
void destroyDraw( DrawCtx* dctx );
#endif #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 * Copyright 2001-2009 by Eric House (xwords@eehouse.org). All rights
* reserved. * reserved.
@ -271,14 +271,12 @@ XW_UtilCtxt*
makeUtil( MPFORMAL JNIEnv *env, jobject j_util, CurGameInfo* gi, makeUtil( MPFORMAL JNIEnv *env, jobject j_util, CurGameInfo* gi,
AndGlobals* closure ) AndGlobals* closure )
{ {
AndUtil* util = XP_MALLOC( mpool, sizeof(*util) ); AndUtil* util = (AndUtil*)XP_CALLOC( mpool, sizeof(*util) );
XP_MEMSET( util, 0, sizeof(*util ) ); UtilVtable* vtable = (UtilVtable*)XP_CALLOC( mpool, sizeof(*vtable) );
UtilVtable* vtable = XP_MALLOC( mpool, sizeof(*vtable) );
XP_MEMSET( vtable, 0, sizeof(*vtable ) );
util->env = env; util->env = env;
util->j_util = (*env)->NewGlobalRef( env, j_util ); util->j_util = (*env)->NewGlobalRef( env, j_util );
util->util.vtable = vtable; util->util.vtable = vtable;
util->util.mpool = mpool; MPASSIGN( util->util.mpool, mpool );
util->util.closure = closure; util->util.closure = closure;
util->util.gameInfo = gi; util->util.gameInfo = gi;
@ -324,3 +322,13 @@ SET_PROC( turnChanged);
return (XW_UtilCtxt*)util; return (XW_UtilCtxt*)util;
} /* makeUtil */ } /* 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, XW_UtilCtxt* makeUtil( MPFORMAL JNIEnv *env, jobject j_util,
CurGameInfo* gi, AndGlobals* globals ); CurGameInfo* gi, AndGlobals* globals );
void destroyUtil( XW_UtilCtxt* util );
bool utilTimerFired( XW_UtilCtxt* util, XWTimerReason why, int handle ); 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 <string.h>
#include <jni.h> #include <jni.h>
#include <android/log.h> #include <android/log.h>
@ -19,8 +19,7 @@
static CurGameInfo* static CurGameInfo*
makeGI( MPFORMAL JNIEnv* env, jobject j_gi ) makeGI( MPFORMAL JNIEnv* env, jobject j_gi )
{ {
CurGameInfo* gi = XP_MALLOC( mpool, sizeof(*gi) ); CurGameInfo* gi = (CurGameInfo*)XP_CALLOC( mpool, sizeof(*gi) );
XP_MEMSET( gi, 0, sizeof(*gi) );
int nPlayers, robotSmartness, boardSize; int nPlayers, robotSmartness, boardSize;
int ii; int ii;
XP_UCHAR buf[256]; /* in case needs whole path */ XP_UCHAR buf[256]; /* in case needs whole path */
@ -75,6 +74,13 @@ makeGI( MPFORMAL JNIEnv* env, jobject j_gi )
return gi; return gi;
} /* makeGI */ } /* makeGI */
static void
destroyGI( MPFORMAL CurGameInfo* gi )
{
gi_disposePlayerInfo( MPPARM(mpool) gi );
XP_FREE( mpool, gi );
}
static bool static bool
loadCommonPrefs( JNIEnv* env, CommonPrefs* cp, jobject j_cp ) 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 ); model_setDictionary( game->game.model, dict );
return (jint) game; return (jint) game;
} } /* makeNewGame */
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 )
{ {
GameAndMPool* game = (GameAndMPool*)gamePtr; GameAndMPool* game = (GameAndMPool*)gamePtr;
MemPoolCtx* mpool = game->mpool; MemPoolCtx* mpool = game->mpool;
AndGlobals* globals = game->globals;
destroyGI( mpool, globals->gi );
game_dispose( &game->game ); 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 ); XP_FREE( mpool, game );
mpool_destroy( mpool ); mpool_destroy( mpool );
} }