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

View File

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

View File

@@ -1,23 +1,35 @@
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.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.augment.engines.Engines;
import org.autojs.autojs.script.ScriptSource;
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.
* Modified by SuperMonster003 as of Jan 1, 2022.
*/
public class ScriptExecutionGlobalListener implements ScriptExecutionListener {
private static final String ENGINE_TAG_START_TIME = "org.autojs.autojs.autojs.Goodbye, World";
@Override
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
@@ -25,29 +37,50 @@ public class ScriptExecutionGlobalListener implements ScriptExecutionListener {
onFinish(execution);
}
@SuppressLint("DefaultLocale")
private void onFinish(ScriptExecution execution) {
Long millis = (Long) execution.getEngine().getTag(ENGINE_TAG_START_TIME);
if (millis != null) {
printSeconds(execution, millis);
ScriptEngine<? extends ScriptSource> engine = execution.getEngine();
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) {
double seconds = (System.currentTimeMillis() - millis) / 1000.0;
private void printSeconds(ScriptExecution execution, Long startTime) {
double seconds = (System.currentTimeMillis() - startTime) / 1000.0;
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();
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
public void onException(ScriptExecution execution, Throwable e) {
ScriptEngine<? extends ScriptSource> engine = execution.getEngine();
emitEngineEvent("exception", engine, e);
emitEngineEvent("error", engine, e);
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.READONLY
import org.mozilla.javascript.ScriptableObject.UNINITIALIZED_CONST
import org.mozilla.javascript.WrappedException
import java.lang.reflect.InvocationTargetException
import java.util.function.Consumer
import java.util.function.Supplier
@@ -158,7 +157,7 @@ abstract class Augmentable(private val scriptRuntime: ScriptRuntime? = null) : F
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, key)
throw RuntimeException(message, e)
throw WrappedRuntimeException(message, e)
}
}
@@ -429,7 +428,7 @@ abstract class Augmentable(private val scriptRuntime: ScriptRuntime? = null) : F
else -> t
}
if (ScriptInterruptedException.causedByInterrupt(e)) {
throw WrappedException(e)
throw e
}
val funcNameSuffix = if (funcName != funcNameAlias) " (${globalContext.getString(R.string.text_alias)}: $funcNameAlias)" else ""
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.toRuntimePath
import org.autojs.autojs.extension.FlexibleArray
import org.autojs.autojs.extension.ScriptableExtensions.prop
import org.autojs.autojs.extension.ScriptableObjectExtensions.inquire
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.exception.WrappedIllegalArgumentException
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.coerceLongNumber
import org.autojs.autojs.util.RhinoUtils.coerceString
import org.autojs.autojs.util.RhinoUtils.newNativeObject
import org.mozilla.javascript.BaseFunction
import org.mozilla.javascript.NativeArray
import org.mozilla.javascript.NativeObject
import org.mozilla.javascript.ScriptableObject
@Suppress("unused")
class Engines(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
class Engines(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), AsEmitter {
override val selfAssignmentFunctions = listOf(
::all.name,
@@ -56,6 +60,13 @@ class Engines(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRunt
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
@RhinoRuntimeFunctionInterface
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.runtime.ScriptRuntime
import org.autojs.autojs.runtime.exception.ScriptInterruptedException
import org.autojs.autojs.runtime.exception.WrappedRuntimeException
import org.autojs.autojs6.BuildConfig
import org.mozilla.javascript.AbstractEcmaObjectOperations
import org.mozilla.javascript.BaseFunction
@@ -176,9 +177,9 @@ object RhinoUtils {
e.printStackTrace()
when {
isMainThread() -> {
scriptRuntime?.exit(e) ?: throw RuntimeException(e)
scriptRuntime?.exit(e) ?: throw WrappedRuntimeException(e)
}
else -> throw RuntimeException(e)
else -> throw WrappedRuntimeException(e)
}
}
}