diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/DUtilCtxt.kt b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/DUtilCtxt.kt index 8c7a7822f..8c921bd26 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/DUtilCtxt.kt +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/DUtilCtxt.kt @@ -22,6 +22,9 @@ import android.content.Context import android.content.Intent import android.os.Build import android.telephony.PhoneNumberUtils + +import kotlin.concurrent.thread + import org.eehouse.android.xw4.Assert import org.eehouse.android.xw4.BuildConfig import org.eehouse.android.xw4.Channels @@ -130,6 +133,30 @@ class DUtilCtxt { m_context = XWApp.getContext() } + private val sCleared = HashSet() + fun setTimer(inMS: Int, key: Int) + { + val startMS = if (BuildConfig.DEBUG) System.currentTimeMillis() else 0 + thread { + Thread.sleep(inMS.toLong()) + if (BuildConfig.DEBUG) { + val wakeMS = System.currentTimeMillis() + Log.d(TAG, "setTimer(): firing; set for $inMS, " + + "took ${wakeMS - startMS}") + } + + if (synchronized(sCleared) {sCleared.remove(key)}) { + XwJNI.dvc_onTimerFired(key) + } + } + } + + fun clearTimer(key: Int) + { + Log.d(TAG, "clearTimer($key)") + synchronized(sCleared) {sCleared.add(key)} + } + // PENDING use prefs for this fun getUsername( posn: Int, diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.kt b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.kt index bcd9b6b5b..da2022ea5 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.kt +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.kt @@ -878,6 +878,10 @@ class XwJNI private constructor() { send: Boolean ): Boolean + fun dvc_onTimerFired(key: Int) = dvc_onTimerFired(jNI.m_ptrGlobals, key) + @JvmStatic + private external fun dvc_onTimerFired(jniState: Long, key: Int) + fun smsproto_prepOutbound( cmd: SMS_CMD, gameID: Int, buf: ByteArray?, phone: String, port: Int, /*out*/ diff --git a/xwords4/android/jni/Android.mk b/xwords4/android/jni/Android.mk index 33d1c64bd..63e0ad516 100644 --- a/xwords4/android/jni/Android.mk +++ b/xwords4/android/jni/Android.mk @@ -52,6 +52,8 @@ LOCAL_DEFINES += \ -DMQTT_GAMEID_TOPICS \ -DGITREV=\"${GITREV}\" \ +LOCAL_DEFINES += -DDUTIL_TIMERS + # XWFEATURE_RAISETILE: first, fix to not use timer # -DXWFEATURE_RAISETILE \ @@ -99,6 +101,7 @@ COMMON_SRC_FILES += \ $(COMMON_PATH)/knownplyr.c \ $(COMMON_PATH)/dllist.c \ $(COMMON_PATH)/stats.c \ + $(COMMON_PATH)/timers.c \ $(COMMON_PATH)/cJSON.c \ $(COMMON_PATH)/cJSON_Utils.c\ diff --git a/xwords4/android/jni/utilwrapper.c b/xwords4/android/jni/utilwrapper.c index 29a28553a..e02c7ed5c 100644 --- a/xwords4/android/jni/utilwrapper.c +++ b/xwords4/android/jni/utilwrapper.c @@ -842,6 +842,25 @@ and_dutil_md5sum( XW_DUtilCtxt* duc, XWEnv xwe, const XP_U8* ptr, XP_U32 len, } +#ifdef DUTIL_TIMERS +static void +and_dutil_setTimer( XW_DUtilCtxt* duc, XWEnv xwe, XP_U32 when, TimerKey key ) +{ + XP_LOGFF( "(key=%d)", key ); + DUTIL_CBK_HEADER( "setTimer", "(II)V" ); + (*env)->CallVoidMethod( env, dutil->jdutil, mid, when, key ); + DUTIL_CBK_TAIL(); +} + +static void +and_dutil_clearTimer( XW_DUtilCtxt* duc, XWEnv xwe, TimerKey key ) +{ + DUTIL_CBK_HEADER( "clearTimer", "(I)V" ); + (*env)->CallVoidMethod( env, dutil->jdutil, mid, key ); + DUTIL_CBK_TAIL(); +} +#endif + static void and_dutil_getUsername( XW_DUtilCtxt* duc, XWEnv xwe, XP_U16 num, XP_Bool isLocal, XP_Bool isRobot, @@ -1125,6 +1144,11 @@ makeDUtil( MPFORMAL JNIEnv* env, SET_DPROC(phoneNumbersSame); #endif SET_DPROC(md5sum); +#ifdef DUTIL_TIMERS + SET_DPROC(setTimer); + SET_DPROC(clearTimer); +#endif + SET_DPROC(getUsername); SET_DPROC(notifyPause); SET_DPROC(haveGame); diff --git a/xwords4/android/jni/xwjni.c b/xwords4/android/jni/xwjni.c index 00fe1bab7..650bbdfef 100644 --- a/xwords4/android/jni/xwjni.c +++ b/xwords4/android/jni/xwjni.c @@ -1257,6 +1257,15 @@ Java_org_eehouse_android_xw4_jni_XwJNI_sts_1increment DVC_HEADER_END(); } +JNIEXPORT void JNICALL +Java_org_eehouse_android_xw4_jni_XwJNI_dvc_1onTimerFired +( JNIEnv* env, jclass C, jlong jniGlobalPtr, jint jkey ) +{ + DVC_HEADER(jniGlobalPtr); + dvc_onTimerFired( globalState->dutil, env, jkey ); + DVC_HEADER_END(); +} + /* Dictionary methods: don't use gamePtr */ JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_dict_1tilesAreSame diff --git a/xwords4/common/stats.c b/xwords4/common/stats.c index 8004e2406..783b58481 100644 --- a/xwords4/common/stats.c +++ b/xwords4/common/stats.c @@ -205,6 +205,8 @@ setStoreTimer( XW_DUtilCtxt* dutil, XWEnv xwe ) XP_U32 inWhenMS = 5 * 1000; TimerKey key = tmr_set( dutil, xwe, inWhenMS, onStoreTimer, dutil ); XP_LOGFF( "tmr_set() => %d", key ); + } else { + XP_LOGFF( "timer already set" ); } #else XP_USE(dutil);