11package com.stardust.autojs.runtime
22
3+ import android.os.Build
4+ import androidx.annotation.RequiresApi
5+ import com.stardust.automator.UiObjectCollection
36import org.mozilla.javascript.BaseFunction
47import org.mozilla.javascript.Context
58import org.mozilla.javascript.Scriptable
@@ -10,6 +13,17 @@ import org.mozilla.javascript.annotations.JSFunction
1013 * Created by Stardust on 2017/7/21.
1114 */
1215class ScriptBridges {
16+ companion object {
17+ fun <T > useJsContext (f : (context: Context ) -> T ): T {
18+ val context = Context .getCurrentContext()
19+ try {
20+ return f(context ? : Context .enter())
21+ } finally {
22+ context ? : Context .exit()
23+ }
24+ }
25+ }
26+
1327 interface Bridges {
1428 fun call (func : Any? , target : Any? , arg : Any? ): Any
1529 fun toArray (o : Iterable <* >? ): Any
@@ -22,46 +36,58 @@ class ScriptBridges {
2236 }
2337
2438 var bridges: Bridges ? = null
25- fun callFunction (func : Any? , target : Any? , args : Array <* >): Any {
39+ fun callFunction (func : Any? , target : Any? , args : Array <* >): Any = useJsContext< Any > { context ->
2640 val jsFn = func as BaseFunction
27- val cx = Context .getCurrentContext()
2841 val scope = jsFn.parentScope
29- val arr = args.map { Context .javaToJS(it, scope) }.toTypedArray()
30- try {
31- return jsFn.call(
32- cx ? : Context .enter(),
33- scope,
34- (Context .javaToJS(target, scope) as ? Scriptable ) ? : Undefined .SCRIPTABLE_UNDEFINED ,
35- arr
36- )
37- } finally {
38- cx ? : Context .exit()
39- }
40- }
42+ val arg = args.map { Context .javaToJS(it, scope) }.toTypedArray()
4143
42- private fun checkBridges () {
43- checkNotNull(bridges) { " no bridges set" }
44+ return @useJsContext jsFn.call(
45+ context, scope,
46+ (Context .javaToJS(target, scope) as ? Scriptable ) ? : Undefined .SCRIPTABLE_UNDEFINED ,
47+ arg
48+ )
4449 }
4550
4651 @JSFunction
47- fun toArray (c : Iterable <* >): Scriptable {
48- val cx = Context .getCurrentContext()
49- val te = cx ? : Context .enter()
50- try {
51- return te.newArray(te.initStandardObjects(), c.toList().toTypedArray())
52- } finally {
53- cx ? : Context .exit()
54- }
52+ fun toArray (c : Iterable <* >): Scriptable = useJsContext<Scriptable > { context ->
53+ val scope = context.initStandardObjects()
54+ return @useJsContext context.newArray(
55+ context.initStandardObjects(),
56+ c.map { Context .javaToJS(it, scope) }.toTypedArray()
57+ )
5558 }
5659
5760 fun toString (obj : Any? ): String {
5861 return Context .toString(obj)
5962 }
6063
61- fun asArray (list : Any? ): Any {
62- val arr = toArray(emptyList<Any ?>())
64+ fun asArray (obj : UiObjectCollection ): Any = useJsContext { context ->
65+ val arr = toArray(obj.mNodes)
66+ obj::class .members.forEach {
67+ val name = it.name
68+ val method = object : BaseFunction () {
69+ override fun getFunctionName (): String {
70+ return name
71+ }
6372
64- checkBridges()
65- return bridges!! .asArray(list)
73+ override fun call (
74+ cx : Context ? ,
75+ scope : Scriptable ? ,
76+ thisObj : Scriptable ? ,
77+ args : Array <out Any >?
78+ ): Any? {
79+ return if (args != null ) {
80+ it.call(obj, * args)
81+ } else it.call(obj)
82+ }
83+
84+ @RequiresApi(Build .VERSION_CODES .O )
85+ override fun getLength (): Int {
86+ return it.parameters.size
87+ }
88+ }
89+ arr.put(name, arr, method)
90+ }
91+ return @useJsContext arr
6692 }
6793}
0 commit comments