6.6.3 - Alpha - 新增 engines.on('start/stop/error', callback) 等事件监听方法

This commit is contained in:
SuperMonster003
2025-04-19 16:43:03 +08:00
parent 2804f4990f
commit d0b5a8fbad
6 changed files with 72 additions and 25 deletions

View File

@@ -3,7 +3,8 @@
"v6.6.3": { "v6.6.3": {
"released_date": "2025/04/19", "released_date": "2025/04/19",
"feature": [ "feature": [
"timers.keepAlive 方法 (已全局化), 用于保持脚本活跃状态" "timers.keepAlive 方法 (已全局化), 用于保持脚本活跃状态",
"engines.on('start/stop/error', callback) 等事件监听方法, 用于监听脚本引擎全局事件"
], ],
"fix": [ "fix": [
"主页文档标签显示在线文档时部分内容被系统导航栏遮挡的问题", "主页文档标签显示在线文档时部分内容被系统导航栏遮挡的问题",

View File

@@ -217,7 +217,9 @@ public class ScriptEngineService {
} }
public Set<ScriptEngine<? extends ScriptSource>> getEngines() { public Set<ScriptEngine<? extends ScriptSource>> getEngines() {
return mScriptEngineManager.getEngines(); synchronized (mScriptEngineManager) {
return new LinkedHashSet<>(mScriptEngineManager.getEngines());
}
} }
public Collection<ScriptExecution> getScriptExecutions() { public Collection<ScriptExecution> getScriptExecutions() {

View File

@@ -1,23 +1,35 @@
package org.autojs.autojs.execution; package org.autojs.autojs.execution;
import static org.autojs.autojs.util.StringUtils.str;
import android.annotation.SuppressLint;
import org.autojs.autojs.AutoJs; import org.autojs.autojs.AutoJs;
import org.autojs.autojs.core.pref.Language; import org.autojs.autojs.core.pref.Language;
import org.autojs.autojs.engine.JavaScriptEngine;
import org.autojs.autojs.engine.ScriptEngine;
import org.autojs.autojs.runtime.ScriptRuntime;
import org.autojs.autojs.runtime.api.Console; import org.autojs.autojs.runtime.api.Console;
import org.autojs.autojs.runtime.api.augment.engines.Engines;
import org.autojs.autojs.script.ScriptSource;
import org.autojs.autojs6.R; import org.autojs.autojs6.R;
import java.util.List;
import java.util.stream.Collectors;
import static org.autojs.autojs.util.StringUtils.str;
/** /**
* Created by Stardust on May 3, 2017. * Created by Stardust on May 3, 2017.
* Modified by SuperMonster003 as of Jan 1, 2022.
*/ */
public class ScriptExecutionGlobalListener implements ScriptExecutionListener { public class ScriptExecutionGlobalListener implements ScriptExecutionListener {
private static final String ENGINE_TAG_START_TIME = "org.autojs.autojs.autojs.Goodbye, World"; private static final String ENGINE_TAG_START_TIME = "org.autojs.autojs.autojs.Goodbye, World";
@Override @Override
public void onStart(ScriptExecution execution) { public void onStart(ScriptExecution execution) {
execution.getEngine().setTag(ENGINE_TAG_START_TIME, System.currentTimeMillis()); ScriptEngine<? extends ScriptSource> engine = execution.getEngine();
emitEngineEvent("start", engine);
engine.setTag(ENGINE_TAG_START_TIME, System.currentTimeMillis());
} }
@Override @Override
@@ -25,29 +37,50 @@ public class ScriptExecutionGlobalListener implements ScriptExecutionListener {
onFinish(execution); onFinish(execution);
} }
@SuppressLint("DefaultLocale")
private void onFinish(ScriptExecution execution) { private void onFinish(ScriptExecution execution) {
Long millis = (Long) execution.getEngine().getTag(ENGINE_TAG_START_TIME); ScriptEngine<? extends ScriptSource> engine = execution.getEngine();
if (millis != null) {
printSeconds(execution, millis); emitEngineEvent("finish", engine);
emitEngineEvent("exit", engine);
emitEngineEvent("stop", engine);
Long startTime = (Long) engine.getTag(ENGINE_TAG_START_TIME);
if (startTime != null) {
printSeconds(execution, startTime);
} }
} }
private void printSeconds(ScriptExecution execution, Long millis) { private void printSeconds(ScriptExecution execution, Long startTime) {
double seconds = (System.currentTimeMillis() - millis) / 1000.0; double seconds = (System.currentTimeMillis() - startTime) / 1000.0;
String secondsString = String.format(Language.getPrefLanguage().getLocale(), "%.3f", seconds).stripTrailing(); String secondsString = String.format(Language.getPrefLanguage().getLocale(), "%.3f", seconds).stripTrailing();
printSeconds(execution, secondsString);
}
private void printSeconds(ScriptExecution execution, String seconds) {
Console console = AutoJs.getInstance().getScriptEngineService().getGlobalConsole(); Console console = AutoJs.getInstance().getScriptEngineService().getGlobalConsole();
String path = execution.getSource().getElegantPath(); String path = execution.getSource().getElegantPath();
console.verbose(str(R.string.text_execution_finished, path, seconds)); console.verbose(str(R.string.text_execution_finished, path, secondsString));
} }
@Override @Override
public void onException(ScriptExecution execution, Throwable e) { public void onException(ScriptExecution execution, Throwable e) {
ScriptEngine<? extends ScriptSource> engine = execution.getEngine();
emitEngineEvent("exception", engine, e);
emitEngineEvent("error", engine, e);
onFinish(execution); onFinish(execution);
} }
} private void emitEngineEvent(String eventName, ScriptEngine<? extends ScriptSource> engine, Object... args) {
List<JavaScriptEngine> jsEngines = AutoJs.getInstance()
.getScriptEngineService()
.getEngines()
.stream()
.filter(JavaScriptEngine.class::isInstance)
.map(JavaScriptEngine.class::cast)
.collect(Collectors.toList());
for (JavaScriptEngine jsEngine : jsEngines) {
ScriptRuntime runtime = jsEngine.getRuntime();
Engines.emit(runtime, eventName, engine, args);
}
}
}

View File

@@ -29,7 +29,6 @@ import org.mozilla.javascript.ScriptableObject.DONTENUM
import org.mozilla.javascript.ScriptableObject.PERMANENT import org.mozilla.javascript.ScriptableObject.PERMANENT
import org.mozilla.javascript.ScriptableObject.READONLY import org.mozilla.javascript.ScriptableObject.READONLY
import org.mozilla.javascript.ScriptableObject.UNINITIALIZED_CONST import org.mozilla.javascript.ScriptableObject.UNINITIALIZED_CONST
import org.mozilla.javascript.WrappedException
import java.lang.reflect.InvocationTargetException import java.lang.reflect.InvocationTargetException
import java.util.function.Consumer import java.util.function.Consumer
import java.util.function.Supplier import java.util.function.Supplier
@@ -158,7 +157,7 @@ abstract class Augmentable(private val scriptRuntime: ScriptRuntime? = null) : F
val message = e.message?.let { val message = e.message?.let {
globalContext.getString(R.string.error_failed_to_instantiate_with_cause, key, it) globalContext.getString(R.string.error_failed_to_instantiate_with_cause, key, it)
} ?: globalContext.getString(R.string.error_failed_to_instantiate, key) } ?: globalContext.getString(R.string.error_failed_to_instantiate, key)
throw RuntimeException(message, e) throw WrappedRuntimeException(message, e)
} }
} }
@@ -429,7 +428,7 @@ abstract class Augmentable(private val scriptRuntime: ScriptRuntime? = null) : F
else -> t else -> t
} }
if (ScriptInterruptedException.causedByInterrupt(e)) { if (ScriptInterruptedException.causedByInterrupt(e)) {
throw WrappedException(e) throw e
} }
val funcNameSuffix = if (funcName != funcNameAlias) " (${globalContext.getString(R.string.text_alias)}: $funcNameAlias)" else "" val funcNameSuffix = if (funcName != funcNameAlias) " (${globalContext.getString(R.string.text_alias)}: $funcNameAlias)" else ""
val methodDescription = "$key.$funcName$funcNameSuffix" val methodDescription = "$key.$funcName$funcNameSuffix"

View File

@@ -9,21 +9,25 @@ import org.autojs.autojs.extension.AnyExtensions.isJsNullish
import org.autojs.autojs.extension.AnyExtensions.jsBrief import org.autojs.autojs.extension.AnyExtensions.jsBrief
import org.autojs.autojs.extension.AnyExtensions.toRuntimePath import org.autojs.autojs.extension.AnyExtensions.toRuntimePath
import org.autojs.autojs.extension.FlexibleArray import org.autojs.autojs.extension.FlexibleArray
import org.autojs.autojs.extension.ScriptableExtensions.prop
import org.autojs.autojs.extension.ScriptableObjectExtensions.inquire import org.autojs.autojs.extension.ScriptableObjectExtensions.inquire
import org.autojs.autojs.runtime.ScriptRuntime import org.autojs.autojs.runtime.ScriptRuntime
import org.autojs.autojs.runtime.api.augment.AsEmitter
import org.autojs.autojs.runtime.api.augment.Augmentable import org.autojs.autojs.runtime.api.augment.Augmentable
import org.autojs.autojs.runtime.exception.WrappedIllegalArgumentException import org.autojs.autojs.runtime.exception.WrappedIllegalArgumentException
import org.autojs.autojs.script.ScriptSource import org.autojs.autojs.script.ScriptSource
import org.autojs.autojs.util.RhinoUtils.callFunction
import org.autojs.autojs.util.RhinoUtils.coerceIntNumber import org.autojs.autojs.util.RhinoUtils.coerceIntNumber
import org.autojs.autojs.util.RhinoUtils.coerceLongNumber import org.autojs.autojs.util.RhinoUtils.coerceLongNumber
import org.autojs.autojs.util.RhinoUtils.coerceString import org.autojs.autojs.util.RhinoUtils.coerceString
import org.autojs.autojs.util.RhinoUtils.newNativeObject import org.autojs.autojs.util.RhinoUtils.newNativeObject
import org.mozilla.javascript.BaseFunction
import org.mozilla.javascript.NativeArray import org.mozilla.javascript.NativeArray
import org.mozilla.javascript.NativeObject import org.mozilla.javascript.NativeObject
import org.mozilla.javascript.ScriptableObject import org.mozilla.javascript.ScriptableObject
@Suppress("unused") @Suppress("unused")
class Engines(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) { class Engines(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), AsEmitter {
override val selfAssignmentFunctions = listOf( override val selfAssignmentFunctions = listOf(
::all.name, ::all.name,
@@ -56,6 +60,13 @@ class Engines(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRunt
companion object : FlexibleArray() { companion object : FlexibleArray() {
@JvmStatic
fun emit(scriptRuntime: ScriptRuntime, eventName: String, vararg args: Any?) {
val engines = scriptRuntime.topLevelScope.prop("engines") as? ScriptableObject ?: return
val emitFunc = engines.prop("emit") as BaseFunction
callFunction(scriptRuntime, emitFunc, arrayOf(eventName, *args))
}
@JvmStatic @JvmStatic
@RhinoRuntimeFunctionInterface @RhinoRuntimeFunctionInterface
fun all(scriptRuntime: ScriptRuntime, args: Array<out Any?>): NativeArray = ensureArgumentsIsEmpty(args) { fun all(scriptRuntime: ScriptRuntime, args: Array<out Any?>): NativeArray = ensureArgumentsIsEmpty(args) {

View File

@@ -17,6 +17,7 @@ import org.autojs.autojs.extension.ScriptableExtensions.prop
import org.autojs.autojs.rhino.TopLevelScope import org.autojs.autojs.rhino.TopLevelScope
import org.autojs.autojs.runtime.ScriptRuntime import org.autojs.autojs.runtime.ScriptRuntime
import org.autojs.autojs.runtime.exception.ScriptInterruptedException import org.autojs.autojs.runtime.exception.ScriptInterruptedException
import org.autojs.autojs.runtime.exception.WrappedRuntimeException
import org.autojs.autojs6.BuildConfig import org.autojs.autojs6.BuildConfig
import org.mozilla.javascript.AbstractEcmaObjectOperations import org.mozilla.javascript.AbstractEcmaObjectOperations
import org.mozilla.javascript.BaseFunction import org.mozilla.javascript.BaseFunction
@@ -176,9 +177,9 @@ object RhinoUtils {
e.printStackTrace() e.printStackTrace()
when { when {
isMainThread() -> { isMainThread() -> {
scriptRuntime?.exit(e) ?: throw RuntimeException(e) scriptRuntime?.exit(e) ?: throw WrappedRuntimeException(e)
} }
else -> throw RuntimeException(e) else -> throw WrappedRuntimeException(e)
} }
} }
} }