perf: cache, lazy invoke
Some checks are pending
Build-Apk / build (push) Waiting to run

This commit is contained in:
lisonge 2024-07-03 17:38:05 +08:00
parent c78d7c0047
commit 0c1cc78ee4
7 changed files with 27 additions and 20 deletions

View File

@ -4,7 +4,7 @@ import android.accessibilityservice.AccessibilityService
import android.view.accessibility.AccessibilityNodeInfo
import kotlinx.coroutines.Job
import li.songe.gkd.service.createCacheTransform
import li.songe.gkd.service.createTransform
import li.songe.gkd.service.createNoCacheTransform
import li.songe.gkd.service.lastTriggerRule
import li.songe.gkd.service.lastTriggerTime
import li.songe.gkd.service.querySelector
@ -130,8 +130,8 @@ sealed class ResolvedRule(
else -> true
}
private val canCacheIndex = (matches + excludeMatches).any { s -> s.useCache }
private val transform = if (canCacheIndex) defaultCacheTransform.transform else defaultTransform
private val useCache = (matches + excludeMatches).any { s -> s.useCache }
private val transform = if (useCache) defaultCacheTransform else defaultTransform
fun query(
nodeInfo: AccessibilityNodeInfo?,
@ -141,24 +141,25 @@ sealed class ResolvedRule(
var target: AccessibilityNodeInfo? = null
if (anyMatches.isNotEmpty()) {
for (selector in anyMatches) {
target = nodeInfo.querySelector(selector, quickFind, transform)
target = nodeInfo.querySelector(selector, quickFind, transform.transform)
?: break
}
if (target == null) return null
}
for (selector in matches) {
target = nodeInfo.querySelector(selector, quickFind, transform)
target = nodeInfo.querySelector(selector, quickFind, transform.transform)
?: return null
}
for (selector in excludeMatches) {
nodeInfo.querySelector(
selector,
quickFind,
transform
transform.transform
)?.let { return null }
}
return target
} finally {
defaultTransform.cache.clear()
defaultCacheTransform.cache.clear()
}
}
@ -247,7 +248,7 @@ fun getFixActivityIds(
}
}
private val defaultTransform = createTransform()
private val defaultTransform = createNoCacheTransform()
private val defaultCacheTransform = createCacheTransform()

View File

@ -493,14 +493,14 @@ fun createCacheTransform(): CacheTransform {
return CacheTransform(transform, cache)
}
private fun List<Any?>.getIntOrNull(i: Int = 0): Int? {
private fun List<Any>.getIntOrNull(i: Int = 0): Int? {
return getOrNull(i) as? Int ?: return null
}
fun createTransform(): Transform<AccessibilityNodeInfo> {
fun createNoCacheTransform(): CacheTransform {
val cache = NodeCache()
val getNodeAttr = createGetNodeAttr(cache)
return Transform(
val transform = Transform(
getAttr = { target, name ->
when (target) {
is AccessibilityNodeInfo -> getNodeAttr(target, name)
@ -569,4 +569,5 @@ fun createTransform(): Transform<AccessibilityNodeInfo> {
}
},
)
return CacheTransform(transform, cache)
}

View File

@ -6,7 +6,7 @@ import kotlin.js.JsExport
@Suppress("UNCHECKED_CAST", "UNUSED")
class MultiplatformTransform<T : Any>(
getAttr: (Any?, String) -> Any?,
getInvoke: (Any?, String, List<Any?>) -> Any?,
getInvoke: (Any?, String, List<Any>) -> Any?,
getName: (T) -> String?,
getChildren: (T) -> Array<T>,
getParent: (T) -> T?,

View File

@ -93,10 +93,7 @@ class Selector internal constructor(
}
val useCache = run {
if (connectKeys.contains(ConnectOperator.BeforeBrother.key)) {
return@run true
}
if (connectKeys.contains(ConnectOperator.AfterBrother.key)) {
if (connectKeys.isNotEmpty()) {
return@run true
}
binaryExpressions.forEach { b ->
@ -139,7 +136,7 @@ class Selector internal constructor(
}
private val useCacheProperties by lazy {
arrayOf("index", "parent")
arrayOf("index", "parent", "depth")
}
private val useCacheMethods by lazy {
arrayOf("getChild")

View File

@ -3,7 +3,7 @@ package li.songe.selector
@Suppress("UNUSED")
class Transform<T>(
val getAttr: (Any?, String) -> Any?,
val getInvoke: (Any?, String, List<Any?>) -> Any? = { _, _, _ -> null },
val getInvoke: (Any?, String, List<Any>) -> Any? = { _, _, _ -> null },
val getName: (T) -> CharSequence?,
val getChildren: (T) -> Sequence<T>,
val getParent: (T) -> T?,

View File

@ -56,6 +56,7 @@ sealed class ValueExpression(open val value: Any?, open val type: String) : Posi
override fun <T> getAttr(node: T, transform: Transform<T>): Any? {
return when (callee) {
is CallExpression -> {
// not support
null
}
@ -63,15 +64,15 @@ sealed class ValueExpression(open val value: Any?, open val type: String) : Posi
transform.getInvoke(
node,
callee.value,
arguments.map { it.getAttr(node, transform) }
arguments.map { it.getAttr(node, transform).whenNull { return null } }
)
}
is MemberExpression -> {
transform.getInvoke(
callee.object0.getAttr(node, transform),
callee.object0.getAttr(node, transform).whenNull { return null },
callee.property,
arguments.map { it.getAttr(node, transform) }
arguments.map { it.getAttr(node, transform).whenNull { return null } }
)
}
}

View File

@ -63,6 +63,13 @@ internal fun optimizeMatchString(value: String): ((CharSequence) -> Boolean)? {
return null
}
internal inline fun <T> T?.whenNull(block: () -> Nothing): T {
if (this == null) {
block()
}
return this
}
@JsExport
class DefaultTypeInfo(
val booleanType: TypeInfo,