diff --git a/app/src/main/java/com/futo/platformplayer/engine/packages/PackageBridge.kt b/app/src/main/java/com/futo/platformplayer/engine/packages/PackageBridge.kt index 027fd4b8..d5876956 100644 --- a/app/src/main/java/com/futo/platformplayer/engine/packages/PackageBridge.kt +++ b/app/src/main/java/com/futo/platformplayer/engine/packages/PackageBridge.kt @@ -2,7 +2,9 @@ package com.futo.platformplayer.engine.packages import com.caoccao.javet.annotations.V8Function import com.caoccao.javet.annotations.V8Property +import com.caoccao.javet.utils.JavetResourceUtils import com.caoccao.javet.values.V8Value +import com.caoccao.javet.values.reference.V8ValueFunction import com.futo.platformplayer.BuildConfig import com.futo.platformplayer.logging.Logger import com.futo.platformplayer.states.StateDeveloper @@ -16,6 +18,7 @@ import com.futo.platformplayer.engine.IV8PluginConfig import com.futo.platformplayer.engine.V8Plugin import com.futo.platformplayer.states.StateApp import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.serialization.Serializable import kotlinx.serialization.encodeToString @@ -37,6 +40,18 @@ class PackageBridge : V8Package { _config = config; _client = plugin.httpClient; _clientAuth = plugin.httpClientAuth; + + withScript(""" + function setTimeout(func, delay) { + let args = Array.prototype.slice.call(arguments, 2); + return bridge.setTimeout(func.bind(globalThis, ...args), delay || 0); + } + """.trimIndent()); + withScript(""" + function clearTimeout(id) { + bridge.clearTimeout(id); + } + """.trimIndent()); } @@ -62,6 +77,48 @@ class PackageBridge : V8Package { value.close(); } + var timeoutCounter = 0; + var timeoutMap = HashSet(); + @V8Function + fun setTimeout(func: V8ValueFunction, timeout: Long): Int { + val id = timeoutCounter++; + + val funcClone = func.toClone() + + StateApp.instance.scopeOrNull?.launch(Dispatchers.IO) { + delay(timeout); + synchronized(timeoutMap) { + if(!timeoutMap.contains(id)) { + JavetResourceUtils.safeClose(funcClone); + return@launch; + } + timeoutMap.remove(id); + } + try { + _plugin.whenNotBusy { + funcClone.callVoid(null, arrayOf()); + } + } + catch(ex: Throwable) { + Logger.e(TAG, "Failed timeout callback", ex); + } + finally { + JavetResourceUtils.safeClose(funcClone); + } + }; + synchronized(timeoutMap) { + timeoutMap.add(id); + } + return id; + } + @V8Function + fun clearTimeout(id: Int) { + synchronized(timeoutMap) { + if(timeoutMap.contains(id)) + timeoutMap.remove(id); + } + } + @V8Function fun toast(str: String) { Logger.i(TAG, "Plugin toast [${_config.name}]: ${str}");