Skip to content

Commit

Permalink
feat(scripting): setTimeout and setInterval support
Browse files Browse the repository at this point in the history
  • Loading branch information
rhunk committed Aug 21, 2024
1 parent 7d06d1c commit 8d2353b
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package me.rhunk.snapenhance.common.scripting

import android.os.Handler
import android.widget.Toast
import kotlinx.coroutines.*
import me.rhunk.snapenhance.common.scripting.bindings.AbstractBinding
import me.rhunk.snapenhance.common.scripting.bindings.BindingsContext
import me.rhunk.snapenhance.common.scripting.impl.JavaInterfaces
Expand All @@ -14,10 +15,8 @@ import me.rhunk.snapenhance.common.scripting.ktx.scriptableObject
import me.rhunk.snapenhance.common.scripting.type.ModuleInfo
import me.rhunk.snapenhance.common.scripting.type.Permissions
import me.rhunk.snapenhance.common.scripting.ui.InterfaceManager
import org.mozilla.javascript.*
import org.mozilla.javascript.Function
import org.mozilla.javascript.ScriptableObject
import org.mozilla.javascript.Undefined
import org.mozilla.javascript.Wrapper
import java.io.Reader
import java.lang.reflect.Modifier
import kotlin.reflect.KClass
Expand All @@ -27,13 +26,15 @@ class JSModule(
val moduleInfo: ModuleInfo,
private val reader: Reader,
) {
val coroutineScope = CoroutineScope(Dispatchers.IO)
private val moduleBindings = mutableMapOf<String, AbstractBinding>()
private lateinit var moduleObject: ScriptableObject

private val moduleBindingContext by lazy {
BindingsContext(
moduleInfo = moduleInfo,
runtime = scriptRuntime
runtime = scriptRuntime,
module = this,
)
}

Expand Down Expand Up @@ -158,6 +159,42 @@ class JSModule(
Undefined.instance
}

moduleObject.putFunction("setTimeout") {
val function = it?.get(0) as? Function ?: return@putFunction Undefined.instance
val time = it[1] as? Number ?: 0

return@putFunction coroutineScope.launch {
delay(time.toLong())
contextScope {
function.call(this, this@putFunction, this@putFunction, emptyArray())
}
}
}

moduleObject.putFunction("setInterval") {
val function = it?.get(0) as? Function ?: return@putFunction Undefined.instance
val time = it[1] as? Number ?: 0

return@putFunction coroutineScope.launch {
while (true) {
delay(time.toLong())
contextScope {
function.call(this, this@putFunction, this@putFunction, emptyArray())
}
}
}
}

arrayOf("clearInterval", "clearTimeout").forEach {
moduleObject.putFunction(it) { args ->
val job = args?.get(0) as? Job ?: return@putFunction Undefined.instance
runCatching {
job.cancel()
}
Undefined.instance
}
}

for (toastFunc in listOf("longToast", "shortToast")) {
moduleObject.putFunction(toastFunc) { args ->
Handler(scriptRuntime.androidContext.mainLooper).post {
Expand Down Expand Up @@ -205,6 +242,9 @@ class JSModule(

fun unload() {
callFunction("module.onUnload")
runCatching {
coroutineScope.cancel("Module unloaded")
}
moduleBindings.entries.removeIf { (name, binding) ->
runCatching {
binding.onDispose()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package me.rhunk.snapenhance.common.scripting.bindings

import me.rhunk.snapenhance.common.scripting.JSModule
import me.rhunk.snapenhance.common.scripting.ScriptRuntime
import me.rhunk.snapenhance.common.scripting.type.ModuleInfo

class BindingsContext(
val moduleInfo: ModuleInfo,
val runtime: ScriptRuntime
val runtime: ScriptRuntime,
val module: JSModule
)

0 comments on commit 8d2353b

Please sign in to comment.