diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DictBrowseDelegate.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DictBrowseDelegate.java index a73490b3f..0bc9e1578 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DictBrowseDelegate.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DictBrowseDelegate.java @@ -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; diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DictLangCache.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DictLangCache.java index fdab651b8..b614446b2 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DictLangCache.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DictLangCache.java @@ -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 ) ) { diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DictUtils.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DictUtils.java index 8fcd1a5f0..f354b1e29 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DictUtils.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DictUtils.java @@ -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; } diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GameUtils.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GameUtils.java index bcef8314a..81d161227 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GameUtils.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GameUtils.java @@ -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 ) { diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/RelayService.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/RelayService.java index b4ce7a02f..cadb8f6af 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/RelayService.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/RelayService.java @@ -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; diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/DUtilCtxt.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/DUtilCtxt.java new file mode 100644 index 000000000..c98ec18c9 --- /dev/null +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/DUtilCtxt.java @@ -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); + +} diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/JNIThread.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/JNIThread.java index 28bf81107..d6c9a6c37 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/JNIThread.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/JNIThread.java @@ -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 ); diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/JNIUtilsImpl.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/JNIUtilsImpl.java index 05506184c..4d2a660f1 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/JNIUtilsImpl.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/JNIUtilsImpl.java @@ -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; } diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/UtilCtxt.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/UtilCtxt.java index cc34891be..8812323e6 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/UtilCtxt.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/UtilCtxt.java @@ -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 ); } diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/UtilCtxtImpl.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/UtilCtxtImpl.java index d18821342..93b0dc831 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/UtilCtxtImpl.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/UtilCtxtImpl.java @@ -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 ); } diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.java index f3b8497a4..ab733abe4 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.java @@ -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 ); } diff --git a/xwords4/android/jni/andglobals.h b/xwords4/android/jni/andglobals.h index 19efedbee..b9f23ad92 100644 --- a/xwords4/android/jni/andglobals.h +++ b/xwords4/android/jni/andglobals.h @@ -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; diff --git a/xwords4/android/jni/andutils.c b/xwords4/android/jni/andutils.c index a05931d71..1df894fbe 100644 --- a/xwords4/android/jni/andutils.c +++ b/xwords4/android/jni/andutils.c @@ -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 ); diff --git a/xwords4/android/jni/andutils.h b/xwords4/android/jni/andutils.h index 22602e32f..1a156dee7 100644 --- a/xwords4/android/jni/andutils.h +++ b/xwords4/android/jni/andutils.h @@ -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; diff --git a/xwords4/android/jni/utilwrapper.c b/xwords4/android/jni/utilwrapper.c index fb6aa18f5..3428afa3b 100644 --- a/xwords4/android/jni/utilwrapper.c +++ b/xwords4/android/jni/utilwrapper.c @@ -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; } diff --git a/xwords4/android/jni/utilwrapper.h b/xwords4/android/jni/utilwrapper.h index 44a21acc3..b317d4ff5 100644 --- a/xwords4/android/jni/utilwrapper.h +++ b/xwords4/android/jni/utilwrapper.h @@ -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 ); diff --git a/xwords4/android/jni/xwjni.c b/xwords4/android/jni/xwjni.c index 1fac0a514..40e82bbf4 100644 --- a/xwords4/android/jni/xwjni.c +++ b/xwords4/android/jni/xwjni.c @@ -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 ); diff --git a/xwords4/common/dictnry.h b/xwords4/common/dictnry.h index 759ef358a..fbe8f7499 100644 --- a/xwords4/common/dictnry.h +++ b/xwords4/common/dictnry.h @@ -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;