mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2025-09-18 15:32:35 +00:00
WIP Async support for Android
This commit is contained in:
parent
d22e918273
commit
b69402dfe9
6 changed files with 212 additions and 9 deletions
|
@ -2,12 +2,22 @@ package com.futo.platformplayer
|
||||||
|
|
||||||
import com.caoccao.javet.values.V8Value
|
import com.caoccao.javet.values.V8Value
|
||||||
import com.caoccao.javet.values.primitive.*
|
import com.caoccao.javet.values.primitive.*
|
||||||
|
import com.caoccao.javet.values.reference.IV8ValuePromise
|
||||||
import com.caoccao.javet.values.reference.V8ValueArray
|
import com.caoccao.javet.values.reference.V8ValueArray
|
||||||
|
import com.caoccao.javet.values.reference.V8ValueError
|
||||||
import com.caoccao.javet.values.reference.V8ValueObject
|
import com.caoccao.javet.values.reference.V8ValueObject
|
||||||
|
import com.caoccao.javet.values.reference.V8ValuePromise
|
||||||
import com.futo.platformplayer.engine.IV8PluginConfig
|
import com.futo.platformplayer.engine.IV8PluginConfig
|
||||||
import com.futo.platformplayer.engine.V8Plugin
|
import com.futo.platformplayer.engine.V8Plugin
|
||||||
|
import com.futo.platformplayer.engine.exceptions.ScriptExecutionException
|
||||||
import com.futo.platformplayer.engine.exceptions.ScriptImplementationException
|
import com.futo.platformplayer.engine.exceptions.ScriptImplementationException
|
||||||
import com.futo.platformplayer.logging.Logger
|
import com.futo.platformplayer.logging.Logger
|
||||||
|
import kotlinx.coroutines.CompletableDeferred
|
||||||
|
import kotlinx.coroutines.Deferred
|
||||||
|
import kotlinx.coroutines.cancel
|
||||||
|
import java.util.concurrent.CancellationException
|
||||||
|
import java.util.concurrent.CountDownLatch
|
||||||
|
import kotlin.reflect.jvm.internal.impl.load.kotlin.JvmType
|
||||||
|
|
||||||
|
|
||||||
//V8
|
//V8
|
||||||
|
@ -174,4 +184,73 @@ fun V8ObjectToHashMap(obj: V8ValueObject?): HashMap<String, String> {
|
||||||
for(prop in obj.ownPropertyNames.keys.map { obj.ownPropertyNames.get<V8Value>(it).toString() })
|
for(prop in obj.ownPropertyNames.keys.map { obj.ownPropertyNames.get<V8Value>(it).toString() })
|
||||||
map.put(prop, obj.getString(prop));
|
map.put(prop, obj.getString(prop));
|
||||||
return map;
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun <T: V8Value> V8ValuePromise.toV8ValueBlocking(plugin: V8Plugin): T {
|
||||||
|
val latch = CountDownLatch(1);
|
||||||
|
var promiseResult: T? = null;
|
||||||
|
var promiseException: Throwable? = null;
|
||||||
|
plugin.busy {
|
||||||
|
this.register(object: IV8ValuePromise.IListener {
|
||||||
|
override fun onFulfilled(p0: V8Value?) {
|
||||||
|
if(p0 is V8ValueError)
|
||||||
|
promiseException = ScriptExecutionException(plugin.config, p0.message);
|
||||||
|
else
|
||||||
|
promiseResult = p0 as T;
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
override fun onRejected(p0: V8Value?) {
|
||||||
|
promiseException = (NotImplementedError("onRejected promise not implemented.."));
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
override fun onCatch(p0: V8Value?) {
|
||||||
|
promiseException = (NotImplementedError("onCatch promise not implemented.."));
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin.registerPromise(this) {
|
||||||
|
promiseException = CancellationException("Cancelled by system");
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
plugin.unbusy {
|
||||||
|
latch.await();
|
||||||
|
}
|
||||||
|
if(promiseException != null)
|
||||||
|
throw promiseException!!;
|
||||||
|
return promiseResult!!;
|
||||||
|
}
|
||||||
|
fun <T: V8Value> V8ValuePromise.toV8ValueAsync(plugin: V8Plugin): Deferred<T> {
|
||||||
|
val def = CompletableDeferred<T>();
|
||||||
|
val promise = this;
|
||||||
|
this.register(object: IV8ValuePromise.IListener {
|
||||||
|
override fun onFulfilled(p0: V8Value?) {
|
||||||
|
plugin.resolvePromise(promise);
|
||||||
|
def.complete(p0 as T);
|
||||||
|
}
|
||||||
|
override fun onRejected(p0: V8Value?) {
|
||||||
|
plugin.resolvePromise(promise);
|
||||||
|
def.completeExceptionally(NotImplementedError("onRejected promise not implemented.."));
|
||||||
|
}
|
||||||
|
override fun onCatch(p0: V8Value?) {
|
||||||
|
plugin.resolvePromise(promise);
|
||||||
|
def.completeExceptionally(NotImplementedError("onCatch promise not implemented.."));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
plugin.registerPromise(promise) {
|
||||||
|
if(def.isActive)
|
||||||
|
def.cancel("Cancelled by system");
|
||||||
|
}
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun <T: V8Value> V8ValueObject.invokeV8(method: String, vararg obj: Any): T {
|
||||||
|
var result = this.invoke<V8Value>(method, *obj);
|
||||||
|
if(result is V8ValuePromise) {
|
||||||
|
return result.toV8ValueBlocking(this.getSourcePlugin()!!);
|
||||||
|
}
|
||||||
|
return result as T;
|
||||||
}
|
}
|
|
@ -632,7 +632,6 @@ open class JSClient : IPlatformClient {
|
||||||
plugin.executeTyped("source.getLiveEvents(${Json.encodeToString(url)})"));
|
plugin.executeTyped("source.getLiveEvents(${Json.encodeToString(url)})"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@JSDocs(19, "source.getContentRecommendations(url)", "Gets recommendations of a content page")
|
@JSDocs(19, "source.getContentRecommendations(url)", "Gets recommendations of a content page")
|
||||||
@JSDocsParameter("url", "Url of content")
|
@JSDocsParameter("url", "Url of content")
|
||||||
override fun getContentRecommendations(url: String): IPager<IPlatformContent>? = isBusyWith("getContentRecommendations") {
|
override fun getContentRecommendations(url: String): IPager<IPlatformContent>? = isBusyWith("getContentRecommendations") {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.futo.platformplayer.api.media.platforms.js.models.sources
|
package com.futo.platformplayer.api.media.platforms.js.models.sources
|
||||||
|
|
||||||
|
import com.caoccao.javet.values.primitive.V8ValueString
|
||||||
import com.caoccao.javet.values.reference.V8ValueObject
|
import com.caoccao.javet.values.reference.V8ValueObject
|
||||||
import com.futo.platformplayer.api.media.models.streams.sources.IAudioSource
|
import com.futo.platformplayer.api.media.models.streams.sources.IAudioSource
|
||||||
import com.futo.platformplayer.api.media.models.streams.sources.IDashManifestSource
|
import com.futo.platformplayer.api.media.models.streams.sources.IDashManifestSource
|
||||||
|
@ -13,6 +14,7 @@ import com.futo.platformplayer.engine.V8Plugin
|
||||||
import com.futo.platformplayer.getOrDefault
|
import com.futo.platformplayer.getOrDefault
|
||||||
import com.futo.platformplayer.getOrNull
|
import com.futo.platformplayer.getOrNull
|
||||||
import com.futo.platformplayer.getOrThrow
|
import com.futo.platformplayer.getOrThrow
|
||||||
|
import com.futo.platformplayer.invokeV8
|
||||||
import com.futo.platformplayer.others.Language
|
import com.futo.platformplayer.others.Language
|
||||||
import com.futo.platformplayer.states.StateDeveloper
|
import com.futo.platformplayer.states.StateDeveloper
|
||||||
|
|
||||||
|
@ -63,14 +65,14 @@ class JSDashManifestRawAudioSource : JSSource, IAudioSource, IJSDashManifestRawS
|
||||||
result = StateDeveloper.instance.handleDevCall(_plugin.devID, "DashManifestRaw", false) {
|
result = StateDeveloper.instance.handleDevCall(_plugin.devID, "DashManifestRaw", false) {
|
||||||
_plugin.getUnderlyingPlugin().catchScriptErrors("DashManifestRaw", "dashManifestRaw.generate()") {
|
_plugin.getUnderlyingPlugin().catchScriptErrors("DashManifestRaw", "dashManifestRaw.generate()") {
|
||||||
_plugin.isBusyWith("dashAudio.generate") {
|
_plugin.isBusyWith("dashAudio.generate") {
|
||||||
_obj.invokeString("generate");
|
_obj.invokeV8<V8ValueString>("generate").value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
result = _plugin.getUnderlyingPlugin().catchScriptErrors("DashManifestRaw", "dashManifestRaw.generate()") {
|
result = _plugin.getUnderlyingPlugin().catchScriptErrors("DashManifestRaw", "dashManifestRaw.generate()") {
|
||||||
_plugin.isBusyWith("dashAudio.generate") {
|
_plugin.isBusyWith("dashAudio.generate") {
|
||||||
_obj.invokeString("generate");
|
_obj.invokeV8<V8ValueString>("generate").value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ import com.futo.platformplayer.engine.V8Plugin
|
||||||
import com.futo.platformplayer.getOrDefault
|
import com.futo.platformplayer.getOrDefault
|
||||||
import com.futo.platformplayer.getOrNull
|
import com.futo.platformplayer.getOrNull
|
||||||
import com.futo.platformplayer.getOrThrow
|
import com.futo.platformplayer.getOrThrow
|
||||||
|
import com.futo.platformplayer.invokeV8
|
||||||
import com.futo.platformplayer.states.StateDeveloper
|
import com.futo.platformplayer.states.StateDeveloper
|
||||||
|
|
||||||
interface IJSDashManifestRawSource {
|
interface IJSDashManifestRawSource {
|
||||||
|
@ -68,7 +69,7 @@ open class JSDashManifestRawSource: JSSource, IVideoSource, IJSDashManifestRawSo
|
||||||
result = StateDeveloper.instance.handleDevCall(_plugin.devID, "DashManifestRawSource.generate()") {
|
result = StateDeveloper.instance.handleDevCall(_plugin.devID, "DashManifestRawSource.generate()") {
|
||||||
_plugin.getUnderlyingPlugin().catchScriptErrors("DashManifestRaw.generate", "generate()", {
|
_plugin.getUnderlyingPlugin().catchScriptErrors("DashManifestRaw.generate", "generate()", {
|
||||||
_plugin.isBusyWith("dashVideo.generate") {
|
_plugin.isBusyWith("dashVideo.generate") {
|
||||||
_obj.invokeString("generate");
|
_obj.invokeV8<V8ValueString>("generate").value;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -76,7 +77,7 @@ open class JSDashManifestRawSource: JSSource, IVideoSource, IJSDashManifestRawSo
|
||||||
else
|
else
|
||||||
result = _plugin.getUnderlyingPlugin().catchScriptErrors("DashManifestRaw.generate", "generate()", {
|
result = _plugin.getUnderlyingPlugin().catchScriptErrors("DashManifestRaw.generate", "generate()", {
|
||||||
_plugin.isBusyWith("dashVideo.generate") {
|
_plugin.isBusyWith("dashVideo.generate") {
|
||||||
_obj.invokeString("generate");
|
_obj.invokeV8<V8ValueString>("generate").value;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,9 @@ import com.caoccao.javet.values.V8Value
|
||||||
import com.caoccao.javet.values.primitive.V8ValueBoolean
|
import com.caoccao.javet.values.primitive.V8ValueBoolean
|
||||||
import com.caoccao.javet.values.primitive.V8ValueInteger
|
import com.caoccao.javet.values.primitive.V8ValueInteger
|
||||||
import com.caoccao.javet.values.primitive.V8ValueString
|
import com.caoccao.javet.values.primitive.V8ValueString
|
||||||
|
import com.caoccao.javet.values.reference.IV8ValuePromise
|
||||||
import com.caoccao.javet.values.reference.V8ValueObject
|
import com.caoccao.javet.values.reference.V8ValueObject
|
||||||
|
import com.caoccao.javet.values.reference.V8ValuePromise
|
||||||
import com.futo.platformplayer.api.http.ManagedHttpClient
|
import com.futo.platformplayer.api.http.ManagedHttpClient
|
||||||
import com.futo.platformplayer.api.media.platforms.js.internal.JSHttpClient
|
import com.futo.platformplayer.api.media.platforms.js.internal.JSHttpClient
|
||||||
import com.futo.platformplayer.constructs.Event1
|
import com.futo.platformplayer.constructs.Event1
|
||||||
|
@ -37,7 +39,15 @@ import com.futo.platformplayer.engine.packages.V8Package
|
||||||
import com.futo.platformplayer.getOrThrow
|
import com.futo.platformplayer.getOrThrow
|
||||||
import com.futo.platformplayer.logging.Logger
|
import com.futo.platformplayer.logging.Logger
|
||||||
import com.futo.platformplayer.states.StateAssets
|
import com.futo.platformplayer.states.StateAssets
|
||||||
|
import com.futo.platformplayer.toList
|
||||||
|
import com.futo.platformplayer.toV8ValueBlocking
|
||||||
|
import com.futo.platformplayer.toV8ValueAsync
|
||||||
import com.futo.platformplayer.warnIfMainThread
|
import com.futo.platformplayer.warnIfMainThread
|
||||||
|
import kotlinx.coroutines.CompletableDeferred
|
||||||
|
import kotlinx.coroutines.Deferred
|
||||||
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
|
import kotlinx.coroutines.cancel
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import java.util.concurrent.locks.ReentrantLock
|
import java.util.concurrent.locks.ReentrantLock
|
||||||
import kotlin.concurrent.withLock
|
import kotlin.concurrent.withLock
|
||||||
|
@ -48,6 +58,7 @@ class V8Plugin {
|
||||||
private val _clientAuth: ManagedHttpClient;
|
private val _clientAuth: ManagedHttpClient;
|
||||||
private val _clientOthers: ConcurrentHashMap<String, JSHttpClient> = ConcurrentHashMap();
|
private val _clientOthers: ConcurrentHashMap<String, JSHttpClient> = ConcurrentHashMap();
|
||||||
|
|
||||||
|
private val _promises = ConcurrentHashMap<V8ValuePromise, ((V8ValuePromise)->Unit)?>();
|
||||||
|
|
||||||
val httpClient: ManagedHttpClient get() = _client;
|
val httpClient: ManagedHttpClient get() = _client;
|
||||||
val httpClientAuth: ManagedHttpClient get() = _clientAuth;
|
val httpClientAuth: ManagedHttpClient get() = _clientAuth;
|
||||||
|
@ -223,37 +234,144 @@ class V8Plugin {
|
||||||
Logger.i(TAG, "Plugin stopped");
|
Logger.i(TAG, "Plugin stopped");
|
||||||
onStopped.emit(this);
|
onStopped.emit(this);
|
||||||
}
|
}
|
||||||
|
cancelAllPromises();
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isThreadAlreadyBusy(): Boolean {
|
fun isThreadAlreadyBusy(): Boolean {
|
||||||
return _busyLock.isHeldByCurrentThread;
|
return _busyLock.isHeldByCurrentThread;
|
||||||
}
|
}
|
||||||
fun <T> busy(handle: ()->T): T {
|
fun <T> busy(handle: ()->T): T {
|
||||||
|
_busyLock.lock();
|
||||||
|
try {
|
||||||
|
return handle();
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
_busyLock.unlock();
|
||||||
|
}
|
||||||
|
/*
|
||||||
_busyLock.withLock {
|
_busyLock.withLock {
|
||||||
//Logger.i(TAG, "Entered busy: " + Thread.currentThread().stackTrace.drop(3)?.firstOrNull()?.toString() + ", " + Thread.currentThread().stackTrace.drop(4)?.firstOrNull()?.toString());
|
//Logger.i(TAG, "Entered busy: " + Thread.currentThread().stackTrace.drop(3)?.firstOrNull()?.toString() + ", " + Thread.currentThread().stackTrace.drop(4)?.firstOrNull()?.toString());
|
||||||
return handle();
|
return handle();
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
fun <T> unbusy(handle: ()->T): T {
|
||||||
|
val wasLocked = isThreadAlreadyBusy();
|
||||||
|
if(!wasLocked)
|
||||||
|
return handle();
|
||||||
|
val lockCount = _busyLock.holdCount;
|
||||||
|
for(i in 1..lockCount)
|
||||||
|
_busyLock.unlock();
|
||||||
|
try {
|
||||||
|
Logger.w(TAG, "Unlocking V8 thread for [${config.name}] for a blocking resolve of a promise")
|
||||||
|
return handle();
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
Logger.w(TAG, "Relocking V8 thread for [${config.name}] for a blocking resolve of a promise")
|
||||||
|
|
||||||
|
for(i in 1..lockCount)
|
||||||
|
_busyLock.lock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun execute(js: String) : V8Value {
|
fun execute(js: String) : V8Value {
|
||||||
return executeTyped<V8Value>(js);
|
return executeTyped<V8Value>(js);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun <T : V8Value> executeTypedAsync(js: String) : Deferred<T> {
|
||||||
|
warnIfMainThread("V8Plugin.executeTyped");
|
||||||
|
if(isStopped)
|
||||||
|
throw PluginEngineStoppedException(config, "Instance is stopped", js);
|
||||||
|
|
||||||
|
return withContext(IO) {
|
||||||
|
return@withContext busy {
|
||||||
|
try {
|
||||||
|
val runtime = _runtime ?: throw IllegalStateException("JSPlugin not started yet");
|
||||||
|
val result = catchScriptErrors<V8Value>("Plugin[${config.name}]", js) {
|
||||||
|
runtime.getExecutor(js).execute()
|
||||||
|
};
|
||||||
|
|
||||||
|
if (result is V8ValuePromise) {
|
||||||
|
return@busy result.toV8ValueAsync<T>(this@V8Plugin);
|
||||||
|
} else
|
||||||
|
return@busy CompletableDeferred(result as T);
|
||||||
|
}
|
||||||
|
catch(ex: Throwable) {
|
||||||
|
val def = CompletableDeferred<T>();
|
||||||
|
def.completeExceptionally(ex);
|
||||||
|
return@busy def;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
fun <T : V8Value> executeTyped(js: String) : T {
|
fun <T : V8Value> executeTyped(js: String) : T {
|
||||||
warnIfMainThread("V8Plugin.executeTyped");
|
warnIfMainThread("V8Plugin.executeTyped");
|
||||||
if(isStopped)
|
if(isStopped)
|
||||||
throw PluginEngineStoppedException(config, "Instance is stopped", js);
|
throw PluginEngineStoppedException(config, "Instance is stopped", js);
|
||||||
|
|
||||||
return busy {
|
val result = busy {
|
||||||
|
|
||||||
val runtime = _runtime ?: throw IllegalStateException("JSPlugin not started yet");
|
val runtime = _runtime ?: throw IllegalStateException("JSPlugin not started yet");
|
||||||
return@busy catchScriptErrors("Plugin[${config.name}]", js) {
|
return@busy catchScriptErrors<V8Value>("Plugin[${config.name}]", js) {
|
||||||
runtime.getExecutor(js).execute()
|
runtime.getExecutor(js).execute()
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
if(result is V8ValuePromise) {
|
||||||
|
return result.toV8ValueBlocking(this@V8Plugin);
|
||||||
}
|
}
|
||||||
|
return result as T;
|
||||||
}
|
}
|
||||||
fun executeBoolean(js: String) : Boolean? = busy { catchScriptErrors("Plugin[${config.name}]") { executeTyped<V8ValueBoolean>(js).value } }
|
fun executeBoolean(js: String) : Boolean? = busy { catchScriptErrors("Plugin[${config.name}]") { executeTyped<V8ValueBoolean>(js).value } }
|
||||||
fun executeString(js: String) : String? = busy { catchScriptErrors("Plugin[${config.name}]") { executeTyped<V8ValueString>(js).value } }
|
fun executeString(js: String) : String? = busy { catchScriptErrors("Plugin[${config.name}]") { executeTyped<V8ValueString>(js).value } }
|
||||||
fun executeInteger(js: String) : Int? = busy { catchScriptErrors("Plugin[${config.name}]") { executeTyped<V8ValueInteger>(js).value } }
|
fun executeInteger(js: String) : Int? = busy { catchScriptErrors("Plugin[${config.name}]") { executeTyped<V8ValueInteger>(js).value } }
|
||||||
|
|
||||||
|
|
||||||
|
fun <T: V8Value> handlePromise(result: V8ValuePromise): CompletableDeferred<T> {
|
||||||
|
val def = CompletableDeferred<T>();
|
||||||
|
result.register(object: IV8ValuePromise.IListener {
|
||||||
|
override fun onFulfilled(p0: V8Value?) {
|
||||||
|
resolvePromise(result);
|
||||||
|
def.complete(p0 as T);
|
||||||
|
}
|
||||||
|
override fun onRejected(p0: V8Value?) {
|
||||||
|
resolvePromise(result);
|
||||||
|
def.completeExceptionally(NotImplementedError("onRejected promise not implemented.."));
|
||||||
|
}
|
||||||
|
override fun onCatch(p0: V8Value?) {
|
||||||
|
resolvePromise(result);
|
||||||
|
def.completeExceptionally(NotImplementedError("onCatch promise not implemented.."));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
registerPromise(result) {
|
||||||
|
if(def.isActive)
|
||||||
|
def.cancel("Cancelled by system");
|
||||||
|
}
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
fun registerPromise(promise: V8ValuePromise, onCancelled: ((V8ValuePromise)->Unit)? = null) {
|
||||||
|
Logger.v(TAG, "Promise registered for plugin [${config.name}]: ${promise.hashCode()}");
|
||||||
|
if (onCancelled != null) {
|
||||||
|
_promises.put(promise, onCancelled)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
fun resolvePromise(promise: V8ValuePromise, cancelled: Boolean = false) {
|
||||||
|
Logger.v(TAG, "Promise resolved for plugin [${config.name}]: ${promise.hashCode()}");
|
||||||
|
val found = synchronized(_promises) {
|
||||||
|
val found = _promises.getOrDefault(promise, null);
|
||||||
|
_promises.remove(promise);
|
||||||
|
return@synchronized found;
|
||||||
|
};
|
||||||
|
if(found != null)
|
||||||
|
found(promise);
|
||||||
|
}
|
||||||
|
fun cancelAllPromises(){
|
||||||
|
val promises = _promises.keys().toList();
|
||||||
|
for(key in promises) {
|
||||||
|
try {
|
||||||
|
resolvePromise(key, true);
|
||||||
|
}
|
||||||
|
catch(ex: Throwable) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun getPackage(packageName: String, allowNull: Boolean = false): V8Package? {
|
private fun getPackage(packageName: String, allowNull: Boolean = false): V8Package? {
|
||||||
//TODO: Auto get all package types?
|
//TODO: Auto get all package types?
|
||||||
return when(packageName) {
|
return when(packageName) {
|
||||||
|
|
|
@ -84,7 +84,8 @@ class PackageBridge : V8Package {
|
||||||
fun supportedFeatures(): Array<String> {
|
fun supportedFeatures(): Array<String> {
|
||||||
return arrayOf(
|
return arrayOf(
|
||||||
"ReloadRequiredException",
|
"ReloadRequiredException",
|
||||||
"HttpBatchClient"
|
"HttpBatchClient",
|
||||||
|
"Async"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,9 +131,12 @@ class PackageBridge : V8Package {
|
||||||
}
|
}
|
||||||
timeoutMap.remove(id);
|
timeoutMap.remove(id);
|
||||||
try {
|
try {
|
||||||
|
Logger.w(TAG, "setTimeout before busy (${timeout}): ${_plugin.isBusy}");
|
||||||
_plugin.busy {
|
_plugin.busy {
|
||||||
|
Logger.w(TAG, "setTimeout in busy");
|
||||||
if (!_plugin.isStopped)
|
if (!_plugin.isStopped)
|
||||||
funcClone.callVoid(null, arrayOf<Any>());
|
funcClone.callVoid(null, arrayOf<Any>());
|
||||||
|
Logger.w(TAG, "setTimeout after");
|
||||||
}
|
}
|
||||||
} catch (ex: Throwable) {
|
} catch (ex: Throwable) {
|
||||||
Logger.e(TAG, "Failed timeout callback", ex);
|
Logger.e(TAG, "Failed timeout callback", ex);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue