implement util->dutil split for Android

So now all jni code uses a single dutil context, but also a single
mempool and jniutil instance instead of new instances of the latter two
per game and dict-iteration.
This commit is contained in:
Eric House 2018-07-05 08:32:19 -07:00
parent d4436b7706
commit ed90c9c16d
18 changed files with 440 additions and 375 deletions

View file

@ -175,8 +175,7 @@ public class DictBrowseDelegate extends DelegateBase
String[] names = { name };
DictUtils.DictPairs pairs = DictUtils.openDicts( m_activity, names );
m_dictClosure = XwJNI.dict_iter_init( pairs.m_bytes[0],
name, pairs.m_paths[0],
JNIUtilsImpl.get(m_activity) );
name, pairs.m_paths[0] );
m_browseState = DBUtils.dictsGetOffset( m_activity, name, m_loc );
boolean newState = null == m_browseState;

View file

@ -486,7 +486,6 @@ public class DictLangCache {
info = new DictInfo();
if ( XwJNI.dict_getInfo( pairs.m_bytes[0], dal.name,
pairs.m_paths[0],
JNIUtilsImpl.get( context ),
DictLoc.DOWNLOAD == dal.loc,
info ) ) {

View file

@ -574,7 +574,7 @@ public class DictUtils {
if ( ok && null != dir ) {
String fullPath = new File( dir, file ).getPath();
ok = XwJNI.dict_getInfo( null, removeDictExtn( file ), fullPath,
JNIUtilsImpl.get(context), true, null );
true, null );
}
return ok;
}

View file

@ -131,8 +131,8 @@ public class GameUtils {
gamePtr = XwJNI.initNew( gi, dictNames, pairs.m_bytes, pairs.m_paths,
gi.langName( context ), (UtilCtxt)null,
JNIUtilsImpl.get( context ), (DrawCtx)null,
CommonPrefs.get( context ), (TransportProcs)null );
(DrawCtx)null, CommonPrefs.get( context ),
(TransportProcs)null );
if ( juggle ) {
gi.juggle();
@ -372,15 +372,13 @@ public class GameUtils {
gamePtr = XwJNI.initFromStream( rowid, stream, gi, dictNames,
pairs.m_bytes, pairs.m_paths,
langName, util,
JNIUtilsImpl.get( context ),
null,
CommonPrefs.get(context),
tp );
if ( null == gamePtr ) {
gamePtr = XwJNI.initNew( gi, dictNames,
pairs.m_bytes, pairs.m_paths,
langName, (UtilCtxt)null,
JNIUtilsImpl.get(context), null,
langName, (UtilCtxt)null, null,
CommonPrefs.get(context), null );
}
}
@ -1024,8 +1022,7 @@ public class GameUtils {
XwJNI.initFromStream( rowid, stream, gi, dictNames,
pairs.m_bytes, pairs.m_paths,
gi.langName( context ), null,
JNIUtilsImpl.get(context), null,
CommonPrefs.get( context ), null );
null, CommonPrefs.get( context ), null );
// second time required as game_makeFromStream can overwrite
gi.replaceDicts( context, newDict );
@ -1075,8 +1072,7 @@ public class GameUtils {
new CurGameInfo(context),
dictNames, pairs.m_bytes,
pairs.m_paths, langName,
null, JNIUtilsImpl.get(context),
null, cp, null );
null, null, cp, null );
madeGame = null != gamePtr;
}
@ -1084,8 +1080,7 @@ public class GameUtils {
Assert.assertNull( gamePtr );
gamePtr = XwJNI.initNew( gi, dictNames, pairs.m_bytes,
pairs.m_paths, langName, util,
JNIUtilsImpl.get(context), (DrawCtx)null,
cp, sink );
(DrawCtx)null, cp, sink );
}
if ( null != car ) {

View file

@ -34,7 +34,7 @@ import org.eehouse.android.xw4.MultiService.DictFetchOwner;
import org.eehouse.android.xw4.MultiService.MultiEvent;
import org.eehouse.android.xw4.jni.CommsAddrRec;
import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType;
import org.eehouse.android.xw4.jni.UtilCtxt.DevIDType;
import org.eehouse.android.xw4.jni.DUtilCtxt.DevIDType;
import org.eehouse.android.xw4.jni.XwJNI;
import org.eehouse.android.xw4.loc.LocUtils;

View file

@ -0,0 +1,216 @@
/* -*- compile-command: "find-and-gradle.sh insXw4Deb"; -*- */
/*
* Copyright 2009-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.
*/
package org.eehouse.android.xw4.jni;
import android.content.Context;
import android.telephony.PhoneNumberUtils;
import junit.framework.Assert;
import org.eehouse.android.xw4.XWApp;
import org.eehouse.android.xw4.DevID;
import org.eehouse.android.xw4.R;
import org.eehouse.android.xw4.Log;
import org.eehouse.android.xw4.loc.LocUtils;
public class DUtilCtxt {
private static final String TAG = DUtilCtxt.class.getSimpleName();
private Context m_context;
public DUtilCtxt() {
m_context = XWApp.getContext();
}
// Possible values for typ[0], these must match enum in xwrelay.sh
public enum DevIDType { ID_TYPE_NONE
, ID_TYPE_RELAY
, ID_TYPE_LINUX
, ID_TYPE_ANDROID_GCM
, ID_TYPE_ANDROID_OTHER
, ID_TYPE_ANON
}
public String getDevID( /*out*/ byte[] typa )
{
DevIDType typ = DevIDType.ID_TYPE_NONE;
String result = DevID.getRelayDevID( m_context );
if ( null != result ) {
typ = DevIDType.ID_TYPE_RELAY;
} else {
result = DevID.getGCMDevID( m_context );
if ( result.equals("") ) {
result = null;
} else {
typ = DevIDType.ID_TYPE_ANDROID_GCM;
}
}
typa[0] = (byte)typ.ordinal();
return result;
}
public void deviceRegistered( DevIDType devIDType, String idRelay )
{
switch ( devIDType ) {
case ID_TYPE_RELAY:
DevID.setRelayDevID( m_context, idRelay );
break;
case ID_TYPE_NONE:
DevID.clearRelayDevID( m_context );
break;
default:
Assert.fail();
break;
}
}
static final int STRD_ROBOT_TRADED = 1;
static final int STR_ROBOT_MOVED = 2;
static final int STRS_VALUES_HEADER = 3;
static final int STRD_REMAINING_TILES_ADD = 4;
static final int STRD_UNUSED_TILES_SUB = 5;
static final int STRS_REMOTE_MOVED = 6;
static final int STRD_TIME_PENALTY_SUB = 7;
static final int STR_PASS = 8;
static final int STRS_MOVE_ACROSS = 9;
static final int STRS_MOVE_DOWN = 10;
static final int STRS_TRAY_AT_START = 11;
static final int STRSS_TRADED_FOR = 12;
static final int STR_PHONY_REJECTED = 13;
static final int STRD_CUMULATIVE_SCORE = 14;
static final int STRS_NEW_TILES = 15;
static final int STR_COMMIT_CONFIRM = 16;
static final int STR_BONUS_ALL = 17;
static final int STRD_TURN_SCORE = 18;
static final int STRD_REMAINS_HEADER = 19;
static final int STRD_REMAINS_EXPL = 20;
static final int STRSD_RESIGNED = 21;
static final int STRSD_WINNER = 22;
static final int STRDSD_PLACER = 23;
public String getUserString( int stringCode )
{
Log.d( TAG, "getUserString(%d)", stringCode );
int id = 0;
switch( stringCode ) {
case STR_ROBOT_MOVED:
id = R.string.str_robot_moved_fmt;
break;
case STRS_VALUES_HEADER:
id = R.string.strs_values_header_fmt;
break;
case STRD_REMAINING_TILES_ADD:
id = R.string.strd_remaining_tiles_add_fmt;
break;
case STRD_UNUSED_TILES_SUB:
id = R.string.strd_unused_tiles_sub_fmt;
break;
case STRS_REMOTE_MOVED:
id = R.string.str_remote_moved_fmt;
break;
case STRD_TIME_PENALTY_SUB:
id = R.string.strd_time_penalty_sub_fmt;
break;
case STR_PASS:
id = R.string.str_pass;
break;
case STRS_MOVE_ACROSS:
id = R.string.strs_move_across_fmt;
break;
case STRS_MOVE_DOWN:
id = R.string.strs_move_down_fmt;
break;
case STRS_TRAY_AT_START:
id = R.string.strs_tray_at_start_fmt;
break;
case STRSS_TRADED_FOR:
id = R.string.strss_traded_for_fmt;
break;
case STR_PHONY_REJECTED:
id = R.string.str_phony_rejected;
break;
case STRD_CUMULATIVE_SCORE:
id = R.string.strd_cumulative_score_fmt;
break;
case STRS_NEW_TILES:
id = R.string.strs_new_tiles_fmt;
break;
case STR_COMMIT_CONFIRM:
id = R.string.str_commit_confirm;
break;
case STR_BONUS_ALL:
id = R.string.str_bonus_all;
break;
case STRD_TURN_SCORE:
id = R.string.strd_turn_score_fmt;
break;
case STRSD_RESIGNED:
id = R.string.str_resigned_fmt;
break;
case STRSD_WINNER:
id = R.string.str_winner_fmt;
break;
case STRDSD_PLACER:
id = R.string.str_placer_fmt;
break;
default:
Log.w( TAG, "no such stringCode: %d", stringCode );
}
String result = (0 == id) ? "" : LocUtils.getString( m_context, id );
Log.d( TAG, "getUserString() => %s", result );
return result;
}
public String getUserQuantityString( int stringCode, int quantity )
{
int pluralsId = 0;
switch ( stringCode ) {
case STRD_ROBOT_TRADED:
pluralsId = R.plurals.strd_robot_traded_fmt;
break;
case STRD_REMAINS_HEADER:
pluralsId = R.plurals.strd_remains_header_fmt;
break;
case STRD_REMAINS_EXPL:
pluralsId = R.plurals.strd_remains_expl_fmt;
break;
}
String result = "";
if ( 0 != pluralsId ) {
result = LocUtils.getQuantityString( m_context, pluralsId, quantity );
}
return result;
}
public boolean phoneNumbersSame( String num1, String num2 )
{
boolean same = PhoneNumberUtils.compare( m_context, num1, num2 );
return same;
}
// SET_DPROC(getCurSeconds);
// SET_DPROC(md5sum);
}

View file

@ -212,7 +212,6 @@ public class JNIThread extends Thread {
}
CommonPrefs cp = CommonPrefs.get( context );
JNIUtils jniUtils = JNIUtilsImpl.get( context );
// Assert.assertNull( m_jniGamePtr ); // fired!!
if ( null != m_jniGamePtr ) {
@ -224,15 +223,13 @@ public class JNIThread extends Thread {
dictNames, pairs.m_bytes,
pairs.m_paths,
m_gi.langName( m_context ),
utils, jniUtils,
null, cp, m_xport );
utils, null, cp, m_xport );
}
if ( null == m_jniGamePtr ) {
m_jniGamePtr = XwJNI.initNew( m_gi, dictNames, pairs.m_bytes,
pairs.m_paths,
m_gi.langName(m_context),
utils, jniUtils, null, cp,
m_xport );
utils, null, cp, m_xport );
}
Assert.assertNotNull( m_jniGamePtr );
m_lastSavedState = Arrays.hashCode( stream );

View file

@ -25,6 +25,7 @@ import android.content.Context;
import junit.framework.Assert;
import org.eehouse.android.xw4.DBUtils;
import org.eehouse.android.xw4.XWApp;
import org.eehouse.android.xw4.Log;
import org.eehouse.android.xw4.Utils;
@ -41,14 +42,13 @@ public class JNIUtilsImpl implements JNIUtils {
private static JNIUtilsImpl s_impl = null;
private Context m_context;
private JNIUtilsImpl(){}
private JNIUtilsImpl(Context context) { m_context = context; }
public static JNIUtils get( Context context )
public static JNIUtils get()
{
if ( null == s_impl ) {
s_impl = new JNIUtilsImpl();
s_impl = new JNIUtilsImpl( XWApp.getContext() );
}
s_impl.m_context = context;
return s_impl;
}

View file

@ -60,50 +60,10 @@ public interface UtilCtxt {
void remSelected();
void setIsServer( boolean isServer );
// Possible values for typ[0], these must match enum in xwrelay.sh
public enum DevIDType { ID_TYPE_NONE
, ID_TYPE_RELAY
, ID_TYPE_LINUX
, ID_TYPE_ANDROID_GCM
, ID_TYPE_ANDROID_OTHER
, ID_TYPE_ANON
}
String getDevID( /*out*/ byte[] typ );
void deviceRegistered( DevIDType devIDType, String idRelay );
void bonusSquareHeld( int bonus );
void playerScoreHeld( int player );
void cellSquareHeld( String words );
static final int STRD_ROBOT_TRADED = 1;
static final int STR_ROBOT_MOVED = 2;
static final int STRS_VALUES_HEADER = 3;
static final int STRD_REMAINING_TILES_ADD = 4;
static final int STRD_UNUSED_TILES_SUB = 5;
static final int STRS_REMOTE_MOVED = 6;
static final int STRD_TIME_PENALTY_SUB = 7;
static final int STR_PASS = 8;
static final int STRS_MOVE_ACROSS = 9;
static final int STRS_MOVE_DOWN = 10;
static final int STRS_TRAY_AT_START = 11;
static final int STRSS_TRADED_FOR = 12;
static final int STR_PHONY_REJECTED = 13;
static final int STRD_CUMULATIVE_SCORE = 14;
static final int STRS_NEW_TILES = 15;
static final int STR_COMMIT_CONFIRM = 16;
static final int STR_BONUS_ALL = 17;
static final int STRD_TURN_SCORE = 18;
static final int STRD_REMAINS_HEADER = 19;
static final int STRD_REMAINS_EXPL = 20;
static final int STRSD_RESIGNED = 21;
static final int STRSD_WINNER = 22;
static final int STRDSD_PLACER = 23;
String getUserString( int stringCode );
String getUserQuantityString( int stringCode, int quantity );
void notifyMove( String query );
void notifyTrade( String[] tiles );
@ -146,6 +106,4 @@ public interface UtilCtxt {
boolean turnLost );
void showChat( String msg, int fromIndx, String fromName, int tsSeconds );
boolean phoneNumbersSame( String num1, String num2 );
}

View file

@ -21,16 +21,11 @@
package org.eehouse.android.xw4.jni;
import android.content.Context;
import android.telephony.PhoneNumberUtils;
import junit.framework.Assert;
import org.eehouse.android.xw4.DevID;
import org.eehouse.android.xw4.Log;
import org.eehouse.android.xw4.R;
import org.eehouse.android.xw4.XWApp;
import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnTypeSet;
import org.eehouse.android.xw4.loc.LocUtils;
public class UtilCtxtImpl implements UtilCtxt {
private static final String TAG = UtilCtxtImpl.class.getSimpleName();
@ -96,39 +91,6 @@ public class UtilCtxtImpl implements UtilCtxt {
subclassOverride( "setIsServer" );
}
public String getDevID( /*out*/ byte[] typa )
{
UtilCtxt.DevIDType typ = UtilCtxt.DevIDType.ID_TYPE_NONE;
String result = DevID.getRelayDevID( m_context );
if ( null != result ) {
typ = UtilCtxt.DevIDType.ID_TYPE_RELAY;
} else {
result = DevID.getGCMDevID( m_context );
if ( result.equals("") ) {
result = null;
} else {
typ = UtilCtxt.DevIDType.ID_TYPE_ANDROID_GCM;
}
}
typa[0] = (byte)typ.ordinal();
return result;
}
public void deviceRegistered( UtilCtxt.DevIDType devIDType, String idRelay )
{
switch ( devIDType ) {
case ID_TYPE_RELAY:
DevID.setRelayDevID( m_context, idRelay );
break;
case ID_TYPE_NONE:
DevID.clearRelayDevID( m_context );
break;
default:
Assert.fail();
break;
}
}
public void bonusSquareHeld( int bonus )
{
}
@ -141,101 +103,6 @@ public class UtilCtxtImpl implements UtilCtxt {
{
}
public String getUserString( int stringCode )
{
int id = 0;
switch( stringCode ) {
case UtilCtxt.STR_ROBOT_MOVED:
id = R.string.str_robot_moved_fmt;
break;
case UtilCtxt.STRS_VALUES_HEADER:
id = R.string.strs_values_header_fmt;
break;
case UtilCtxt.STRD_REMAINING_TILES_ADD:
id = R.string.strd_remaining_tiles_add_fmt;
break;
case UtilCtxt.STRD_UNUSED_TILES_SUB:
id = R.string.strd_unused_tiles_sub_fmt;
break;
case UtilCtxt.STRS_REMOTE_MOVED:
id = R.string.str_remote_moved_fmt;
break;
case UtilCtxt.STRD_TIME_PENALTY_SUB:
id = R.string.strd_time_penalty_sub_fmt;
break;
case UtilCtxt.STR_PASS:
id = R.string.str_pass;
break;
case UtilCtxt.STRS_MOVE_ACROSS:
id = R.string.strs_move_across_fmt;
break;
case UtilCtxt.STRS_MOVE_DOWN:
id = R.string.strs_move_down_fmt;
break;
case UtilCtxt.STRS_TRAY_AT_START:
id = R.string.strs_tray_at_start_fmt;
break;
case UtilCtxt.STRSS_TRADED_FOR:
id = R.string.strss_traded_for_fmt;
break;
case UtilCtxt.STR_PHONY_REJECTED:
id = R.string.str_phony_rejected;
break;
case UtilCtxt.STRD_CUMULATIVE_SCORE:
id = R.string.strd_cumulative_score_fmt;
break;
case UtilCtxt.STRS_NEW_TILES:
id = R.string.strs_new_tiles_fmt;
break;
case UtilCtxt.STR_COMMIT_CONFIRM:
id = R.string.str_commit_confirm;
break;
case UtilCtxt.STR_BONUS_ALL:
id = R.string.str_bonus_all;
break;
case UtilCtxt.STRD_TURN_SCORE:
id = R.string.strd_turn_score_fmt;
break;
case UtilCtxt.STRSD_RESIGNED:
id = R.string.str_resigned_fmt;
break;
case UtilCtxt.STRSD_WINNER:
id = R.string.str_winner_fmt;
break;
case UtilCtxt.STRDSD_PLACER:
id = R.string.str_placer_fmt;
break;
default:
Log.w( TAG, "no such stringCode: %d", stringCode );
}
String result = (0 == id) ? "" : LocUtils.getString( m_context, id );
return result;
}
public String getUserQuantityString( int stringCode, int quantity )
{
int pluralsId = 0;
switch ( stringCode ) {
case UtilCtxt.STRD_ROBOT_TRADED:
pluralsId = R.plurals.strd_robot_traded_fmt;
break;
case UtilCtxt.STRD_REMAINS_HEADER:
pluralsId = R.plurals.strd_remains_header_fmt;
break;
case UtilCtxt.STRD_REMAINS_EXPL:
pluralsId = R.plurals.strd_remains_expl_fmt;
break;
}
String result = "";
if ( 0 != pluralsId ) {
result = LocUtils.getQuantityString( m_context, pluralsId, quantity );
}
return result;
}
public void notifyMove( String query )
{
subclassOverride( "notifyMove" );
@ -293,12 +160,6 @@ public class UtilCtxtImpl implements UtilCtxt {
subclassOverride( "showChat" );
}
public boolean phoneNumbersSame( String num1, String num2 )
{
boolean same = PhoneNumberUtils.compare( m_context, num1, num2 );
return same;
}
private void subclassOverride( String name ) {
// DbgUtils.logf( "%s::%s() called", getClass().getName(), name );
}

View file

@ -1,7 +1,7 @@
/* -*- compile-command: "find-and-gradle.sh insXw4Deb"; -*- */
/*
* Copyright 2009-2010 by Eric House (xwords@eehouse.org). All
* rights reserved.
* Copyright 2009 - 2018 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
@ -97,7 +97,7 @@ public class XwJNI {
private int m_ptr;
private XwJNI()
{
m_ptr = initGlobals();
m_ptr = initGlobals( new DUtilCtxt(), JNIUtilsImpl.get() );
}
public static void cleanGlobals()
@ -167,8 +167,7 @@ public class XwJNI {
private static GamePtr initJNI( long rowid )
{
int seed = Utils.nextRandomInt();
String tag = String.format( "%d", rowid );
int ptr = initJNI( getJNI().m_ptr, seed, tag );
int ptr = initJNI( getJNI().m_ptr, seed );
GamePtr result = 0 == ptr ? null : new GamePtr( ptr, rowid );
return result;
}
@ -177,13 +176,13 @@ public class XwJNI {
initFromStream( long rowid, byte[] stream, CurGameInfo gi,
String[] dictNames, byte[][] dictBytes,
String[] dictPaths, String langName,
UtilCtxt util, JNIUtils jniu, DrawCtx draw,
UtilCtxt util, DrawCtx draw,
CommonPrefs cp, TransportProcs procs )
{
GamePtr gamePtr = initJNI( rowid );
if ( game_makeFromStream( gamePtr, stream, gi, dictNames, dictBytes,
dictPaths, langName, util, jniu, draw,
dictPaths, langName, util, draw,
cp, procs ) ) {
gamePtr.retain();
} else {
@ -196,12 +195,11 @@ public class XwJNI {
public static synchronized GamePtr
initNew( CurGameInfo gi, String[] dictNames, byte[][] dictBytes,
String[] dictPaths, String langName, UtilCtxt util,
JNIUtils jniu, DrawCtx draw, CommonPrefs cp,
TransportProcs procs )
DrawCtx draw, CommonPrefs cp, TransportProcs procs )
{
GamePtr gamePtr = initJNI( 0 );
game_makeNewGame( gamePtr, gi, dictNames, dictBytes, dictPaths,
langName, util, jniu, draw, cp, procs );
langName, util, draw, cp, procs );
return gamePtr.retain();
}
@ -218,7 +216,6 @@ public class XwJNI {
String[] dictPaths,
String langName,
UtilCtxt util,
JNIUtils jniu,
DrawCtx draw, CommonPrefs cp,
TransportProcs procs );
@ -230,7 +227,6 @@ public class XwJNI {
String[] dictPaths,
String langName,
UtilCtxt util,
JNIUtils jniu,
DrawCtx draw,
CommonPrefs cp,
TransportProcs procs );
@ -446,12 +442,10 @@ public class XwJNI {
public static native boolean dict_tilesAreSame( int dict1, int dict2 );
public static native String[] dict_getChars( int dict );
public static boolean dict_getInfo( byte[] dict, String name,
String path, JNIUtils jniu,
public static boolean dict_getInfo( byte[] dict, String name, String path,
boolean check, DictInfo info )
{
return dict_getInfo( getJNI().m_ptr, dict, name, path, jniu,
check, info );
return dict_getInfo( getJNI().m_ptr, dict, name, path, check, info );
}
public static native int dict_getTileValue( int dictPtr, int tile );
@ -459,9 +453,9 @@ public class XwJNI {
// Dict iterator
public final static int MAX_COLS_DICT = 15; // from dictiter.h
public static int dict_iter_init( byte[] dict, String name,
String path, JNIUtils jniu )
String path )
{
return dict_iter_init( getJNI().m_ptr, dict, name, path, jniu );
return dict_iter_init( getJNI().m_ptr, dict, name, path );
}
public static native void dict_iter_setMinMax( int closure,
int min, int max );
@ -476,7 +470,7 @@ public class XwJNI {
public static native String dict_iter_getDesc( int closure );
// Private methods -- called only here
private static native int initGlobals();
private static native int initGlobals(DUtilCtxt dutil, JNIUtils jniu);
private static native void cleanGlobals( int jniState );
private static native byte[] gi_to_stream( int jniState, CurGameInfo gi );
private static native void gi_from_stream( int jniState, CurGameInfo gi,
@ -484,17 +478,16 @@ public class XwJNI {
private static native byte[] nli_to_stream( int jniState, NetLaunchInfo nli );
private static native void nli_from_stream( int jniState, NetLaunchInfo nli,
byte[] stream );
private static native int initJNI( int jniState, int seed, String tag );
private static native int initJNI( int jniState, int seed );
private static native void envDone( int globals );
private static native void dict_ref( int dictPtr );
private static native void dict_unref( int dictPtr );
private static native boolean dict_getInfo( int jniState, byte[] dict,
String name, String path,
JNIUtils jniu, boolean check,
boolean check,
DictInfo info );
private static native int dict_iter_init( int jniState, byte[] dict,
String name, String path,
JNIUtils jniu );
String name, String path );
private static native boolean haveEnv( int jniState );
}

View file

@ -26,15 +26,16 @@
typedef struct _JNIState JNIState;
typedef struct _AndGlobals {
typedef struct _AndGameGlobals {
VTableMgr* vtMgr;
CurGameInfo* gi;
DrawCtx* dctx;
XW_UtilCtxt* util;
struct JNIUtilCtxt* jniutil;
TransportProcs* xportProcs;
XW_DUtilCtxt* dutil;
JNIState* state;
} AndGlobals;
} AndGameGlobals;
typedef struct _EnvThreadInfo EnvThreadInfo;

View file

@ -689,7 +689,7 @@ jEnumToInt( JNIEnv* env, jobject jenum )
}
XWStreamCtxt*
and_empty_stream( MPFORMAL AndGlobals* globals )
and_empty_stream( MPFORMAL AndGameGlobals* globals )
{
XWStreamCtxt* stream = mem_stream_make( MPPARM(mpool) globals->vtMgr,
globals, 0, NULL );

View file

@ -31,7 +31,7 @@
/* callback for streams */
void and_send_on_close( XWStreamCtxt* stream, void* closure );
XWStreamCtxt* and_empty_stream( MPFORMAL AndGlobals* globals );
XWStreamCtxt* and_empty_stream( MPFORMAL AndGameGlobals* globals );
typedef struct _SetInfo {
const char* name;

View file

@ -30,6 +30,18 @@
#define MAX_QUANTITY_STRS 4
typedef struct _AndDUtil {
XW_DUtilCtxt dutil;
EnvThreadInfo* ti;
JNIUtilCtxt* jniutil;
jobject jdutil; /* global ref to object implementing XW_DUtilCtxt */
XP_UCHAR* userStrings[N_AND_USER_STRINGS];
XP_U32 userStringsBits;
#ifdef XWFEATURE_DEVID
XP_UCHAR* devIDStorage;
#endif
} AndDUtil;
typedef struct _TimerStorage {
XWTimerProc proc;
void* closure;
@ -40,21 +52,8 @@ typedef struct _AndUtil {
EnvThreadInfo* ti;
jobject jutil; /* global ref to object implementing XW_UtilCtxt */
TimerStorage timerStorage[NUM_TIMERS_PLUS_ONE];
XP_UCHAR* userStrings[N_AND_USER_STRINGS];
XP_U32 userStringsBits;
#ifdef XWFEATURE_DEVID
XP_UCHAR* devIDStorage;
#endif
} AndUtil;
static VTableMgr*
and_util_getVTManager( XW_UtilCtxt* uc )
{
AndGlobals* globals = (AndGlobals*)uc->closure;
return globals->vtMgr;
}
#ifndef XWFEATURE_STANDALONE_ONLY
static XWStreamCtxt*
and_util_makeStreamFromAddr( XW_UtilCtxt* uc, XP_PlayerAddr channelNo )
@ -62,7 +61,7 @@ and_util_makeStreamFromAddr( XW_UtilCtxt* uc, XP_PlayerAddr channelNo )
#ifdef DEBUG
AndUtil* util = (AndUtil*)uc;
#endif
AndGlobals* globals = (AndGlobals*)uc->closure;
AndGameGlobals* globals = (AndGameGlobals*)uc->closure;
XWStreamCtxt* stream = and_empty_stream( MPPARM(util->util.mpool)
globals );
stream_setAddress( stream, channelNo );
@ -82,6 +81,14 @@ and_util_makeStreamFromAddr( XW_UtilCtxt* uc, XP_PlayerAddr channelNo )
XP_LOGF( "%s: skipping call into java because jutil==NULL", \
__func__ ); \
}
#define DUTIL_CBK_HEADER(nam,sig) \
AndDUtil* dutil = (AndDUtil*)duc; \
JNIEnv* env = ENVFORME( dutil->ti ); \
if ( NULL != dutil->jdutil ) { \
jmethodID mid = getMethodID( env, dutil->jdutil, nam, sig )
#define DUTIL_CBK_TAIL() UTIL_CBK_TAIL()
static XWBonusType and_util_getSquareBonus( XW_UtilCtxt* XP_UNUSED(uc),
XP_U16 boardSize,
@ -349,26 +356,24 @@ and_util_altKeyDown( XW_UtilCtxt* uc )
return XP_FALSE;
}
XP_U32
and_util_getCurSeconds( XW_UtilCtxt* uc )
and_dutil_getCurSeconds( XW_DUtilCtxt* duc )
{
AndUtil* andutil = (AndUtil*)uc;
XP_U32 curSeconds = getCurSeconds( ENVFORME( andutil->ti ) );
AndDUtil* anddutil = (AndDUtil*)duc;
XP_U32 curSeconds = getCurSeconds( ENVFORME( anddutil->ti ) );
/* struct timeval tv; */
/* gettimeofday( &tv, NULL ); */
/* XP_LOGF( "%s: %d vs %d", __func__, (int)tv.tv_sec, (int)curSeconds ); */
return curSeconds;
}
static DictionaryCtxt*
and_util_makeEmptyDict( XW_UtilCtxt* uc )
{
#ifdef STUBBED_DICT
XP_ASSERT(0);
#else
AndGlobals* globals = (AndGlobals*)uc->closure;
AndGameGlobals* globals = (AndGameGlobals*)uc->closure;
AndUtil* andutil = (AndUtil*)uc;
DictionaryCtxt* result =
and_dictionary_make_empty( MPPARM( ((AndUtil*)uc)->util.mpool )
@ -378,51 +383,51 @@ and_util_makeEmptyDict( XW_UtilCtxt* uc )
}
static const XP_UCHAR*
and_util_getUserString( XW_UtilCtxt* uc, XP_U16 stringCode )
and_dutil_getUserString( XW_DUtilCtxt* duc, XP_U16 stringCode )
{
XP_UCHAR* result = "";
UTIL_CBK_HEADER("getUserString", "(I)Ljava/lang/String;" );
DUTIL_CBK_HEADER("getUserString", "(I)Ljava/lang/String;" );
int index = stringCode - 1; /* see LocalizedStrIncludes.h */
XP_ASSERT( index < VSIZE( util->userStrings ) );
XP_ASSERT( index < VSIZE( dutil->userStrings ) );
XP_ASSERT( 0 == (util->userStringsBits & (1 << index)) );
XP_ASSERT( 0 == (dutil->userStringsBits & (1 << index)) );
if ( ! util->userStrings[index] ) {
jstring jresult = (*env)->CallObjectMethod( env, util->jutil, mid,
if ( ! dutil->userStrings[index] ) {
jstring jresult = (*env)->CallObjectMethod( env, dutil->jdutil, mid,
stringCode );
jsize len = (*env)->GetStringUTFLength( env, jresult );
XP_UCHAR* buf = XP_MALLOC( util->util.mpool, len + 1 );
XP_UCHAR* buf = XP_MALLOC( dutil->dutil.mpool, len + 1 );
const char* jchars = (*env)->GetStringUTFChars( env, jresult, NULL );
XP_MEMCPY( buf, jchars, len );
buf[len] = '\0';
(*env)->ReleaseStringUTFChars( env, jresult, jchars );
deleteLocalRef( env, jresult );
util->userStrings[index] = buf;
dutil->userStrings[index] = buf;
}
result = util->userStrings[index];
UTIL_CBK_TAIL();
result = dutil->userStrings[index];
DUTIL_CBK_TAIL();
return result;
}
static const XP_UCHAR*
and_util_getUserQuantityString( XW_UtilCtxt* uc, XP_U16 stringCode, XP_U16 quantity )
and_dutil_getUserQuantityString( XW_DUtilCtxt* duc, XP_U16 stringCode, XP_U16 quantity )
{
XP_UCHAR* result = "";
UTIL_CBK_HEADER("getUserQuantityString", "(II)Ljava/lang/String;" );
DUTIL_CBK_HEADER("getUserQuantityString", "(II)Ljava/lang/String;" );
int index = stringCode - 1; /* see LocalizedStrIncludes.h */
XP_ASSERT( index < VSIZE( util->userStrings ) );
XP_ASSERT( index < VSIZE( dutil->userStrings ) );
XP_UCHAR** ptrs;
util->userStringsBits |= 1 << index;
ptrs = (XP_UCHAR**)util->userStrings[index];
dutil->userStringsBits |= 1 << index;
ptrs = (XP_UCHAR**)dutil->userStrings[index];
if ( !ptrs ) {
ptrs = (XP_UCHAR**)XP_CALLOC( util->util.mpool, MAX_QUANTITY_STRS * sizeof(*ptrs) );
util->userStrings[index] = (XP_UCHAR*)ptrs;
ptrs = (XP_UCHAR**)XP_CALLOC( dutil->dutil.mpool, MAX_QUANTITY_STRS * sizeof(*ptrs) );
dutil->userStrings[index] = (XP_UCHAR*)ptrs;
}
jstring jresult = (*env)->CallObjectMethod( env, util->jutil, mid,
jstring jresult = (*env)->CallObjectMethod( env, dutil->jdutil, mid,
stringCode, quantity );
const char* jchars = (*env)->GetStringUTFChars( env, jresult, NULL );
int indx = 0;
@ -439,7 +444,7 @@ and_util_getUserQuantityString( XW_UtilCtxt* uc, XP_U16 stringCode, XP_U16 quant
if ( !ptrs[indx] ) {
XP_ASSERT( indx < MAX_QUANTITY_STRS );
jsize len = (*env)->GetStringUTFLength( env, jresult );
XP_UCHAR* buf = XP_MALLOC( util->util.mpool, len + 1 );
XP_UCHAR* buf = XP_MALLOC( dutil->dutil.mpool, len + 1 );
XP_MEMCPY( buf, jchars, len );
buf[len] = '\0';
ptrs[indx] = buf;
@ -449,7 +454,7 @@ and_util_getUserQuantityString( XW_UtilCtxt* uc, XP_U16 stringCode, XP_U16 quant
deleteLocalRef( env, jresult );
result = ptrs[indx];
UTIL_CBK_TAIL();
DUTIL_CBK_TAIL();
return result;
}
@ -519,18 +524,18 @@ and_util_playerScoreHeld( XW_UtilCtxt* uc, XP_U16 player )
#ifdef XWFEATURE_SMS
static XP_Bool
and_util_phoneNumbersSame( XW_UtilCtxt* uc, const XP_UCHAR* p1,
const XP_UCHAR* p2 )
and_dutil_phoneNumbersSame( XW_DUtilCtxt* duc, const XP_UCHAR* p1,
const XP_UCHAR* p2 )
{
XP_Bool same = 0 == strcmp( p1, p2 );
if ( !same ) {
UTIL_CBK_HEADER( "phoneNumbersSame",
"(Ljava/lang/String;Ljava/lang/String;)Z" );
DUTIL_CBK_HEADER( "phoneNumbersSame",
"(Ljava/lang/String;Ljava/lang/String;)Z" );
jstring js1 = (*env)->NewStringUTF( env, p1 );
jstring js2 = (*env)->NewStringUTF( env, p2 );
same = (*env)->CallBooleanMethod( env, util->jutil, mid, js1, js2 );
same = (*env)->CallBooleanMethod( env, dutil->jdutil, mid, js1, js2 );
deleteLocalRefs( env, js1, js2, DELETE_NO_REF );
UTIL_CBK_TAIL();
DUTIL_CBK_TAIL();
}
return same;
}
@ -576,61 +581,61 @@ and_util_addrChange( XW_UtilCtxt* uc, const CommsAddrRec* oldAddr,
}
static void
and_util_setIsServer(XW_UtilCtxt* uc, XP_Bool isServer )
and_util_setIsServer( XW_UtilCtxt* uc, XP_Bool isServer )
{
/* Change both the C and Java structs, which need to stay in sync */
uc->gameInfo->serverRole = isServer? SERVER_ISSERVER : SERVER_ISCLIENT;
UTIL_CBK_HEADER("setIsServer", "(Z)V" );
UTIL_CBK_HEADER( "setIsServer", "(Z)V" );
(*env)->CallVoidMethod( env, util->jutil, mid, isServer );
UTIL_CBK_TAIL();
}
#ifdef XWFEATURE_DEVID
static const XP_UCHAR*
and_util_getDevID( XW_UtilCtxt* uc, DevIDType* typ )
and_dutil_getDevID( XW_DUtilCtxt* duc, DevIDType* typ )
{
const XP_UCHAR* result = NULL;
*typ = ID_TYPE_NONE;
UTIL_CBK_HEADER( "getDevID", "([B)Ljava/lang/String;" );
DUTIL_CBK_HEADER( "getDevID", "([B)Ljava/lang/String;" );
jbyteArray jbarr = makeByteArray( env, 1, NULL );
jstring jresult = (*env)->CallObjectMethod( env, util->jutil, mid, jbarr );
jstring jresult = (*env)->CallObjectMethod( env, dutil->jdutil, mid, jbarr );
if ( NULL != jresult ) {
const char* jchars = (*env)->GetStringUTFChars( env, jresult, NULL );
jsize len = (*env)->GetStringUTFLength( env, jresult );
if ( NULL != util->devIDStorage
&& 0 == XP_MEMCMP( util->devIDStorage, jchars, len ) ) {
if ( NULL != dutil->devIDStorage
&& 0 == XP_MEMCMP( dutil->devIDStorage, jchars, len ) ) {
XP_LOGF( "%s: already have matching devID", __func__ );
} else {
XP_LOGF( "%s: allocating storage for devID", __func__ );
XP_FREEP( util->util.mpool, &util->devIDStorage );
util->devIDStorage = XP_MALLOC( util->util.mpool, len + 1 );
XP_MEMCPY( util->devIDStorage, jchars, len );
util->devIDStorage[len] = '\0';
XP_FREEP( dutil->dutil.mpool, &dutil->devIDStorage );
dutil->devIDStorage = XP_MALLOC( dutil->dutil.mpool, len + 1 );
XP_MEMCPY( dutil->devIDStorage, jchars, len );
dutil->devIDStorage[len] = '\0';
}
(*env)->ReleaseStringUTFChars( env, jresult, jchars );
result = (const XP_UCHAR*)util->devIDStorage;
result = (const XP_UCHAR*)dutil->devIDStorage;
jbyte* elems = (*env)->GetByteArrayElements( env, jbarr, NULL );
*typ = (DevIDType)elems[0];
(*env)->ReleaseByteArrayElements( env, jbarr, elems, 0 );
}
deleteLocalRef( env, jbarr );
UTIL_CBK_TAIL();
DUTIL_CBK_TAIL();
return result;
}
static void
and_util_deviceRegistered( XW_UtilCtxt* uc, DevIDType typ,
const XP_UCHAR* idRelay )
and_dutil_deviceRegistered( XW_DUtilCtxt* duc, DevIDType typ,
const XP_UCHAR* idRelay )
{
UTIL_CBK_HEADER( "deviceRegistered",
"(L" PKG_PATH("jni/UtilCtxt$DevIDType") ";Ljava/lang/String;)V" );
DUTIL_CBK_HEADER( "deviceRegistered",
"(L" PKG_PATH("jni/UtilCtxt$DevIDType") ";Ljava/lang/String;)V" );
jstring jstr = (*env)->NewStringUTF( env, idRelay );
jobject jtyp = intToJEnum( env, typ,
PKG_PATH("jni/UtilCtxt$DevIDType") );
(*env)->CallVoidMethod( env, util->jutil, mid, jtyp, jstr );
(*env)->CallVoidMethod( env, dutil->jdutil, mid, jtyp, jstr );
deleteLocalRefs( env, jstr, jtyp, DELETE_NO_REF );
UTIL_CBK_TAIL();
DUTIL_CBK_TAIL();
}
#endif /* XWFEATURE_DEVID */
@ -664,16 +669,24 @@ and_util_engineStopping( XW_UtilCtxt* uc )
}
#endif
static XW_DUtilCtxt*
and_util_getDevUtilCtxt( XW_UtilCtxt* uc )
{
LOG_FUNC();
AndGameGlobals* globals = (AndGameGlobals*)uc->closure;
XP_ASSERT( !!globals->dutil );
return globals->dutil;
}
#ifdef COMMS_CHECKSUM
static XP_UCHAR*
and_util_md5sum( XW_UtilCtxt* uc, const XP_U8* ptr, XP_U16 len )
and_dutil_md5sum( XW_DUtilCtxt* duc, const XP_U8* ptr, XP_U16 len )
{
AndUtil* util = (AndUtil*)uc;
JNIEnv* env = ENVFORME( util->ti );
AndGlobals* globals = (AndGlobals*)uc->closure;
struct JNIUtilCtxt* jniutil = globals->jniutil;
AndDUtil* dutil = (AndDUtil*)duc;
JNIEnv* env = ENVFORME( dutil->ti );
struct JNIUtilCtxt* jniutil = dutil->jniutil;
jstring jsum = and_util_getMD5SumForBytes( jniutil, ptr, len );
XP_UCHAR* result = getStringCopy( MPPARM(uc->mpool) env, jsum );
XP_UCHAR* result = getStringCopy( MPPARM(duc->mpool) env, jsum );
deleteLocalRef( env, jsum );
return result;
}
@ -681,8 +694,8 @@ and_util_md5sum( XW_UtilCtxt* uc, const XP_U8* ptr, XP_U16 len )
XW_UtilCtxt*
makeUtil( MPFORMAL EnvThreadInfo* ti, jobject jutil, CurGameInfo* gi,
AndGlobals* closure )
makeUtil( MPFORMAL EnvThreadInfo* ti, jobject jutil, CurGameInfo* gi,
AndGameGlobals* closure )
{
AndUtil* util = (AndUtil*)XP_CALLOC( mpool, sizeof(*util) );
UtilVtable* vtable = (UtilVtable*)XP_CALLOC( mpool, sizeof(*vtable) );
@ -697,7 +710,7 @@ makeUtil( MPFORMAL EnvThreadInfo* ti, jobject jutil, CurGameInfo* gi,
util->util.gameInfo = gi;
#define SET_PROC(nam) vtable->m_util_##nam = and_util_##nam
SET_PROC(getVTManager);
#ifndef XWFEATURE_STANDALONE_ONLY
SET_PROC(makeStreamFromAddr);
#endif
@ -725,10 +738,7 @@ makeUtil( MPFORMAL EnvThreadInfo* ti, jobject jutil, CurGameInfo* gi,
SET_PROC(clearTimer);
SET_PROC(requestTime);
SET_PROC(altKeyDown);
SET_PROC(getCurSeconds);
SET_PROC(makeEmptyDict);
SET_PROC(getUserString);
SET_PROC(getUserQuantityString);
SET_PROC(notifyIllegalWords);
#ifdef XWFEATURE_CHAT
SET_PROC(showChat);
@ -740,10 +750,6 @@ makeUtil( MPFORMAL EnvThreadInfo* ti, jobject jutil, CurGameInfo* gi,
SET_PROC(playerScoreHeld);
#endif
#ifdef XWFEATURE_SMS
SET_PROC(phoneNumbersSame);
#endif
#ifdef XWFEATURE_BOARDWORDS
SET_PROC(cellSquareHeld);
#endif
@ -752,10 +758,6 @@ makeUtil( MPFORMAL EnvThreadInfo* ti, jobject jutil, CurGameInfo* gi,
SET_PROC(informMissing);
SET_PROC(addrChange);
SET_PROC(setIsServer);
# ifdef XWFEATURE_DEVID
SET_PROC(getDevID);
SET_PROC(deviceRegistered);
# endif
#endif
#ifdef XWFEATURE_SEARCHLIMIT
SET_PROC(getTraySearchLimits);
@ -764,9 +766,8 @@ makeUtil( MPFORMAL EnvThreadInfo* ti, jobject jutil, CurGameInfo* gi,
SET_PROC(engineStarting);
SET_PROC(engineStopping);
#endif
#ifdef COMMS_CHECKSUM
SET_PROC(md5sum);
#endif
SET_PROC(getDevUtilCtxt);
#undef SET_PROC
return (XW_UtilCtxt*)util;
@ -778,31 +779,77 @@ destroyUtil( XW_UtilCtxt** utilc )
AndUtil* util = (AndUtil*)*utilc;
JNIEnv* env = ENVFORME( util->ti );
for ( int ii = 0; ii < VSIZE(util->userStrings); ++ii ) {
XP_UCHAR* ptr = util->userStrings[ii];
if ( NULL != util->jutil ) {
(*env)->DeleteGlobalRef( env, util->jutil );
}
XP_FREE( util->util.mpool, util->util.vtable );
XP_FREE( util->util.mpool, util );
*utilc = NULL;
}
XW_DUtilCtxt*
makeDUtil( MPFORMAL EnvThreadInfo* ti, jobject jdutil, VTableMgr* vtMgr,
JNIUtilCtxt* jniutil, void* closure )
{
AndDUtil* dutil = (AndDUtil*)XP_CALLOC( mpool, sizeof(*dutil) );
dutil->ti = ti;
dutil->jniutil = jniutil;
dutil->dutil.closure = closure;
dutil->dutil.vtMgr = vtMgr;
if ( NULL != jdutil ) {
JNIEnv* env = ENVFORME( ti );
dutil->jdutil = (*env)->NewGlobalRef( env, jdutil );
}
MPASSIGN( dutil->dutil.mpool, mpool );
DUtilVtable* vtable = &dutil->dutil.vtable;
#define SET_DPROC(nam) vtable->m_dutil_##nam = and_dutil_##nam
SET_DPROC(getCurSeconds);
SET_DPROC(getUserString);
SET_DPROC(getUserQuantityString);
# ifdef XWFEATURE_DEVID
SET_DPROC(getDevID);
SET_DPROC(deviceRegistered);
# endif
#ifdef XWFEATURE_SMS
SET_DPROC(phoneNumbersSame);
#endif
#ifdef COMMS_CHECKSUM
SET_DPROC(md5sum);
#endif
return &dutil->dutil;
}
void
destroyDUtil( XW_DUtilCtxt** dutilp )
{
AndDUtil* dutil = (AndDUtil*)*dutilp;
JNIEnv* env = ENVFORME( dutil->ti );
if ( NULL != dutil->jdutil ) {
(*env)->DeleteGlobalRef( env, dutil->jdutil );
}
for ( int ii = 0; ii < VSIZE(dutil->userStrings); ++ii ) {
XP_UCHAR* ptr = dutil->userStrings[ii];
if ( NULL != ptr ) {
if ( 0 == (util->userStringsBits & (1 << ii)) ) {
XP_FREE( util->util.mpool, ptr );
if ( 0 == (dutil->userStringsBits & (1 << ii)) ) {
XP_FREE( dutil->dutil.mpool, ptr );
} else {
XP_UCHAR** ptrs = (XP_UCHAR**)ptr;
for ( int jj = 0; jj < MAX_QUANTITY_STRS; ++jj ) {
ptr = ptrs[jj];
if ( !!ptr ) {
XP_FREE( util->util.mpool, ptr );
XP_FREE( dutil->dutil.mpool, ptr );
}
}
XP_FREE( util->util.mpool, ptrs );
XP_FREE( dutil->dutil.mpool, ptrs );
}
}
}
if ( NULL != util->jutil ) {
(*env)->DeleteGlobalRef( env, util->jutil );
}
#ifdef XWFEATURE_DEVID
XP_FREEP( util->util.mpool, &util->devIDStorage );
XP_FREEP( dutil->dutil.mpool, &dutil->devIDStorage );
#endif
XP_FREE( util->util.mpool, util->util.vtable );
XP_FREE( util->util.mpool, util );
*utilc = NULL;
}

View file

@ -25,10 +25,17 @@
#include "game.h"
#include "util.h"
#include "dutil.h"
#include "andglobals.h"
#include "jniutlswrapper.h"
XW_DUtilCtxt* makeDUtil( MPFORMAL EnvThreadInfo* ti, jobject j_dutil,
VTableMgr* vtMgr, JNIUtilCtxt* jniutil,
void* closure );
void destroyDUtil( XW_DUtilCtxt** dutilp );
XW_UtilCtxt* makeUtil( MPFORMAL EnvThreadInfo* ti, jobject j_util,
CurGameInfo* gi, AndGlobals* globals );
CurGameInfo* gi, AndGameGlobals* globals );
void destroyUtil( XW_UtilCtxt** util );
bool utilTimerFired( XW_UtilCtxt* util, XWTimerReason why, int handle );

View file

@ -1,4 +1,4 @@
/* -*- compile-command: "find-and-gradle.sh installXw4Debug"; -*- */
/* -*- compile-command: "find-and-gradle.sh inXw4Deb"; -*- */
/*
* Copyright © 2009 - 2018 by Eric House (xwords@eehouse.org). All rights
* reserved.
@ -61,6 +61,8 @@ typedef struct _JNIGlobalState {
EnvThreadInfo ti;
DictMgrCtxt* dictMgr;
VTableMgr* vtMgr;
XW_DUtilCtxt* dutil;
JNIUtilCtxt* jniutil;
XP_Bool mpoolInUse;
MPSLOT
} JNIGlobalState;
@ -276,15 +278,18 @@ getState( JNIEnv* env, GamePtrType gamePtr )
JNIEXPORT jint JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_initGlobals
( JNIEnv* env, jclass C )
( JNIEnv* env, jclass C, jobject jdutil, jobject jniu )
{
#ifdef MEM_DEBUG
MemPoolCtx* mpool = mpool_make( NULL );
#endif
JNIGlobalState* state = (JNIGlobalState*)XP_CALLOC( mpool, sizeof(*state) );
map_init( MPPARM(mpool) &state->ti, env );
state->dictMgr = dmgr_make( MPPARM_NOCOMMA( mpool ) );
state->jniutil = makeJNIUtil( MPPARM(mpool) env, &state->ti, jniu );
state->vtMgr = make_vtablemgr( MPPARM_NOCOMMA(mpool) );
state->dutil = makeDUtil( MPPARM(mpool) &state->ti, jdutil, state->vtMgr,
state->jniutil, NULL );
state->dictMgr = dmgr_make( MPPARM_NOCOMMA( mpool ) );
MPASSIGN( state->mpool, mpool );
// LOG_RETURNF( "%p", state );
return (jint)state;
@ -292,18 +297,19 @@ Java_org_eehouse_android_xw4_jni_XwJNI_initGlobals
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_cleanGlobals
( JNIEnv* env, jclass C, jint ptr )
( JNIEnv* env, jclass C, jint jniGlobalPtr )
{
// LOG_FUNC();
if ( 0 != ptr ) {
JNIGlobalState* state = (JNIGlobalState*)ptr;
XP_ASSERT( ENVFORME(&state->ti) == env );
if ( 0 != jniGlobalPtr ) {
JNIGlobalState* state = (JNIGlobalState*)jniGlobalPtr;
#ifdef MEM_DEBUG
MemPoolCtx* mpool = getMPool( state );
#endif
XP_ASSERT( ENVFORME(&state->ti) == env );
vtmgr_destroy( MPPARM(mpool) state->vtMgr );
dmgr_destroy( state->dictMgr );
destroyDUtil( &state->dutil );
destroyJNIUtil( env, &state->jniutil );
map_destroy( &state->ti );
XP_FREE( mpool, state );
mpool_destroy( mpool );
@ -696,7 +702,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_dict_1unref
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_dict_1getInfo
( JNIEnv* env, jclass C, jint jniGlobalPtr, jbyteArray jDictBytes,
jstring jname, jstring jpath, jobject jniu, jboolean check, jobject jinfo )
jstring jname, jstring jpath, jboolean check, jobject jinfo )
{
jboolean result = false;
JNIGlobalState* state = (JNIGlobalState*)jniGlobalPtr;
@ -706,9 +712,8 @@ Java_org_eehouse_android_xw4_jni_XwJNI_dict_1getInfo
MemPoolCtx* mpool = getMPool( state );
#endif
JNIUtilCtxt* jniutil = makeJNIUtil( MPPARM(mpool) env, &state->ti, jniu );
DictionaryCtxt* dict = makeDict( MPPARM(mpool) env, state->dictMgr,
jniutil, jname, jDictBytes, jpath,
state->jniutil, jname, jDictBytes, jpath,
NULL, check );
if ( NULL != dict ) {
if ( NULL != jinfo ) {
@ -721,7 +726,6 @@ Java_org_eehouse_android_xw4_jni_XwJNI_dict_1getInfo
dict_unref( dict );
result = true;
}
destroyJNIUtil( env, &jniutil );
releaseMPool( state );
return result;
@ -760,7 +764,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_dict_1getTileValue
struct _JNIState {
XWGame game;
JNIGlobalState* globalJNI;
AndGlobals globals;
AndGameGlobals globals;
// pthread_mutex_t msgMutex;
XP_U16 curSaveCount;
XP_U16 lastSavedSize;
@ -779,27 +783,26 @@ struct _JNIState {
#define XWJNI_START_GLOBALS() \
XWJNI_START() \
AndGlobals* globals = &state->globals; \
AndGameGlobals* globals = &state->globals; \
#define XWJNI_END() \
} \
JNIEXPORT jint JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_initJNI
( JNIEnv* env, jclass C, int jniGlobalPtr, jint seed, jstring jtag )
( JNIEnv* env, jclass C, int jniGlobalPtr, jint seed )
{
/* Why am I doing this twice? */
/* struct timeval tv; */
/* gettimeofday( &tv, NULL ); */
/* srandom( tv.tv_sec ); */
#ifdef MEM_DEBUG
const char* tag = (*env)->GetStringUTFChars( env, jtag, NULL );
MemPoolCtx* mpool = mpool_make( tag );
(*env)->ReleaseStringUTFChars( env, jtag, tag );
MemPoolCtx* mpool = ((JNIGlobalState*)jniGlobalPtr)->mpool;
#endif
JNIState* state = (JNIState*)XP_CALLOC( mpool, sizeof(*state) );
state->globalJNI = (JNIGlobalState*)jniGlobalPtr;
AndGlobals* globals = &state->globals;
AndGameGlobals* globals = &state->globals;
globals->dutil = state->globalJNI->dutil;
globals->state = (JNIState*)state;
MPASSIGN( state->mpool, mpool );
globals->vtMgr = make_vtablemgr(MPPARM_NOCOMMA(mpool));
@ -825,8 +828,8 @@ JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeNewGame
( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject j_gi,
jobjectArray j_names, jobjectArray j_dicts, jobjectArray j_paths,
jstring j_lang, jobject j_util, jobject jniu, jobject j_draw,
jobject j_cp, jobject j_procs )
jstring j_lang, jobject j_util, jobject j_draw, jobject j_cp,
jobject j_procs )
{
XWJNI_START_GLOBALS();
EnvThreadInfo* ti = &state->globalJNI->ti;
@ -834,7 +837,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeNewGame
globals->gi = gi;
globals->util = makeUtil( MPPARM(mpool) ti, j_util, gi,
globals );
globals->jniutil = makeJNIUtil( MPPARM(mpool) env, ti, jniu );
globals->jniutil = state->globalJNI->jniutil;
DrawCtx* dctx = NULL;
if ( !!j_draw ) {
dctx = makeDraw( MPPARM(mpool) ti, j_draw );
@ -876,7 +879,7 @@ JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_game_1dispose
#ifdef MEM_DEBUG
MemPoolCtx* mpool = state->mpool;
#endif
AndGlobals* globals = &state->globals;
AndGameGlobals* globals = &state->globals;
destroyGI( MPPARM(mpool) &globals->gi );
@ -885,22 +888,19 @@ JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_game_1dispose
destroyDraw( &globals->dctx );
destroyXportProcs( &globals->xportProcs );
destroyUtil( &globals->util );
destroyJNIUtil( env, &globals->jniutil );
vtmgr_destroy( MPPARM(mpool) globals->vtMgr );
MAP_REMOVE( &state->globalJNI->ti, env );
/* pthread_mutex_destroy( &state->msgMutex ); */
XP_FREE( mpool, state );
mpool_destroy( mpool );
} /* game_dispose */
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeFromStream
( JNIEnv* env, jclass C, GamePtrType gamePtr, jbyteArray jstream, jobject /*out*/jgi,
jobjectArray jdictNames, jobjectArray jdicts, jobjectArray jpaths,
jstring jlang, jobject jutil, jobject jniu, jobject jdraw, jobject jcp,
jobject jprocs )
jstring jlang, jobject jutil, jobject jdraw, jobject jcp, jobject jprocs )
{
jboolean result;
DictionaryCtxt* dict;
@ -910,7 +910,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeFromStream
globals->gi = (CurGameInfo*)XP_CALLOC( mpool, sizeof(*globals->gi) );
globals->util = makeUtil( MPPARM(mpool) ti, jutil, globals->gi, globals);
globals->jniutil = makeJNIUtil( MPPARM(mpool) env, ti, jniu );
globals->jniutil = state->globalJNI->jniutil;
makeDicts( MPPARM(state->globalJNI->mpool) env, state->globalJNI->dictMgr,
globals->jniutil, &dict, &dicts, jdictNames, jdicts, jpaths,
jlang );
@ -941,7 +941,6 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeFromStream
destroyDraw( &globals->dctx );
destroyXportProcs( &globals->xportProcs );
destroyUtil( &globals->util );
destroyJNIUtil( env, &globals->jniutil );
destroyGI( MPPARM(mpool) &globals->gi );
}
@ -1574,7 +1573,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_server_1writeFinalScores
void
and_send_on_close( XWStreamCtxt* stream, void* closure )
{
AndGlobals* globals = (AndGlobals*)closure;
AndGameGlobals* globals = (AndGameGlobals*)closure;
JNIState* state = (JNIState*)globals->state;
XP_ASSERT( !!state->game.comms );
@ -2120,29 +2119,25 @@ static void freeIndices( DictIterData* data );
JNIEXPORT jint JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_dict_1iter_1init
( JNIEnv* env, jclass C, jint jniGlobalPtr, jbyteArray jDictBytes, jstring jname,
jstring jpath, jobject jniu )
jstring jpath )
{
jint closure = 0;
JNIGlobalState* state = (JNIGlobalState*)jniGlobalPtr;
JNIUtilCtxt* jniutil = makeJNIUtil( MPPARM(state->mpool) env,
&state->ti, jniu );
DictionaryCtxt* dict = makeDict( MPPARM(state->mpool) env, state->dictMgr,
jniutil, jname, jDictBytes, jpath, NULL,
state->jniutil, jname, jDictBytes, jpath, NULL,
false );
if ( !!dict ) {
DictIterData* data = XP_CALLOC( state->mpool, sizeof(*data) );
data->env = env;
data->vtMgr = make_vtablemgr( MPPARM_NOCOMMA(state->mpool) );
data->jniutil = jniutil;
data->jniutil = state->jniutil;
data->dict = dict;
data->depth = 2;
#ifdef MEM_DEBUG
data->mpool = state->mpool;
#endif
closure = (int)data;
} else {
destroyJNIUtil( env, &jniutil );
}
return closure;
}
@ -2170,7 +2165,6 @@ Java_org_eehouse_android_xw4_jni_XwJNI_dict_1iter_1destroy
#endif
dict_unref( data->dict );
destroyJNIUtil( env, &data->jniutil );
freeIndices( data );
vtmgr_destroy( MPPARM(mpool) data->vtMgr );
XP_FREE( mpool, data );

View file

@ -44,8 +44,6 @@ extern "C" {
#define DICT_HEADER_MASK 0x08
#define DICT_SYNONYMS_MASK 0x10
typedef XP_U8 XP_LangCode;
typedef enum {
INTRADE_MW_TEXT = BONUS_LAST
} XWMiniTextType;