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 }; String[] names = { name };
DictUtils.DictPairs pairs = DictUtils.openDicts( m_activity, names ); DictUtils.DictPairs pairs = DictUtils.openDicts( m_activity, names );
m_dictClosure = XwJNI.dict_iter_init( pairs.m_bytes[0], m_dictClosure = XwJNI.dict_iter_init( pairs.m_bytes[0],
name, pairs.m_paths[0], name, pairs.m_paths[0] );
JNIUtilsImpl.get(m_activity) );
m_browseState = DBUtils.dictsGetOffset( m_activity, name, m_loc ); m_browseState = DBUtils.dictsGetOffset( m_activity, name, m_loc );
boolean newState = null == m_browseState; boolean newState = null == m_browseState;

View file

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

View file

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

View file

@ -131,8 +131,8 @@ public class GameUtils {
gamePtr = XwJNI.initNew( gi, dictNames, pairs.m_bytes, pairs.m_paths, gamePtr = XwJNI.initNew( gi, dictNames, pairs.m_bytes, pairs.m_paths,
gi.langName( context ), (UtilCtxt)null, gi.langName( context ), (UtilCtxt)null,
JNIUtilsImpl.get( context ), (DrawCtx)null, (DrawCtx)null, CommonPrefs.get( context ),
CommonPrefs.get( context ), (TransportProcs)null ); (TransportProcs)null );
if ( juggle ) { if ( juggle ) {
gi.juggle(); gi.juggle();
@ -372,15 +372,13 @@ public class GameUtils {
gamePtr = XwJNI.initFromStream( rowid, stream, gi, dictNames, gamePtr = XwJNI.initFromStream( rowid, stream, gi, dictNames,
pairs.m_bytes, pairs.m_paths, pairs.m_bytes, pairs.m_paths,
langName, util, langName, util,
JNIUtilsImpl.get( context ),
null, null,
CommonPrefs.get(context), CommonPrefs.get(context),
tp ); tp );
if ( null == gamePtr ) { if ( null == gamePtr ) {
gamePtr = XwJNI.initNew( gi, dictNames, gamePtr = XwJNI.initNew( gi, dictNames,
pairs.m_bytes, pairs.m_paths, pairs.m_bytes, pairs.m_paths,
langName, (UtilCtxt)null, langName, (UtilCtxt)null, null,
JNIUtilsImpl.get(context), null,
CommonPrefs.get(context), null ); CommonPrefs.get(context), null );
} }
} }
@ -1024,8 +1022,7 @@ public class GameUtils {
XwJNI.initFromStream( rowid, stream, gi, dictNames, XwJNI.initFromStream( rowid, stream, gi, dictNames,
pairs.m_bytes, pairs.m_paths, pairs.m_bytes, pairs.m_paths,
gi.langName( context ), null, gi.langName( context ), null,
JNIUtilsImpl.get(context), null, null, CommonPrefs.get( context ), null );
CommonPrefs.get( context ), null );
// second time required as game_makeFromStream can overwrite // second time required as game_makeFromStream can overwrite
gi.replaceDicts( context, newDict ); gi.replaceDicts( context, newDict );
@ -1075,8 +1072,7 @@ public class GameUtils {
new CurGameInfo(context), new CurGameInfo(context),
dictNames, pairs.m_bytes, dictNames, pairs.m_bytes,
pairs.m_paths, langName, pairs.m_paths, langName,
null, JNIUtilsImpl.get(context), null, null, cp, null );
null, cp, null );
madeGame = null != gamePtr; madeGame = null != gamePtr;
} }
@ -1084,8 +1080,7 @@ public class GameUtils {
Assert.assertNull( gamePtr ); Assert.assertNull( gamePtr );
gamePtr = XwJNI.initNew( gi, dictNames, pairs.m_bytes, gamePtr = XwJNI.initNew( gi, dictNames, pairs.m_bytes,
pairs.m_paths, langName, util, pairs.m_paths, langName, util,
JNIUtilsImpl.get(context), (DrawCtx)null, (DrawCtx)null, cp, sink );
cp, sink );
} }
if ( null != car ) { 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.MultiService.MultiEvent;
import org.eehouse.android.xw4.jni.CommsAddrRec; import org.eehouse.android.xw4.jni.CommsAddrRec;
import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType; 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.jni.XwJNI;
import org.eehouse.android.xw4.loc.LocUtils; 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 ); CommonPrefs cp = CommonPrefs.get( context );
JNIUtils jniUtils = JNIUtilsImpl.get( context );
// Assert.assertNull( m_jniGamePtr ); // fired!! // Assert.assertNull( m_jniGamePtr ); // fired!!
if ( null != m_jniGamePtr ) { if ( null != m_jniGamePtr ) {
@ -224,15 +223,13 @@ public class JNIThread extends Thread {
dictNames, pairs.m_bytes, dictNames, pairs.m_bytes,
pairs.m_paths, pairs.m_paths,
m_gi.langName( m_context ), m_gi.langName( m_context ),
utils, jniUtils, utils, null, cp, m_xport );
null, cp, m_xport );
} }
if ( null == m_jniGamePtr ) { if ( null == m_jniGamePtr ) {
m_jniGamePtr = XwJNI.initNew( m_gi, dictNames, pairs.m_bytes, m_jniGamePtr = XwJNI.initNew( m_gi, dictNames, pairs.m_bytes,
pairs.m_paths, pairs.m_paths,
m_gi.langName(m_context), m_gi.langName(m_context),
utils, jniUtils, null, cp, utils, null, cp, m_xport );
m_xport );
} }
Assert.assertNotNull( m_jniGamePtr ); Assert.assertNotNull( m_jniGamePtr );
m_lastSavedState = Arrays.hashCode( stream ); m_lastSavedState = Arrays.hashCode( stream );

View file

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

View file

@ -60,50 +60,10 @@ public interface UtilCtxt {
void remSelected(); void remSelected();
void setIsServer( boolean isServer ); 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 bonusSquareHeld( int bonus );
void playerScoreHeld( int player ); void playerScoreHeld( int player );
void cellSquareHeld( String words ); 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 notifyMove( String query );
void notifyTrade( String[] tiles ); void notifyTrade( String[] tiles );
@ -146,6 +106,4 @@ public interface UtilCtxt {
boolean turnLost ); boolean turnLost );
void showChat( String msg, int fromIndx, String fromName, int tsSeconds ); 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; package org.eehouse.android.xw4.jni;
import android.content.Context; import android.content.Context;
import android.telephony.PhoneNumberUtils;
import junit.framework.Assert; import junit.framework.Assert;
import org.eehouse.android.xw4.DevID;
import org.eehouse.android.xw4.Log; 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.jni.CommsAddrRec.CommsConnTypeSet;
import org.eehouse.android.xw4.loc.LocUtils;
public class UtilCtxtImpl implements UtilCtxt { public class UtilCtxtImpl implements UtilCtxt {
private static final String TAG = UtilCtxtImpl.class.getSimpleName(); private static final String TAG = UtilCtxtImpl.class.getSimpleName();
@ -96,39 +91,6 @@ public class UtilCtxtImpl implements UtilCtxt {
subclassOverride( "setIsServer" ); 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 ) 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 ) public void notifyMove( String query )
{ {
subclassOverride( "notifyMove" ); subclassOverride( "notifyMove" );
@ -293,12 +160,6 @@ public class UtilCtxtImpl implements UtilCtxt {
subclassOverride( "showChat" ); subclassOverride( "showChat" );
} }
public boolean phoneNumbersSame( String num1, String num2 )
{
boolean same = PhoneNumberUtils.compare( m_context, num1, num2 );
return same;
}
private void subclassOverride( String name ) { private void subclassOverride( String name ) {
// DbgUtils.logf( "%s::%s() called", getClass().getName(), name ); // DbgUtils.logf( "%s::%s() called", getClass().getName(), name );
} }

View file

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

View file

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

View file

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

View file

@ -31,7 +31,7 @@
/* callback for streams */ /* callback for streams */
void and_send_on_close( XWStreamCtxt* stream, void* closure ); 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 { typedef struct _SetInfo {
const char* name; const char* name;

View file

@ -30,6 +30,18 @@
#define MAX_QUANTITY_STRS 4 #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 { typedef struct _TimerStorage {
XWTimerProc proc; XWTimerProc proc;
void* closure; void* closure;
@ -40,21 +52,8 @@ typedef struct _AndUtil {
EnvThreadInfo* ti; EnvThreadInfo* ti;
jobject jutil; /* global ref to object implementing XW_UtilCtxt */ jobject jutil; /* global ref to object implementing XW_UtilCtxt */
TimerStorage timerStorage[NUM_TIMERS_PLUS_ONE]; TimerStorage timerStorage[NUM_TIMERS_PLUS_ONE];
XP_UCHAR* userStrings[N_AND_USER_STRINGS];
XP_U32 userStringsBits;
#ifdef XWFEATURE_DEVID
XP_UCHAR* devIDStorage;
#endif
} AndUtil; } AndUtil;
static VTableMgr*
and_util_getVTManager( XW_UtilCtxt* uc )
{
AndGlobals* globals = (AndGlobals*)uc->closure;
return globals->vtMgr;
}
#ifndef XWFEATURE_STANDALONE_ONLY #ifndef XWFEATURE_STANDALONE_ONLY
static XWStreamCtxt* static XWStreamCtxt*
and_util_makeStreamFromAddr( XW_UtilCtxt* uc, XP_PlayerAddr channelNo ) and_util_makeStreamFromAddr( XW_UtilCtxt* uc, XP_PlayerAddr channelNo )
@ -62,7 +61,7 @@ and_util_makeStreamFromAddr( XW_UtilCtxt* uc, XP_PlayerAddr channelNo )
#ifdef DEBUG #ifdef DEBUG
AndUtil* util = (AndUtil*)uc; AndUtil* util = (AndUtil*)uc;
#endif #endif
AndGlobals* globals = (AndGlobals*)uc->closure; AndGameGlobals* globals = (AndGameGlobals*)uc->closure;
XWStreamCtxt* stream = and_empty_stream( MPPARM(util->util.mpool) XWStreamCtxt* stream = and_empty_stream( MPPARM(util->util.mpool)
globals ); globals );
stream_setAddress( stream, channelNo ); 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", \ XP_LOGF( "%s: skipping call into java because jutil==NULL", \
__func__ ); \ __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), static XWBonusType and_util_getSquareBonus( XW_UtilCtxt* XP_UNUSED(uc),
XP_U16 boardSize, XP_U16 boardSize,
@ -349,26 +356,24 @@ and_util_altKeyDown( XW_UtilCtxt* uc )
return XP_FALSE; return XP_FALSE;
} }
XP_U32 XP_U32
and_util_getCurSeconds( XW_UtilCtxt* uc ) and_dutil_getCurSeconds( XW_DUtilCtxt* duc )
{ {
AndUtil* andutil = (AndUtil*)uc; AndDUtil* anddutil = (AndDUtil*)duc;
XP_U32 curSeconds = getCurSeconds( ENVFORME( andutil->ti ) ); XP_U32 curSeconds = getCurSeconds( ENVFORME( anddutil->ti ) );
/* struct timeval tv; */ /* struct timeval tv; */
/* gettimeofday( &tv, NULL ); */ /* gettimeofday( &tv, NULL ); */
/* XP_LOGF( "%s: %d vs %d", __func__, (int)tv.tv_sec, (int)curSeconds ); */ /* XP_LOGF( "%s: %d vs %d", __func__, (int)tv.tv_sec, (int)curSeconds ); */
return curSeconds; return curSeconds;
} }
static DictionaryCtxt* static DictionaryCtxt*
and_util_makeEmptyDict( XW_UtilCtxt* uc ) and_util_makeEmptyDict( XW_UtilCtxt* uc )
{ {
#ifdef STUBBED_DICT #ifdef STUBBED_DICT
XP_ASSERT(0); XP_ASSERT(0);
#else #else
AndGlobals* globals = (AndGlobals*)uc->closure; AndGameGlobals* globals = (AndGameGlobals*)uc->closure;
AndUtil* andutil = (AndUtil*)uc; AndUtil* andutil = (AndUtil*)uc;
DictionaryCtxt* result = DictionaryCtxt* result =
and_dictionary_make_empty( MPPARM( ((AndUtil*)uc)->util.mpool ) and_dictionary_make_empty( MPPARM( ((AndUtil*)uc)->util.mpool )
@ -378,51 +383,51 @@ and_util_makeEmptyDict( XW_UtilCtxt* uc )
} }
static const XP_UCHAR* 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 = ""; 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 */ 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] ) { if ( ! dutil->userStrings[index] ) {
jstring jresult = (*env)->CallObjectMethod( env, util->jutil, mid, jstring jresult = (*env)->CallObjectMethod( env, dutil->jdutil, mid,
stringCode ); stringCode );
jsize len = (*env)->GetStringUTFLength( env, jresult ); 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 ); const char* jchars = (*env)->GetStringUTFChars( env, jresult, NULL );
XP_MEMCPY( buf, jchars, len ); XP_MEMCPY( buf, jchars, len );
buf[len] = '\0'; buf[len] = '\0';
(*env)->ReleaseStringUTFChars( env, jresult, jchars ); (*env)->ReleaseStringUTFChars( env, jresult, jchars );
deleteLocalRef( env, jresult ); deleteLocalRef( env, jresult );
util->userStrings[index] = buf; dutil->userStrings[index] = buf;
} }
result = util->userStrings[index]; result = dutil->userStrings[index];
UTIL_CBK_TAIL(); DUTIL_CBK_TAIL();
return result; return result;
} }
static const XP_UCHAR* 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 = ""; 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 */ int index = stringCode - 1; /* see LocalizedStrIncludes.h */
XP_ASSERT( index < VSIZE( util->userStrings ) ); XP_ASSERT( index < VSIZE( dutil->userStrings ) );
XP_UCHAR** ptrs; XP_UCHAR** ptrs;
util->userStringsBits |= 1 << index; dutil->userStringsBits |= 1 << index;
ptrs = (XP_UCHAR**)util->userStrings[index]; ptrs = (XP_UCHAR**)dutil->userStrings[index];
if ( !ptrs ) { if ( !ptrs ) {
ptrs = (XP_UCHAR**)XP_CALLOC( util->util.mpool, MAX_QUANTITY_STRS * sizeof(*ptrs) ); ptrs = (XP_UCHAR**)XP_CALLOC( dutil->dutil.mpool, MAX_QUANTITY_STRS * sizeof(*ptrs) );
util->userStrings[index] = (XP_UCHAR*)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 ); stringCode, quantity );
const char* jchars = (*env)->GetStringUTFChars( env, jresult, NULL ); const char* jchars = (*env)->GetStringUTFChars( env, jresult, NULL );
int indx = 0; int indx = 0;
@ -439,7 +444,7 @@ and_util_getUserQuantityString( XW_UtilCtxt* uc, XP_U16 stringCode, XP_U16 quant
if ( !ptrs[indx] ) { if ( !ptrs[indx] ) {
XP_ASSERT( indx < MAX_QUANTITY_STRS ); XP_ASSERT( indx < MAX_QUANTITY_STRS );
jsize len = (*env)->GetStringUTFLength( env, jresult ); 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 ); XP_MEMCPY( buf, jchars, len );
buf[len] = '\0'; buf[len] = '\0';
ptrs[indx] = buf; ptrs[indx] = buf;
@ -449,7 +454,7 @@ and_util_getUserQuantityString( XW_UtilCtxt* uc, XP_U16 stringCode, XP_U16 quant
deleteLocalRef( env, jresult ); deleteLocalRef( env, jresult );
result = ptrs[indx]; result = ptrs[indx];
UTIL_CBK_TAIL(); DUTIL_CBK_TAIL();
return result; return result;
} }
@ -519,18 +524,18 @@ and_util_playerScoreHeld( XW_UtilCtxt* uc, XP_U16 player )
#ifdef XWFEATURE_SMS #ifdef XWFEATURE_SMS
static XP_Bool static XP_Bool
and_util_phoneNumbersSame( XW_UtilCtxt* uc, const XP_UCHAR* p1, and_dutil_phoneNumbersSame( XW_DUtilCtxt* duc, const XP_UCHAR* p1,
const XP_UCHAR* p2 ) const XP_UCHAR* p2 )
{ {
XP_Bool same = 0 == strcmp( p1, p2 ); XP_Bool same = 0 == strcmp( p1, p2 );
if ( !same ) { if ( !same ) {
UTIL_CBK_HEADER( "phoneNumbersSame", DUTIL_CBK_HEADER( "phoneNumbersSame",
"(Ljava/lang/String;Ljava/lang/String;)Z" ); "(Ljava/lang/String;Ljava/lang/String;)Z" );
jstring js1 = (*env)->NewStringUTF( env, p1 ); jstring js1 = (*env)->NewStringUTF( env, p1 );
jstring js2 = (*env)->NewStringUTF( env, p2 ); 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 ); deleteLocalRefs( env, js1, js2, DELETE_NO_REF );
UTIL_CBK_TAIL(); DUTIL_CBK_TAIL();
} }
return same; return same;
} }
@ -576,61 +581,61 @@ and_util_addrChange( XW_UtilCtxt* uc, const CommsAddrRec* oldAddr,
} }
static void 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 */ /* Change both the C and Java structs, which need to stay in sync */
uc->gameInfo->serverRole = isServer? SERVER_ISSERVER : SERVER_ISCLIENT; 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 ); (*env)->CallVoidMethod( env, util->jutil, mid, isServer );
UTIL_CBK_TAIL(); UTIL_CBK_TAIL();
} }
#ifdef XWFEATURE_DEVID #ifdef XWFEATURE_DEVID
static const XP_UCHAR* 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; const XP_UCHAR* result = NULL;
*typ = ID_TYPE_NONE; *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 ); 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 ) { if ( NULL != jresult ) {
const char* jchars = (*env)->GetStringUTFChars( env, jresult, NULL ); const char* jchars = (*env)->GetStringUTFChars( env, jresult, NULL );
jsize len = (*env)->GetStringUTFLength( env, jresult ); jsize len = (*env)->GetStringUTFLength( env, jresult );
if ( NULL != util->devIDStorage if ( NULL != dutil->devIDStorage
&& 0 == XP_MEMCMP( util->devIDStorage, jchars, len ) ) { && 0 == XP_MEMCMP( dutil->devIDStorage, jchars, len ) ) {
XP_LOGF( "%s: already have matching devID", __func__ ); XP_LOGF( "%s: already have matching devID", __func__ );
} else { } else {
XP_LOGF( "%s: allocating storage for devID", __func__ ); XP_LOGF( "%s: allocating storage for devID", __func__ );
XP_FREEP( util->util.mpool, &util->devIDStorage ); XP_FREEP( dutil->dutil.mpool, &dutil->devIDStorage );
util->devIDStorage = XP_MALLOC( util->util.mpool, len + 1 ); dutil->devIDStorage = XP_MALLOC( dutil->dutil.mpool, len + 1 );
XP_MEMCPY( util->devIDStorage, jchars, len ); XP_MEMCPY( dutil->devIDStorage, jchars, len );
util->devIDStorage[len] = '\0'; dutil->devIDStorage[len] = '\0';
} }
(*env)->ReleaseStringUTFChars( env, jresult, jchars ); (*env)->ReleaseStringUTFChars( env, jresult, jchars );
result = (const XP_UCHAR*)util->devIDStorage; result = (const XP_UCHAR*)dutil->devIDStorage;
jbyte* elems = (*env)->GetByteArrayElements( env, jbarr, NULL ); jbyte* elems = (*env)->GetByteArrayElements( env, jbarr, NULL );
*typ = (DevIDType)elems[0]; *typ = (DevIDType)elems[0];
(*env)->ReleaseByteArrayElements( env, jbarr, elems, 0 ); (*env)->ReleaseByteArrayElements( env, jbarr, elems, 0 );
} }
deleteLocalRef( env, jbarr ); deleteLocalRef( env, jbarr );
UTIL_CBK_TAIL(); DUTIL_CBK_TAIL();
return result; return result;
} }
static void static void
and_util_deviceRegistered( XW_UtilCtxt* uc, DevIDType typ, and_dutil_deviceRegistered( XW_DUtilCtxt* duc, DevIDType typ,
const XP_UCHAR* idRelay ) const XP_UCHAR* idRelay )
{ {
UTIL_CBK_HEADER( "deviceRegistered", DUTIL_CBK_HEADER( "deviceRegistered",
"(L" PKG_PATH("jni/UtilCtxt$DevIDType") ";Ljava/lang/String;)V" ); "(L" PKG_PATH("jni/UtilCtxt$DevIDType") ";Ljava/lang/String;)V" );
jstring jstr = (*env)->NewStringUTF( env, idRelay ); jstring jstr = (*env)->NewStringUTF( env, idRelay );
jobject jtyp = intToJEnum( env, typ, jobject jtyp = intToJEnum( env, typ,
PKG_PATH("jni/UtilCtxt$DevIDType") ); 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 ); deleteLocalRefs( env, jstr, jtyp, DELETE_NO_REF );
UTIL_CBK_TAIL(); DUTIL_CBK_TAIL();
} }
#endif /* XWFEATURE_DEVID */ #endif /* XWFEATURE_DEVID */
@ -664,16 +669,24 @@ and_util_engineStopping( XW_UtilCtxt* uc )
} }
#endif #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 #ifdef COMMS_CHECKSUM
static XP_UCHAR* 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; AndDUtil* dutil = (AndDUtil*)duc;
JNIEnv* env = ENVFORME( util->ti ); JNIEnv* env = ENVFORME( dutil->ti );
AndGlobals* globals = (AndGlobals*)uc->closure; struct JNIUtilCtxt* jniutil = dutil->jniutil;
struct JNIUtilCtxt* jniutil = globals->jniutil;
jstring jsum = and_util_getMD5SumForBytes( jniutil, ptr, len ); 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 ); deleteLocalRef( env, jsum );
return result; return result;
} }
@ -681,8 +694,8 @@ and_util_md5sum( XW_UtilCtxt* uc, const XP_U8* ptr, XP_U16 len )
XW_UtilCtxt* XW_UtilCtxt*
makeUtil( MPFORMAL EnvThreadInfo* ti, jobject jutil, CurGameInfo* gi, makeUtil( MPFORMAL EnvThreadInfo* ti, jobject jutil, CurGameInfo* gi,
AndGlobals* closure ) AndGameGlobals* closure )
{ {
AndUtil* util = (AndUtil*)XP_CALLOC( mpool, sizeof(*util) ); AndUtil* util = (AndUtil*)XP_CALLOC( mpool, sizeof(*util) );
UtilVtable* vtable = (UtilVtable*)XP_CALLOC( mpool, sizeof(*vtable) ); UtilVtable* vtable = (UtilVtable*)XP_CALLOC( mpool, sizeof(*vtable) );
@ -697,7 +710,7 @@ makeUtil( MPFORMAL EnvThreadInfo* ti, jobject jutil, CurGameInfo* gi,
util->util.gameInfo = gi; util->util.gameInfo = gi;
#define SET_PROC(nam) vtable->m_util_##nam = and_util_##nam #define SET_PROC(nam) vtable->m_util_##nam = and_util_##nam
SET_PROC(getVTManager);
#ifndef XWFEATURE_STANDALONE_ONLY #ifndef XWFEATURE_STANDALONE_ONLY
SET_PROC(makeStreamFromAddr); SET_PROC(makeStreamFromAddr);
#endif #endif
@ -725,10 +738,7 @@ makeUtil( MPFORMAL EnvThreadInfo* ti, jobject jutil, CurGameInfo* gi,
SET_PROC(clearTimer); SET_PROC(clearTimer);
SET_PROC(requestTime); SET_PROC(requestTime);
SET_PROC(altKeyDown); SET_PROC(altKeyDown);
SET_PROC(getCurSeconds);
SET_PROC(makeEmptyDict); SET_PROC(makeEmptyDict);
SET_PROC(getUserString);
SET_PROC(getUserQuantityString);
SET_PROC(notifyIllegalWords); SET_PROC(notifyIllegalWords);
#ifdef XWFEATURE_CHAT #ifdef XWFEATURE_CHAT
SET_PROC(showChat); SET_PROC(showChat);
@ -740,10 +750,6 @@ makeUtil( MPFORMAL EnvThreadInfo* ti, jobject jutil, CurGameInfo* gi,
SET_PROC(playerScoreHeld); SET_PROC(playerScoreHeld);
#endif #endif
#ifdef XWFEATURE_SMS
SET_PROC(phoneNumbersSame);
#endif
#ifdef XWFEATURE_BOARDWORDS #ifdef XWFEATURE_BOARDWORDS
SET_PROC(cellSquareHeld); SET_PROC(cellSquareHeld);
#endif #endif
@ -752,10 +758,6 @@ makeUtil( MPFORMAL EnvThreadInfo* ti, jobject jutil, CurGameInfo* gi,
SET_PROC(informMissing); SET_PROC(informMissing);
SET_PROC(addrChange); SET_PROC(addrChange);
SET_PROC(setIsServer); SET_PROC(setIsServer);
# ifdef XWFEATURE_DEVID
SET_PROC(getDevID);
SET_PROC(deviceRegistered);
# endif
#endif #endif
#ifdef XWFEATURE_SEARCHLIMIT #ifdef XWFEATURE_SEARCHLIMIT
SET_PROC(getTraySearchLimits); SET_PROC(getTraySearchLimits);
@ -764,9 +766,8 @@ makeUtil( MPFORMAL EnvThreadInfo* ti, jobject jutil, CurGameInfo* gi,
SET_PROC(engineStarting); SET_PROC(engineStarting);
SET_PROC(engineStopping); SET_PROC(engineStopping);
#endif #endif
#ifdef COMMS_CHECKSUM
SET_PROC(md5sum); SET_PROC(getDevUtilCtxt);
#endif
#undef SET_PROC #undef SET_PROC
return (XW_UtilCtxt*)util; return (XW_UtilCtxt*)util;
@ -778,31 +779,77 @@ destroyUtil( XW_UtilCtxt** utilc )
AndUtil* util = (AndUtil*)*utilc; AndUtil* util = (AndUtil*)*utilc;
JNIEnv* env = ENVFORME( util->ti ); JNIEnv* env = ENVFORME( util->ti );
for ( int ii = 0; ii < VSIZE(util->userStrings); ++ii ) { if ( NULL != util->jutil ) {
XP_UCHAR* ptr = util->userStrings[ii]; (*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 ( NULL != ptr ) {
if ( 0 == (util->userStringsBits & (1 << ii)) ) { if ( 0 == (dutil->userStringsBits & (1 << ii)) ) {
XP_FREE( util->util.mpool, ptr ); XP_FREE( dutil->dutil.mpool, ptr );
} else { } else {
XP_UCHAR** ptrs = (XP_UCHAR**)ptr; XP_UCHAR** ptrs = (XP_UCHAR**)ptr;
for ( int jj = 0; jj < MAX_QUANTITY_STRS; ++jj ) { for ( int jj = 0; jj < MAX_QUANTITY_STRS; ++jj ) {
ptr = ptrs[jj]; ptr = ptrs[jj];
if ( !!ptr ) { 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 #ifdef XWFEATURE_DEVID
XP_FREEP( util->util.mpool, &util->devIDStorage ); XP_FREEP( dutil->dutil.mpool, &dutil->devIDStorage );
#endif #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 "game.h"
#include "util.h" #include "util.h"
#include "dutil.h"
#include "andglobals.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, XW_UtilCtxt* makeUtil( MPFORMAL EnvThreadInfo* ti, jobject j_util,
CurGameInfo* gi, AndGlobals* globals ); CurGameInfo* gi, AndGameGlobals* globals );
void destroyUtil( XW_UtilCtxt** util ); 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 @@
/* -*- 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 * Copyright © 2009 - 2018 by Eric House (xwords@eehouse.org). All rights
* reserved. * reserved.
@ -61,6 +61,8 @@ typedef struct _JNIGlobalState {
EnvThreadInfo ti; EnvThreadInfo ti;
DictMgrCtxt* dictMgr; DictMgrCtxt* dictMgr;
VTableMgr* vtMgr; VTableMgr* vtMgr;
XW_DUtilCtxt* dutil;
JNIUtilCtxt* jniutil;
XP_Bool mpoolInUse; XP_Bool mpoolInUse;
MPSLOT MPSLOT
} JNIGlobalState; } JNIGlobalState;
@ -276,15 +278,18 @@ getState( JNIEnv* env, GamePtrType gamePtr )
JNIEXPORT jint JNICALL JNIEXPORT jint JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_initGlobals Java_org_eehouse_android_xw4_jni_XwJNI_initGlobals
( JNIEnv* env, jclass C ) ( JNIEnv* env, jclass C, jobject jdutil, jobject jniu )
{ {
#ifdef MEM_DEBUG #ifdef MEM_DEBUG
MemPoolCtx* mpool = mpool_make( NULL ); MemPoolCtx* mpool = mpool_make( NULL );
#endif #endif
JNIGlobalState* state = (JNIGlobalState*)XP_CALLOC( mpool, sizeof(*state) ); JNIGlobalState* state = (JNIGlobalState*)XP_CALLOC( mpool, sizeof(*state) );
map_init( MPPARM(mpool) &state->ti, env ); 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->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 ); MPASSIGN( state->mpool, mpool );
// LOG_RETURNF( "%p", state ); // LOG_RETURNF( "%p", state );
return (jint)state; return (jint)state;
@ -292,18 +297,19 @@ Java_org_eehouse_android_xw4_jni_XwJNI_initGlobals
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_cleanGlobals Java_org_eehouse_android_xw4_jni_XwJNI_cleanGlobals
( JNIEnv* env, jclass C, jint ptr ) ( JNIEnv* env, jclass C, jint jniGlobalPtr )
{ {
// LOG_FUNC(); // LOG_FUNC();
if ( 0 != ptr ) { if ( 0 != jniGlobalPtr ) {
JNIGlobalState* state = (JNIGlobalState*)ptr; JNIGlobalState* state = (JNIGlobalState*)jniGlobalPtr;
XP_ASSERT( ENVFORME(&state->ti) == env );
#ifdef MEM_DEBUG #ifdef MEM_DEBUG
MemPoolCtx* mpool = getMPool( state ); MemPoolCtx* mpool = getMPool( state );
#endif #endif
XP_ASSERT( ENVFORME(&state->ti) == env ); XP_ASSERT( ENVFORME(&state->ti) == env );
vtmgr_destroy( MPPARM(mpool) state->vtMgr ); vtmgr_destroy( MPPARM(mpool) state->vtMgr );
dmgr_destroy( state->dictMgr ); dmgr_destroy( state->dictMgr );
destroyDUtil( &state->dutil );
destroyJNIUtil( env, &state->jniutil );
map_destroy( &state->ti ); map_destroy( &state->ti );
XP_FREE( mpool, state ); XP_FREE( mpool, state );
mpool_destroy( mpool ); mpool_destroy( mpool );
@ -696,7 +702,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_dict_1unref
JNIEXPORT jboolean JNICALL JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_dict_1getInfo Java_org_eehouse_android_xw4_jni_XwJNI_dict_1getInfo
( JNIEnv* env, jclass C, jint jniGlobalPtr, jbyteArray jDictBytes, ( 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; jboolean result = false;
JNIGlobalState* state = (JNIGlobalState*)jniGlobalPtr; JNIGlobalState* state = (JNIGlobalState*)jniGlobalPtr;
@ -706,9 +712,8 @@ Java_org_eehouse_android_xw4_jni_XwJNI_dict_1getInfo
MemPoolCtx* mpool = getMPool( state ); MemPoolCtx* mpool = getMPool( state );
#endif #endif
JNIUtilCtxt* jniutil = makeJNIUtil( MPPARM(mpool) env, &state->ti, jniu );
DictionaryCtxt* dict = makeDict( MPPARM(mpool) env, state->dictMgr, DictionaryCtxt* dict = makeDict( MPPARM(mpool) env, state->dictMgr,
jniutil, jname, jDictBytes, jpath, state->jniutil, jname, jDictBytes, jpath,
NULL, check ); NULL, check );
if ( NULL != dict ) { if ( NULL != dict ) {
if ( NULL != jinfo ) { if ( NULL != jinfo ) {
@ -721,7 +726,6 @@ Java_org_eehouse_android_xw4_jni_XwJNI_dict_1getInfo
dict_unref( dict ); dict_unref( dict );
result = true; result = true;
} }
destroyJNIUtil( env, &jniutil );
releaseMPool( state ); releaseMPool( state );
return result; return result;
@ -760,7 +764,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_dict_1getTileValue
struct _JNIState { struct _JNIState {
XWGame game; XWGame game;
JNIGlobalState* globalJNI; JNIGlobalState* globalJNI;
AndGlobals globals; AndGameGlobals globals;
// pthread_mutex_t msgMutex; // pthread_mutex_t msgMutex;
XP_U16 curSaveCount; XP_U16 curSaveCount;
XP_U16 lastSavedSize; XP_U16 lastSavedSize;
@ -779,27 +783,26 @@ struct _JNIState {
#define XWJNI_START_GLOBALS() \ #define XWJNI_START_GLOBALS() \
XWJNI_START() \ XWJNI_START() \
AndGlobals* globals = &state->globals; \ AndGameGlobals* globals = &state->globals; \
#define XWJNI_END() \ #define XWJNI_END() \
} \ } \
JNIEXPORT jint JNICALL JNIEXPORT jint JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_initJNI 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? */ /* Why am I doing this twice? */
/* struct timeval tv; */ /* struct timeval tv; */
/* gettimeofday( &tv, NULL ); */ /* gettimeofday( &tv, NULL ); */
/* srandom( tv.tv_sec ); */ /* srandom( tv.tv_sec ); */
#ifdef MEM_DEBUG #ifdef MEM_DEBUG
const char* tag = (*env)->GetStringUTFChars( env, jtag, NULL ); MemPoolCtx* mpool = ((JNIGlobalState*)jniGlobalPtr)->mpool;
MemPoolCtx* mpool = mpool_make( tag );
(*env)->ReleaseStringUTFChars( env, jtag, tag );
#endif #endif
JNIState* state = (JNIState*)XP_CALLOC( mpool, sizeof(*state) ); JNIState* state = (JNIState*)XP_CALLOC( mpool, sizeof(*state) );
state->globalJNI = (JNIGlobalState*)jniGlobalPtr; state->globalJNI = (JNIGlobalState*)jniGlobalPtr;
AndGlobals* globals = &state->globals; AndGameGlobals* globals = &state->globals;
globals->dutil = state->globalJNI->dutil;
globals->state = (JNIState*)state; globals->state = (JNIState*)state;
MPASSIGN( state->mpool, mpool ); MPASSIGN( state->mpool, mpool );
globals->vtMgr = make_vtablemgr(MPPARM_NOCOMMA(mpool)); globals->vtMgr = make_vtablemgr(MPPARM_NOCOMMA(mpool));
@ -825,8 +828,8 @@ JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeNewGame Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeNewGame
( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject j_gi, ( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject j_gi,
jobjectArray j_names, jobjectArray j_dicts, jobjectArray j_paths, jobjectArray j_names, jobjectArray j_dicts, jobjectArray j_paths,
jstring j_lang, jobject j_util, jobject jniu, jobject j_draw, jstring j_lang, jobject j_util, jobject j_draw, jobject j_cp,
jobject j_cp, jobject j_procs ) jobject j_procs )
{ {
XWJNI_START_GLOBALS(); XWJNI_START_GLOBALS();
EnvThreadInfo* ti = &state->globalJNI->ti; EnvThreadInfo* ti = &state->globalJNI->ti;
@ -834,7 +837,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeNewGame
globals->gi = gi; globals->gi = gi;
globals->util = makeUtil( MPPARM(mpool) ti, j_util, gi, globals->util = makeUtil( MPPARM(mpool) ti, j_util, gi,
globals ); globals );
globals->jniutil = makeJNIUtil( MPPARM(mpool) env, ti, jniu ); globals->jniutil = state->globalJNI->jniutil;
DrawCtx* dctx = NULL; DrawCtx* dctx = NULL;
if ( !!j_draw ) { if ( !!j_draw ) {
dctx = makeDraw( MPPARM(mpool) ti, 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 #ifdef MEM_DEBUG
MemPoolCtx* mpool = state->mpool; MemPoolCtx* mpool = state->mpool;
#endif #endif
AndGlobals* globals = &state->globals; AndGameGlobals* globals = &state->globals;
destroyGI( MPPARM(mpool) &globals->gi ); destroyGI( MPPARM(mpool) &globals->gi );
@ -885,22 +888,19 @@ JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_game_1dispose
destroyDraw( &globals->dctx ); destroyDraw( &globals->dctx );
destroyXportProcs( &globals->xportProcs ); destroyXportProcs( &globals->xportProcs );
destroyUtil( &globals->util ); destroyUtil( &globals->util );
destroyJNIUtil( env, &globals->jniutil );
vtmgr_destroy( MPPARM(mpool) globals->vtMgr ); vtmgr_destroy( MPPARM(mpool) globals->vtMgr );
MAP_REMOVE( &state->globalJNI->ti, env ); MAP_REMOVE( &state->globalJNI->ti, env );
/* pthread_mutex_destroy( &state->msgMutex ); */ /* pthread_mutex_destroy( &state->msgMutex ); */
XP_FREE( mpool, state ); XP_FREE( mpool, state );
mpool_destroy( mpool );
} /* game_dispose */ } /* game_dispose */
JNIEXPORT jboolean JNICALL JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeFromStream Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeFromStream
( JNIEnv* env, jclass C, GamePtrType gamePtr, jbyteArray jstream, jobject /*out*/jgi, ( JNIEnv* env, jclass C, GamePtrType gamePtr, jbyteArray jstream, jobject /*out*/jgi,
jobjectArray jdictNames, jobjectArray jdicts, jobjectArray jpaths, jobjectArray jdictNames, jobjectArray jdicts, jobjectArray jpaths,
jstring jlang, jobject jutil, jobject jniu, jobject jdraw, jobject jcp, jstring jlang, jobject jutil, jobject jdraw, jobject jcp, jobject jprocs )
jobject jprocs )
{ {
jboolean result; jboolean result;
DictionaryCtxt* dict; 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->gi = (CurGameInfo*)XP_CALLOC( mpool, sizeof(*globals->gi) );
globals->util = makeUtil( MPPARM(mpool) ti, jutil, globals->gi, globals); 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, makeDicts( MPPARM(state->globalJNI->mpool) env, state->globalJNI->dictMgr,
globals->jniutil, &dict, &dicts, jdictNames, jdicts, jpaths, globals->jniutil, &dict, &dicts, jdictNames, jdicts, jpaths,
jlang ); jlang );
@ -941,7 +941,6 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeFromStream
destroyDraw( &globals->dctx ); destroyDraw( &globals->dctx );
destroyXportProcs( &globals->xportProcs ); destroyXportProcs( &globals->xportProcs );
destroyUtil( &globals->util ); destroyUtil( &globals->util );
destroyJNIUtil( env, &globals->jniutil );
destroyGI( MPPARM(mpool) &globals->gi ); destroyGI( MPPARM(mpool) &globals->gi );
} }
@ -1574,7 +1573,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_server_1writeFinalScores
void void
and_send_on_close( XWStreamCtxt* stream, void* closure ) and_send_on_close( XWStreamCtxt* stream, void* closure )
{ {
AndGlobals* globals = (AndGlobals*)closure; AndGameGlobals* globals = (AndGameGlobals*)closure;
JNIState* state = (JNIState*)globals->state; JNIState* state = (JNIState*)globals->state;
XP_ASSERT( !!state->game.comms ); XP_ASSERT( !!state->game.comms );
@ -2120,29 +2119,25 @@ static void freeIndices( DictIterData* data );
JNIEXPORT jint JNICALL JNIEXPORT jint JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_dict_1iter_1init Java_org_eehouse_android_xw4_jni_XwJNI_dict_1iter_1init
( JNIEnv* env, jclass C, jint jniGlobalPtr, jbyteArray jDictBytes, jstring jname, ( JNIEnv* env, jclass C, jint jniGlobalPtr, jbyteArray jDictBytes, jstring jname,
jstring jpath, jobject jniu ) jstring jpath )
{ {
jint closure = 0; jint closure = 0;
JNIGlobalState* state = (JNIGlobalState*)jniGlobalPtr; JNIGlobalState* state = (JNIGlobalState*)jniGlobalPtr;
JNIUtilCtxt* jniutil = makeJNIUtil( MPPARM(state->mpool) env,
&state->ti, jniu );
DictionaryCtxt* dict = makeDict( MPPARM(state->mpool) env, state->dictMgr, DictionaryCtxt* dict = makeDict( MPPARM(state->mpool) env, state->dictMgr,
jniutil, jname, jDictBytes, jpath, NULL, state->jniutil, jname, jDictBytes, jpath, NULL,
false ); false );
if ( !!dict ) { if ( !!dict ) {
DictIterData* data = XP_CALLOC( state->mpool, sizeof(*data) ); DictIterData* data = XP_CALLOC( state->mpool, sizeof(*data) );
data->env = env; data->env = env;
data->vtMgr = make_vtablemgr( MPPARM_NOCOMMA(state->mpool) ); data->vtMgr = make_vtablemgr( MPPARM_NOCOMMA(state->mpool) );
data->jniutil = jniutil; data->jniutil = state->jniutil;
data->dict = dict; data->dict = dict;
data->depth = 2; data->depth = 2;
#ifdef MEM_DEBUG #ifdef MEM_DEBUG
data->mpool = state->mpool; data->mpool = state->mpool;
#endif #endif
closure = (int)data; closure = (int)data;
} else {
destroyJNIUtil( env, &jniutil );
} }
return closure; return closure;
} }
@ -2170,7 +2165,6 @@ Java_org_eehouse_android_xw4_jni_XwJNI_dict_1iter_1destroy
#endif #endif
dict_unref( data->dict ); dict_unref( data->dict );
destroyJNIUtil( env, &data->jniutil );
freeIndices( data ); freeIndices( data );
vtmgr_destroy( MPPARM(mpool) data->vtMgr ); vtmgr_destroy( MPPARM(mpool) data->vtMgr );
XP_FREE( mpool, data ); XP_FREE( mpool, data );

View file

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