mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2024-12-28 09:58:30 +01:00
implement dictChanged. And so that utf8 dicts could be opened without
their games being drawn (no BoardActivity around) break the two android-only callbacks out of UtilCtxt and into a new JNIUtils interface that then requires new handing in C.
This commit is contained in:
parent
099cf66a79
commit
bd611bb6f4
22 changed files with 372 additions and 161 deletions
|
@ -32,6 +32,7 @@ local_SRC_FILES += \
|
|||
xportwrapper.c \
|
||||
anddict.c \
|
||||
andutils.c \
|
||||
jniutlswrapper.c \
|
||||
|
||||
|
||||
COMMON_PATH=../../../common
|
||||
|
|
|
@ -8,11 +8,12 @@
|
|||
#include "xptypes.h"
|
||||
#include "dictnry.h"
|
||||
#include "strutils.h"
|
||||
#include "andutils.h"
|
||||
#include "utilwrapper.h"
|
||||
|
||||
typedef struct _AndDictionaryCtxt {
|
||||
DictionaryCtxt super;
|
||||
XW_UtilCtxt* util;
|
||||
JNIUtilCtxt* jniutil;
|
||||
JNIEnv *env;
|
||||
XP_U8* bytes;
|
||||
} AndDictionaryCtxt;
|
||||
|
@ -22,7 +23,8 @@ dict_splitFaces( DictionaryCtxt* dict, const XP_U8* bytes,
|
|||
XP_U16 nBytes, XP_U16 nFaces )
|
||||
{
|
||||
XP_UCHAR* faces = (XP_UCHAR*)XP_CALLOC( dict->mpool, nBytes + nFaces );
|
||||
XP_UCHAR** ptrs = (XP_UCHAR**)XP_CALLOC( dict->mpool, nFaces * sizeof(ptrs[0]));
|
||||
const XP_UCHAR** ptrs = (const XP_UCHAR**)
|
||||
XP_CALLOC( dict->mpool, nFaces * sizeof(ptrs[0]));
|
||||
XP_U16 ii;
|
||||
XP_UCHAR* next = faces;
|
||||
|
||||
|
@ -112,7 +114,7 @@ andMakeBitmap( AndDictionaryCtxt* ctxt, XP_U8** ptrp )
|
|||
}
|
||||
|
||||
JNIEnv* env = ctxt->env;
|
||||
bitmap = and_util_makeJBitmap( ctxt->util, nCols, nRows, colors );
|
||||
bitmap = and_util_makeJBitmap( ctxt->jniutil, nCols, nRows, colors );
|
||||
jobject tmp = (*env)->NewGlobalRef( env, bitmap );
|
||||
XP_ASSERT( tmp == bitmap );
|
||||
(*env)->DeleteLocalRef( env, bitmap );
|
||||
|
@ -176,7 +178,7 @@ splitFaces_via_java( JNIEnv* env, AndDictionaryCtxt* ctxt, const XP_U8* ptr,
|
|||
int nBytes;
|
||||
int ii;
|
||||
|
||||
jobject jstrarr = and_util_splitFaces( ctxt->util, ptr, nFaceBytes );
|
||||
jobject jstrarr = and_util_splitFaces( ctxt->jniutil, ptr, nFaceBytes );
|
||||
XP_ASSERT( (*env)->GetArrayLength( env, jstrarr ) == nFaces );
|
||||
|
||||
for ( ii = 0; ii < nFaces; ++ii ) {
|
||||
|
@ -204,8 +206,8 @@ splitFaces_via_java( JNIEnv* env, AndDictionaryCtxt* ctxt, const XP_U8* ptr,
|
|||
(*env)->DeleteLocalRef( env, jstrarr );
|
||||
|
||||
XP_UCHAR* faces = (XP_UCHAR*)XP_CALLOC( ctxt->super.mpool, indx );
|
||||
XP_UCHAR** ptrs = (XP_UCHAR**)XP_CALLOC( ctxt->super.mpool,
|
||||
nFaces * sizeof(ptrs[0]));
|
||||
const XP_UCHAR** ptrs = (const XP_UCHAR**)
|
||||
XP_CALLOC( ctxt->super.mpool, nFaces * sizeof(ptrs[0]));
|
||||
|
||||
XP_MEMCPY( faces, facesBuf, indx );
|
||||
for ( ii = 0; ii < nFaces; ++ii ) {
|
||||
|
@ -373,6 +375,20 @@ and_dictionary_destroy( DictionaryCtxt* dict )
|
|||
LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
jobject
|
||||
and_dictionary_getChars( JNIEnv* env, DictionaryCtxt* dict )
|
||||
{
|
||||
AndDictionaryCtxt* anddict = (AndDictionaryCtxt*)dict;
|
||||
XP_ASSERT( env == anddict->env );
|
||||
|
||||
/* This is cheating: specials will be rep'd as 1,2, etc. But as long as
|
||||
java code wants to ignore them anyway that's ok. Otherwise need to
|
||||
use dict_tilesToString() */
|
||||
XP_U16 nFaces = dict_numTileFaces( dict );
|
||||
jobject jstrs = makeStringArray( env, nFaces, dict->facePtrs );
|
||||
return jstrs;
|
||||
}
|
||||
|
||||
DictionaryCtxt*
|
||||
and_dictionary_make_empty( MPFORMAL_NOCOMMA )
|
||||
{
|
||||
|
@ -384,7 +400,7 @@ and_dictionary_make_empty( MPFORMAL_NOCOMMA )
|
|||
}
|
||||
|
||||
DictionaryCtxt*
|
||||
makeDict( MPFORMAL JNIEnv *env, XW_UtilCtxt* util, jbyteArray jbytes )
|
||||
makeDict( MPFORMAL JNIEnv *env, JNIUtilCtxt* jniutil, jbyteArray jbytes )
|
||||
{
|
||||
XP_Bool formatOk = XP_TRUE;
|
||||
XP_Bool isUTF8 = XP_FALSE;
|
||||
|
@ -392,7 +408,6 @@ makeDict( MPFORMAL JNIEnv *env, XW_UtilCtxt* util, jbyteArray jbytes )
|
|||
AndDictionaryCtxt* anddict = NULL;
|
||||
|
||||
jsize len = (*env)->GetArrayLength( env, jbytes );
|
||||
XP_LOGF( "%s: got %d bytes", __func__, len );
|
||||
|
||||
XP_U8* localBytes = XP_MALLOC( mpool, len );
|
||||
jbyte* src = (*env)->GetByteArrayElements( env, jbytes, NULL );
|
||||
|
@ -406,7 +421,7 @@ makeDict( MPFORMAL JNIEnv *env, XW_UtilCtxt* util, jbyteArray jbytes )
|
|||
|
||||
anddict->bytes = localBytes;
|
||||
anddict->env = env;
|
||||
anddict->util = util;
|
||||
anddict->jniutil = jniutil;
|
||||
|
||||
parseDict( anddict, localBytes, len );
|
||||
setBlankTile( &anddict->super );
|
||||
|
|
|
@ -5,14 +5,17 @@
|
|||
|
||||
#include "dictnry.h"
|
||||
#include "comtypes.h"
|
||||
#include "jniutlswrapper.h"
|
||||
|
||||
void
|
||||
dict_splitFaces( DictionaryCtxt* dict, const XP_U8* bytes,
|
||||
XP_U16 nBytes, XP_U16 nFaces );
|
||||
|
||||
DictionaryCtxt* makeDict( MPFORMAL JNIEnv *env, XW_UtilCtxt* util,
|
||||
DictionaryCtxt* makeDict( MPFORMAL JNIEnv *env, JNIUtilCtxt* jniutil,
|
||||
jbyteArray bytes );
|
||||
|
||||
DictionaryCtxt* and_dictionary_make_empty( MPFORMAL_NOCOMMA );
|
||||
|
||||
jobject and_dictionary_getChars( JNIEnv* env, DictionaryCtxt* dict );
|
||||
|
||||
#endif
|
||||
|
|
|
@ -11,6 +11,7 @@ typedef struct _AndGlobals {
|
|||
CurGameInfo* gi;
|
||||
DrawCtx* dctx;
|
||||
XW_UtilCtxt* util;
|
||||
struct JNIUtilCtxt* jniutil;
|
||||
TransportProcs* xportProcs;
|
||||
struct JNIState* state;
|
||||
} AndGlobals;
|
||||
|
|
|
@ -109,6 +109,7 @@ makeDSI( AndDraw* draw, int indx, const DrawScoreInfo* dsi )
|
|||
#define DRAW_CBK_HEADER(nam,sig) \
|
||||
AndDraw* draw = (AndDraw*)dctx; \
|
||||
JNIEnv* env = *draw->env; \
|
||||
XP_ASSERT( !!draw->jdraw ); \
|
||||
jmethodID mid = getMethodID( env, draw->jdraw, nam, sig );
|
||||
|
||||
static void
|
||||
|
@ -209,7 +210,9 @@ and_draw_score_drawPlayer( DrawCtx* dctx,
|
|||
static XP_Bool
|
||||
and_draw_boardBegin( DrawCtx* dctx, const XP_Rect* rect, DrawFocusState dfs )
|
||||
{
|
||||
return XP_TRUE;
|
||||
AndDraw* draw = (AndDraw*)dctx;
|
||||
XP_Bool result = NULL != draw->jdraw;
|
||||
return result;
|
||||
}
|
||||
|
||||
static XP_Bool
|
||||
|
@ -380,7 +383,11 @@ and_draw_objFinished( DrawCtx* dctx, BoardObjectType typ,
|
|||
static void
|
||||
and_draw_dictChanged( DrawCtx* dctx, const DictionaryCtxt* dict )
|
||||
{
|
||||
LOG_FUNC();
|
||||
AndDraw* draw = (AndDraw*)dctx;
|
||||
if ( NULL != draw->jdraw ) {
|
||||
DRAW_CBK_HEADER( "dictChanged", "(I)V" );
|
||||
(*env)->CallVoidMethod( env, draw->jdraw, mid, (jint)dict );
|
||||
}
|
||||
}
|
||||
|
||||
static const XP_UCHAR*
|
||||
|
|
93
xwords4/android/XWords4/jni/jniutlswrapper.c
Normal file
93
xwords4/android/XWords4/jni/jniutlswrapper.c
Normal file
|
@ -0,0 +1,93 @@
|
|||
/* -*-mode: C; compile-command: "../../scripts/ndkbuild.sh"; -*- */
|
||||
/*
|
||||
* Copyright 2001-2010 by Eric House (xwords@eehouse.org). All rights
|
||||
* reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "strutils.h"
|
||||
#include "jniutlswrapper.h"
|
||||
#include "andutils.h"
|
||||
|
||||
|
||||
struct JNIUtilCtxt {
|
||||
JNIEnv** envp;
|
||||
jobject jjniutil;
|
||||
MPSLOT;
|
||||
};
|
||||
|
||||
JNIUtilCtxt*
|
||||
makeJNIUtil( MPFORMAL JNIEnv** envp, jobject jniutls )
|
||||
{
|
||||
JNIUtilCtxt* ctxt = (JNIUtilCtxt*)XP_CALLOC( mpool, sizeof( *ctxt ) );
|
||||
JNIEnv* env = *envp;
|
||||
ctxt->envp = envp;
|
||||
ctxt->jjniutil = (*env)->NewGlobalRef( env, jniutls );
|
||||
MPASSIGN( ctxt->mpool, mpool );
|
||||
return ctxt;
|
||||
}
|
||||
|
||||
void
|
||||
destroyJNIUtil( JNIUtilCtxt** ctxtp )
|
||||
{
|
||||
JNIUtilCtxt* ctxt = *ctxtp;
|
||||
if ( !!ctxt ) {
|
||||
JNIEnv* env = *ctxt->envp;
|
||||
(*env)->DeleteGlobalRef( env, ctxt->jjniutil );
|
||||
XP_FREE( ctxt->mpool, ctxt );
|
||||
*ctxtp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* These are called from anddict.c, not via vtable */
|
||||
jobject
|
||||
and_util_makeJBitmap( JNIUtilCtxt* jniutil, int nCols, int nRows,
|
||||
const jboolean* colors )
|
||||
{
|
||||
jobject bitmap;
|
||||
JNIEnv* env = *jniutil->envp;
|
||||
jmethodID mid
|
||||
= getMethodID( env, jniutil->jjniutil, "makeBitmap",
|
||||
"(II[Z)Landroid/graphics/drawable/BitmapDrawable;" );
|
||||
|
||||
jbooleanArray jcolors = makeBooleanArray( env, nCols*nRows, colors );
|
||||
|
||||
bitmap = (*env)->CallObjectMethod( env, jniutil->jjniutil, mid,
|
||||
nCols, nRows, jcolors );
|
||||
(*env)->DeleteLocalRef( env, jcolors );
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
jobject
|
||||
and_util_splitFaces( JNIUtilCtxt* jniutil, const XP_U8* bytes, jsize len )
|
||||
{
|
||||
jobject strarray = NULL;
|
||||
JNIEnv* env = *jniutil->envp;
|
||||
jmethodID mid
|
||||
= getMethodID( env, jniutil->jjniutil, "splitFaces",
|
||||
"([B)[Ljava/lang/String;" );
|
||||
|
||||
jbyteArray jbytes = (*env)->NewByteArray( env, len );
|
||||
|
||||
jbyte* jp = (*env)->GetByteArrayElements( env, jbytes, NULL );
|
||||
XP_MEMCPY( jp, bytes, len );
|
||||
(*env)->ReleaseByteArrayElements( env, jbytes, jp, 0 );
|
||||
|
||||
strarray = (*env)->CallObjectMethod( env, jniutil->jjniutil, mid, jbytes );
|
||||
(*env)->DeleteLocalRef( env, jbytes );
|
||||
return strarray;
|
||||
}
|
38
xwords4/android/XWords4/jni/jniutlswrapper.h
Normal file
38
xwords4/android/XWords4/jni/jniutlswrapper.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/* -*-mode: C; fill-column: 76; c-basic-offset: 4; -*- */
|
||||
/*
|
||||
* Copyright 2001-2010 by Eric House (xwords@eehouse.org). All rights
|
||||
* reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _JNIUTLSWRAPPER_H_
|
||||
#define _JNIUTLSWRAPPER_H_
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "andglobals.h"
|
||||
|
||||
typedef struct JNIUtilCtxt JNIUtilCtxt;
|
||||
|
||||
JNIUtilCtxt* makeJNIUtil( MPFORMAL JNIEnv** env, jobject jniutls );
|
||||
void destroyJNIUtil( JNIUtilCtxt** jniu );
|
||||
|
||||
jobject and_util_makeJBitmap( JNIUtilCtxt* jniu, int nCols, int nRows,
|
||||
const jboolean* colors );
|
||||
jobject and_util_splitFaces( JNIUtilCtxt* jniu, const XP_U8* bytes, int len );
|
||||
|
||||
#endif
|
|
@ -287,13 +287,11 @@ and_util_getUserString( XW_UtilCtxt* uc, XP_U16 stringCode )
|
|||
const char* jchars = (*env)->GetStringUTFChars( env, jresult, NULL );
|
||||
XP_MEMCPY( buf, jchars, len );
|
||||
buf[len] = '\0';
|
||||
XP_LOGF( "got string from java: %s", buf );
|
||||
(*env)->ReleaseStringUTFChars( env, jresult, jchars );
|
||||
(*env)->DeleteLocalRef( env, jresult );
|
||||
util->userStrings[index] = buf;
|
||||
}
|
||||
|
||||
LOG_RETURNF( "%s", util->userStrings[index] );
|
||||
result = util->userStrings[index];
|
||||
UTIL_CBK_TAIL();
|
||||
return result;
|
||||
|
@ -350,42 +348,6 @@ and_util_engineStopping( XW_UtilCtxt* uc )
|
|||
}
|
||||
#endif
|
||||
|
||||
/* These are called from anddict.c, not via vtable */
|
||||
jobject
|
||||
and_util_makeJBitmap( XW_UtilCtxt* uc, int nCols, int nRows,
|
||||
const jboolean* colors )
|
||||
{
|
||||
jobject bitmap;
|
||||
UTIL_CBK_HEADER( "makeBitmap",
|
||||
"(II[Z)Landroid/graphics/drawable/BitmapDrawable;" );
|
||||
jbooleanArray jcolors = makeBooleanArray( env, nCols*nRows, colors );
|
||||
|
||||
bitmap = (*env)->CallObjectMethod( env, util->jutil, mid,
|
||||
nCols, nRows, jcolors );
|
||||
(*env)->DeleteLocalRef( env, jcolors );
|
||||
UTIL_CBK_TAIL();
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
jobject
|
||||
and_util_splitFaces( XW_UtilCtxt* uc, const XP_U8* bytes, jsize len )
|
||||
{
|
||||
jobject strarray;
|
||||
UTIL_CBK_HEADER( "splitFaces", "([B)[Ljava/lang/String;" );
|
||||
|
||||
jbyteArray jbytes = (*env)->NewByteArray( env, len );
|
||||
|
||||
jbyte* jp = (*env)->GetByteArrayElements( env, jbytes, NULL );
|
||||
XP_MEMCPY( jp, bytes, len );
|
||||
(*env)->ReleaseByteArrayElements( env, jbytes, jp, 0 );
|
||||
|
||||
strarray = (*env)->CallObjectMethod( env, util->jutil, mid, jbytes );
|
||||
(*env)->DeleteLocalRef( env, jbytes );
|
||||
UTIL_CBK_TAIL();
|
||||
return strarray;
|
||||
}
|
||||
|
||||
|
||||
XW_UtilCtxt*
|
||||
makeUtil( MPFORMAL JNIEnv** envp, jobject jutil, CurGameInfo* gi,
|
||||
AndGlobals* closure )
|
||||
|
@ -447,7 +409,6 @@ makeUtil( MPFORMAL JNIEnv** envp, jobject jutil, CurGameInfo* gi,
|
|||
void
|
||||
destroyUtil( XW_UtilCtxt** utilc )
|
||||
{
|
||||
LOG_FUNC();
|
||||
AndUtil* util = (AndUtil*)*utilc;
|
||||
JNIEnv *env = *util->env;
|
||||
|
||||
|
@ -465,5 +426,4 @@ destroyUtil( XW_UtilCtxt** utilc )
|
|||
XP_FREE( util->util.mpool, util->util.vtable );
|
||||
XP_FREE( util->util.mpool, util );
|
||||
*utilc = NULL;
|
||||
LOG_RETURN_VOID();
|
||||
}
|
||||
|
|
|
@ -33,8 +33,4 @@ void destroyUtil( XW_UtilCtxt** util );
|
|||
|
||||
bool utilTimerFired( XW_UtilCtxt* util, XWTimerReason why, int handle );
|
||||
|
||||
jobject and_util_makeJBitmap( XW_UtilCtxt* util, int nCols, int nRows,
|
||||
const jboolean* colors );
|
||||
jobject and_util_splitFaces( XW_UtilCtxt* uc, const XP_U8* bytes, int len );
|
||||
|
||||
#endif
|
||||
|
|
|
@ -102,8 +102,6 @@ makeXportProcs( MPFORMAL JNIEnv** envp, jobject jxport )
|
|||
{
|
||||
AndTransportProcs* aprocs = NULL;
|
||||
|
||||
XP_LOGF( "%s: jxport=%p", __func__, jxport );
|
||||
|
||||
JNIEnv* env = *envp;
|
||||
aprocs = (AndTransportProcs*)XP_CALLOC( mpool, sizeof(*aprocs) );
|
||||
if ( NULL != jxport ) {
|
||||
|
@ -119,7 +117,6 @@ makeXportProcs( MPFORMAL JNIEnv** envp, jobject jxport )
|
|||
aprocs->tp.rerror = and_xport_relayError;
|
||||
aprocs->tp.closure = aprocs;
|
||||
|
||||
LOG_RETURNF( "%p", aprocs );
|
||||
return (TransportProcs*)aprocs;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "xportwrapper.h"
|
||||
#include "anddict.h"
|
||||
#include "andutils.h"
|
||||
#include "jniutlswrapper.h"
|
||||
|
||||
static CurGameInfo*
|
||||
makeGI( MPFORMAL JNIEnv* env, jobject j_gi )
|
||||
|
@ -219,6 +220,32 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getInitialAddr
|
|||
setJAddrRec( env, jaddr, &addr );
|
||||
}
|
||||
|
||||
/* Dictionary methods: don't use gamePtr */
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_dict_1tilesAreSame
|
||||
( JNIEnv* env, jclass C, jint dictPtr1, jint dictPtr2 )
|
||||
{
|
||||
LOG_FUNC();
|
||||
jboolean result;
|
||||
const DictionaryCtxt* dict1 = (DictionaryCtxt*)dictPtr1;
|
||||
const DictionaryCtxt* dict2 = (DictionaryCtxt*)dictPtr2;
|
||||
result = dict_tilesAreSame( dict1, dict2 );
|
||||
LOG_RETURNF( "%d", result );
|
||||
return result;
|
||||
}
|
||||
|
||||
JNIEXPORT jobjectArray JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_dict_1getChars
|
||||
( JNIEnv* env, jclass C, jint dictPtr )
|
||||
{
|
||||
LOG_FUNC();
|
||||
jobject result = NULL;
|
||||
result = and_dictionary_getChars( env, (DictionaryCtxt*)dictPtr );
|
||||
(*env)->DeleteLocalRef( env, result );
|
||||
LOG_RETURNF( "%p", result );
|
||||
return result;
|
||||
}
|
||||
|
||||
typedef struct _JNIState {
|
||||
XWGame game;
|
||||
JNIEnv* env;
|
||||
|
@ -262,15 +289,16 @@ Java_org_eehouse_android_xw4_jni_XwJNI_initJNI
|
|||
|
||||
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, jobject j_cp, jobject j_procs, jbyteArray jDictBytes )
|
||||
( JNIEnv* env, jclass C, jint gamePtr, jobject j_gi, jobject j_util,
|
||||
jobject jniu, jobject j_draw, jobject j_cp, jobject j_procs,
|
||||
jbyteArray jDictBytes )
|
||||
{
|
||||
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 );
|
||||
globals->util = util;
|
||||
globals->util = makeUtil( MPPARM(mpool) &state->env, j_util, gi,
|
||||
globals );
|
||||
globals->jniutil = makeJNIUtil( MPPARM(mpool) &state->env, jniu );
|
||||
DrawCtx* dctx = makeDraw( MPPARM(mpool) &state->env, j_draw );
|
||||
globals->dctx = dctx;
|
||||
globals->xportProcs = makeXportProcs( MPPARM(mpool) &state->env, j_procs );
|
||||
|
@ -278,10 +306,11 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeNewGame
|
|||
loadCommonPrefs( env, &cp, j_cp );
|
||||
|
||||
XP_LOGF( "calling game_makeNewGame" );
|
||||
game_makeNewGame( MPPARM(mpool) &state->game, gi, util, dctx, &cp,
|
||||
game_makeNewGame( MPPARM(mpool) &state->game, gi, globals->util, dctx, &cp,
|
||||
globals->xportProcs );
|
||||
|
||||
DictionaryCtxt* dict = makeDict( MPPARM(mpool) env, util, jDictBytes );
|
||||
DictionaryCtxt* dict = makeDict( MPPARM(mpool) env, globals->jniutil,
|
||||
jDictBytes );
|
||||
#ifdef STUBBED_DICT
|
||||
if ( !dict ) {
|
||||
XP_LOGF( "falling back to stubbed dict" );
|
||||
|
@ -312,6 +341,7 @@ JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_game_1dispose
|
|||
destroyDraw( &globals->dctx );
|
||||
destroyXportProcs( &globals->xportProcs );
|
||||
destroyUtil( &globals->util );
|
||||
destroyJNIUtil( &globals->jniutil );
|
||||
vtmgr_destroy( MPPARM(mpool) globals->vtMgr );
|
||||
|
||||
state->env = oldEnv;
|
||||
|
@ -323,8 +353,8 @@ JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_game_1dispose
|
|||
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 )
|
||||
jobject /*out*/jgi, jbyteArray jdict, jobject jutil, jobject jniu,
|
||||
jobject jdraw, jobject jcp, jobject jprocs )
|
||||
{
|
||||
jboolean result;
|
||||
XWJNI_START();
|
||||
|
@ -332,7 +362,8 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeFromStream
|
|||
globals->gi = (CurGameInfo*)XP_CALLOC( mpool, sizeof(*globals->gi) );
|
||||
globals->util = makeUtil( MPPARM(mpool) &state->env,
|
||||
jutil, globals->gi, globals );
|
||||
DictionaryCtxt* dict = makeDict( MPPARM(mpool) env, globals->util, jdict );
|
||||
globals->jniutil = makeJNIUtil( MPPARM(mpool) &state->env, jniu );
|
||||
DictionaryCtxt* dict = makeDict( MPPARM(mpool) env, globals->jniutil, jdict );
|
||||
globals->dctx = makeDraw( MPPARM(mpool) &state->env, jdraw );
|
||||
globals->xportProcs = makeXportProcs( MPPARM(mpool) &state->env, jprocs );
|
||||
|
||||
|
@ -357,6 +388,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeFromStream
|
|||
dict_destroy( dict );
|
||||
dict = NULL;
|
||||
destroyUtil( &globals->util );
|
||||
destroyJNIUtil( &globals->jniutil );
|
||||
destroyGI( MPPARM(mpool) &globals->gi );
|
||||
}
|
||||
|
||||
|
@ -371,12 +403,19 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1saveToStream
|
|||
jbyteArray result;
|
||||
XWJNI_START();
|
||||
|
||||
CurGameInfo* gi = makeGI( MPPARM(mpool) env, jgi );
|
||||
/* Use our copy of gi if none's provided. That's because only the caller
|
||||
knows if its gi should win -- user has changed game config -- or if
|
||||
ours should -- changes like remote players being added. */
|
||||
CurGameInfo* gi =
|
||||
(NULL == jgi) ? globals->gi : makeGI( MPPARM(mpool) env, jgi );
|
||||
XWStreamCtxt* stream = mem_stream_make( MPPARM(mpool) globals->vtMgr,
|
||||
NULL, 0, NULL );
|
||||
|
||||
game_saveToStream( &state->game, gi, stream );
|
||||
destroyGI( MPPARM(mpool) &gi );
|
||||
|
||||
if ( NULL != jgi ) {
|
||||
destroyGI( MPPARM(mpool) &gi );
|
||||
}
|
||||
|
||||
int nBytes = stream_getSize( stream );
|
||||
result = (*env)->NewByteArray( env, nBytes );
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- compile-command: "cd ../../../../../; ant reinstall"; -*- */
|
||||
/* -*- compile-command: "cd ../../../../../; ant install"; -*- */
|
||||
|
||||
package org.eehouse.android.xw4;
|
||||
|
||||
|
@ -9,12 +9,10 @@ import android.view.MenuItem;
|
|||
import android.view.MenuInflater;
|
||||
import android.content.res.AssetManager;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.Intent;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
@ -22,9 +20,6 @@ import android.net.Uri;
|
|||
import android.app.Dialog;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.Bitmap;
|
||||
import java.util.ArrayList;
|
||||
import android.content.res.Resources;
|
||||
|
||||
import org.eehouse.android.xw4.jni.*;
|
||||
|
@ -51,6 +46,7 @@ public class BoardActivity extends Activity implements UtilCtxt {
|
|||
private int m_dlgTitle;
|
||||
private boolean m_dlgResult;
|
||||
private CommonPrefs m_cp;
|
||||
private JNIUtils m_jniu;
|
||||
|
||||
// call startActivityForResult synchronously
|
||||
private Semaphore m_forResultWait = new Semaphore(0);
|
||||
|
@ -113,6 +109,7 @@ public class BoardActivity extends Activity implements UtilCtxt {
|
|||
super.onCreate( savedInstanceState );
|
||||
|
||||
m_cp = CommonPrefs.get();
|
||||
m_jniu = JNIUtilsImpl.get();
|
||||
|
||||
setContentView( R.layout.board );
|
||||
m_handler = new Handler();
|
||||
|
@ -147,9 +144,9 @@ public class BoardActivity extends Activity implements UtilCtxt {
|
|||
if ( null == stream ||
|
||||
! XwJNI.game_makeFromStream( m_jniGamePtr, stream,
|
||||
m_gi, dictBytes, this,
|
||||
m_view, m_cp, m_xport ) ) {
|
||||
XwJNI.game_makeNewGame( m_jniGamePtr, m_gi, this, m_view,
|
||||
m_cp, m_xport, dictBytes );
|
||||
m_jniu, m_view, m_cp, m_xport ) ) {
|
||||
XwJNI.game_makeNewGame( m_jniGamePtr, m_gi, this, m_jniu,
|
||||
m_view, m_cp, m_xport, dictBytes );
|
||||
}
|
||||
|
||||
m_jniThread = new
|
||||
|
@ -193,7 +190,7 @@ public class BoardActivity extends Activity implements UtilCtxt {
|
|||
|
||||
protected void onDestroy()
|
||||
{
|
||||
byte[] state = XwJNI.game_saveToStream( m_jniGamePtr, m_gi );
|
||||
byte[] state = XwJNI.game_saveToStream( m_jniGamePtr, null );
|
||||
Utils.saveGame( this, state, m_path );
|
||||
|
||||
if ( null != m_xport ) {
|
||||
|
@ -596,63 +593,4 @@ public class BoardActivity extends Activity implements UtilCtxt {
|
|||
m_jniThread.handle( JNIThread.JNICmd.CMD_POST_OVER,
|
||||
R.string.finalscores_title );
|
||||
}
|
||||
|
||||
public BitmapDrawable makeBitmap( int width, int height, boolean[] colors )
|
||||
{
|
||||
Bitmap bitmap = Bitmap.createBitmap( width, height,
|
||||
Bitmap.Config.ARGB_8888 );
|
||||
|
||||
int indx = 0;
|
||||
for ( int yy = 0; yy < height; ++yy ) {
|
||||
for ( int xx = 0; xx < width; ++xx ) {
|
||||
boolean pixelSet = colors[indx++];
|
||||
bitmap.setPixel( xx, yy, pixelSet? 0xFF000000 : 0x00FFFFFF );
|
||||
}
|
||||
}
|
||||
|
||||
// Doesn't compile if pass getResources(). Maybe the
|
||||
// "deprecated" API is really the only one?
|
||||
return new BitmapDrawable( /*getResources(), */bitmap );
|
||||
}
|
||||
|
||||
/** Working around lack of utf8 support on the JNI side: given a
|
||||
* utf-8 string with embedded small number vals starting with 0,
|
||||
* convert into individual strings. The 0 is the problem: it's
|
||||
* not valid utf8. So turn it and the other nums into strings and
|
||||
* catch them on the other side.
|
||||
*/
|
||||
public String[] splitFaces( byte[] chars )
|
||||
{
|
||||
ArrayList<String> al = new ArrayList<String>();
|
||||
int ii = 0;
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream( chars );
|
||||
InputStreamReader isr = new InputStreamReader( bais );
|
||||
|
||||
int[] codePoints = new int[1];
|
||||
|
||||
for ( ; ; ) {
|
||||
int chr = -1;
|
||||
try {
|
||||
chr = isr.read();
|
||||
} catch ( java.io.IOException ioe ) {
|
||||
Utils.logf( ioe.toString() );
|
||||
}
|
||||
if ( -1 == chr ) {
|
||||
break;
|
||||
} else {
|
||||
String letter;
|
||||
if ( chr < 32 ) {
|
||||
letter = String.format( "%d", chr );
|
||||
} else {
|
||||
codePoints[0] = chr;
|
||||
letter = new String( codePoints, 0, 1 );
|
||||
}
|
||||
al.add( letter );
|
||||
}
|
||||
}
|
||||
|
||||
String[] result = al.toArray( new String[al.size()] );
|
||||
return result;
|
||||
}
|
||||
|
||||
} // class BoardActivity
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- compile-command: "cd ../../../../../; ant reinstall"; -*- */
|
||||
/* -*- compile-command: "cd ../../../../../; ant install"; -*- */
|
||||
|
||||
package org.eehouse.android.xw4;
|
||||
|
||||
|
@ -37,6 +37,7 @@ public class BoardView extends View implements DrawCtx,
|
|||
private String[] m_scores;
|
||||
private Rect m_boundsScratch;
|
||||
private String m_remText;
|
||||
private int m_dictPtr = 0;
|
||||
|
||||
private static final int BLACK = 0xFF000000;
|
||||
private static final int WHITE = 0xFFFFFFFF;
|
||||
|
@ -359,6 +360,22 @@ public class BoardView extends View implements DrawCtx,
|
|||
}
|
||||
}
|
||||
|
||||
public void dictChanged( int dictPtr )
|
||||
{
|
||||
Utils.logf( "BoardView::dictChanged" );
|
||||
if ( m_dictPtr != dictPtr ) {
|
||||
if ( m_dictPtr == 0 || !XwJNI.dict_tilesAreSame( m_dictPtr, dictPtr ) ) {
|
||||
String[] chars = XwJNI.dict_getChars( dictPtr );
|
||||
for ( String str : chars ) {
|
||||
if ( str.length() > 0 && str.charAt(0) >= 32 ) {
|
||||
Utils.logf( "got " + str );
|
||||
}
|
||||
}
|
||||
}
|
||||
m_dictPtr = dictPtr;
|
||||
}
|
||||
}
|
||||
|
||||
private void drawTileImpl( Rect rect, String text,
|
||||
BitmapDrawable[] bitmaps, int val,
|
||||
int flags, boolean clearBack )
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- compile-command: "cd ../../../../../; ant reinstall"; -*- */
|
||||
/* -*- compile-command: "cd ../../../../../; ant install"; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
|
@ -241,9 +241,10 @@ public class GameConfig extends Activity implements View.OnClickListener {
|
|||
byte[] dictBytes = Utils.openDict( this, m_gi.dictName );
|
||||
|
||||
int gamePtr = XwJNI.initJNI();
|
||||
if ( !XwJNI.game_makeFromStream( gamePtr, stream, m_gi, dictBytes,
|
||||
m_cp ) ) {
|
||||
XwJNI.game_makeNewGame( gamePtr, m_gi, m_cp, dictBytes );
|
||||
if ( !XwJNI.game_makeFromStream( gamePtr, stream, JNIUtilsImpl.get(),
|
||||
m_gi, dictBytes, m_cp ) ) {
|
||||
XwJNI.game_makeNewGame( gamePtr, m_gi, JNIUtilsImpl.get(),
|
||||
m_cp, dictBytes );
|
||||
}
|
||||
|
||||
int curSel = listAvailableDicts( m_gi.dictName );
|
||||
|
@ -616,7 +617,8 @@ public class GameConfig extends Activity implements View.OnClickListener {
|
|||
|
||||
byte[] dictBytes = Utils.openDict( this, m_gi.dictName );
|
||||
int gamePtr = XwJNI.initJNI();
|
||||
XwJNI.game_makeNewGame( gamePtr, m_gi, m_cp, dictBytes );
|
||||
XwJNI.game_makeNewGame( gamePtr, m_gi, JNIUtilsImpl.get(),
|
||||
m_cp, dictBytes );
|
||||
|
||||
if ( null != m_car ) {
|
||||
XwJNI.comms_setAddr( gamePtr, m_car );
|
||||
|
|
|
@ -77,7 +77,11 @@ public class CommonPrefs {
|
|||
{
|
||||
String key = s_context.getString( id );
|
||||
String val = sp.getString( key, "" );
|
||||
return 0xFF000000 | Integer.decode( val );
|
||||
try {
|
||||
return 0xFF000000 | Integer.decode( val );
|
||||
} catch ( java.lang.NumberFormatException nfe ) {
|
||||
return 0xFF7F7F7F;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -47,4 +47,6 @@ public interface DrawCtx {
|
|||
|
||||
void objFinished( /*BoardObjectType*/int typ, Rect rect, int dfs );
|
||||
|
||||
void dictChanged( int dictPtr );
|
||||
|
||||
}
|
||||
|
|
|
@ -61,7 +61,6 @@ public class JNIThread extends Thread {
|
|||
}
|
||||
|
||||
public JNIThread( int gamePtr, CurGameInfo gi, Handler handler ) {
|
||||
Utils.logf( "in JNIThread()" );
|
||||
m_jniGamePtr = gamePtr;
|
||||
m_gi = gi;
|
||||
m_handler = handler;
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
/* -*- compile-command: "cd ../../../../../../; ant install"; -*- */
|
||||
|
||||
package org.eehouse.android.xw4.jni;
|
||||
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
|
||||
public interface JNIUtils {
|
||||
|
||||
// Stuff I can't do in C....
|
||||
BitmapDrawable makeBitmap( int width, int height, boolean[] colors );
|
||||
String[] splitFaces( byte[] chars );
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/* -*- compile-command: "cd ../../../../../../; ant install"; -*- */
|
||||
|
||||
package org.eehouse.android.xw4.jni;
|
||||
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.Bitmap;
|
||||
import java.util.ArrayList;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import org.eehouse.android.xw4.*;
|
||||
|
||||
public class JNIUtilsImpl implements JNIUtils {
|
||||
|
||||
private static JNIUtils s_impl = null;
|
||||
|
||||
private JNIUtilsImpl(){}
|
||||
|
||||
public static JNIUtils get()
|
||||
{
|
||||
if ( null == s_impl ) {
|
||||
s_impl = new JNIUtilsImpl();
|
||||
}
|
||||
return s_impl;
|
||||
}
|
||||
|
||||
public BitmapDrawable makeBitmap( int width, int height, boolean[] colors )
|
||||
{
|
||||
Bitmap bitmap = Bitmap.createBitmap( width, height,
|
||||
Bitmap.Config.ARGB_8888 );
|
||||
|
||||
int indx = 0;
|
||||
for ( int yy = 0; yy < height; ++yy ) {
|
||||
for ( int xx = 0; xx < width; ++xx ) {
|
||||
boolean pixelSet = colors[indx++];
|
||||
bitmap.setPixel( xx, yy, pixelSet? 0xFF000000 : 0x00FFFFFF );
|
||||
}
|
||||
}
|
||||
|
||||
// Doesn't compile if pass getResources(). Maybe the
|
||||
// "deprecated" API is really the only one?
|
||||
return new BitmapDrawable( /*getResources(), */bitmap );
|
||||
}
|
||||
|
||||
/** Working around lack of utf8 support on the JNI side: given a
|
||||
* utf-8 string with embedded small number vals starting with 0,
|
||||
* convert into individual strings. The 0 is the problem: it's
|
||||
* not valid utf8. So turn it and the other nums into strings and
|
||||
* catch them on the other side.
|
||||
*/
|
||||
public String[] splitFaces( byte[] chars )
|
||||
{
|
||||
ArrayList<String> al = new ArrayList<String>();
|
||||
int ii = 0;
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream( chars );
|
||||
InputStreamReader isr = new InputStreamReader( bais );
|
||||
|
||||
int[] codePoints = new int[1];
|
||||
|
||||
for ( ; ; ) {
|
||||
int chr = -1;
|
||||
try {
|
||||
chr = isr.read();
|
||||
} catch ( java.io.IOException ioe ) {
|
||||
Utils.logf( ioe.toString() );
|
||||
}
|
||||
if ( -1 == chr ) {
|
||||
break;
|
||||
} else {
|
||||
String letter;
|
||||
if ( chr < 32 ) {
|
||||
letter = String.format( "%d", chr );
|
||||
} else {
|
||||
codePoints[0] = chr;
|
||||
letter = new String( codePoints, 0, 1 );
|
||||
}
|
||||
al.add( letter );
|
||||
}
|
||||
}
|
||||
|
||||
String[] result = al.toArray( new String[al.size()] );
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- compile-command: "cd ../../../../../../; ant reinstall"; -*- */
|
||||
/* -*- compile-command: "cd ../../../../../../; ant install"; -*- */
|
||||
|
||||
package org.eehouse.android.xw4.jni;
|
||||
|
||||
|
@ -81,12 +81,6 @@ public interface UtilCtxt {
|
|||
void userError( int id );
|
||||
|
||||
void notifyGameOver();
|
||||
|
||||
BitmapDrawable makeBitmap( int width, int height, boolean[] colors );
|
||||
|
||||
String[] splitFaces( byte[] chars );
|
||||
|
||||
// Don't need this unless we have a scroll thumb to indicate position
|
||||
//void yOffsetChange( int oldOffset, int newOffset );
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- compile-command: "cd ../../../../../../; ant reinstall"; -*- */
|
||||
/* -*- compile-command: "cd ../../../../../../; ant install"; -*- */
|
||||
|
||||
package org.eehouse.android.xw4.jni;
|
||||
|
||||
|
@ -28,6 +28,7 @@ public class XwJNI {
|
|||
public static native void game_makeNewGame( int gamePtr,
|
||||
CurGameInfo gi,
|
||||
UtilCtxt util,
|
||||
JNIUtils jniu,
|
||||
DrawCtx draw, CommonPrefs cp,
|
||||
TransportProcs procs,
|
||||
byte[] dict );
|
||||
|
@ -37,25 +38,29 @@ public class XwJNI {
|
|||
CurGameInfo gi,
|
||||
byte[] dict,
|
||||
UtilCtxt util,
|
||||
JNIUtils jniu,
|
||||
DrawCtx draw,
|
||||
CommonPrefs cp,
|
||||
TransportProcs procs );
|
||||
|
||||
// leave out options params for when game won't be rendered or
|
||||
// played
|
||||
public static void game_makeNewGame( int gamePtr, CurGameInfo gi,
|
||||
CommonPrefs cp, byte[] dict ) {
|
||||
game_makeNewGame( gamePtr, gi, (UtilCtxt)null,
|
||||
public static void game_makeNewGame( int gamePtr, CurGameInfo gi,
|
||||
JNIUtils jniu, CommonPrefs cp,
|
||||
byte[] dict ) {
|
||||
game_makeNewGame( gamePtr, gi, (UtilCtxt)null, jniu,
|
||||
(DrawCtx)null, cp, (TransportProcs)null, dict );
|
||||
}
|
||||
|
||||
public static boolean game_makeFromStream( int gamePtr,
|
||||
byte[] stream,
|
||||
JNIUtils jniu,
|
||||
CurGameInfo gi,
|
||||
byte[] dict,
|
||||
CommonPrefs cp ) {
|
||||
return game_makeFromStream( gamePtr, stream, gi, dict, (UtilCtxt)null,
|
||||
(DrawCtx)null, cp, (TransportProcs)null );
|
||||
jniu, (DrawCtx)null, cp,
|
||||
(TransportProcs)null );
|
||||
}
|
||||
|
||||
public static native boolean game_receiveMessage( int gamePtr,
|
||||
|
@ -119,4 +124,8 @@ public class XwJNI {
|
|||
public static native void comms_start( int gamePtr );
|
||||
public static native void comms_getAddr( int gamePtr, CommsAddrRec addr );
|
||||
public static native void comms_setAddr( int gamePtr, CommsAddrRec addr );
|
||||
|
||||
// Dicts
|
||||
public static native boolean dict_tilesAreSame( int dictPtr1, int dictPtr2 );
|
||||
public static native String[] dict_getChars( int dictPtr );
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ struct DictionaryCtxt {
|
|||
necessarily the entry point for search!! */
|
||||
XP_UCHAR* name;
|
||||
XP_UCHAR* faces;
|
||||
XP_UCHAR** facePtrs;
|
||||
const XP_UCHAR** facePtrs;
|
||||
XP_U8* countsAndValues;
|
||||
|
||||
SpecialBitmaps* bitmaps;
|
||||
|
|
Loading…
Reference in a new issue