diff --git a/project/module-common/src/main/kotlin/cn/fd/ratziel/common/element/ElementEvaluator.kt b/project/module-common/src/main/kotlin/cn/fd/ratziel/common/element/ElementEvaluator.kt index 0487292c..36100c10 100644 --- a/project/module-common/src/main/kotlin/cn/fd/ratziel/common/element/ElementEvaluator.kt +++ b/project/module-common/src/main/kotlin/cn/fd/ratziel/common/element/ElementEvaluator.kt @@ -5,9 +5,9 @@ import cn.fd.ratziel.core.element.Element import cn.fd.ratziel.core.element.api.ElementHandler import cn.fd.ratziel.core.element.service.ElementRegistry import cn.fd.ratziel.core.util.FutureFactory -import cn.fd.ratziel.function.argument.ArgumentContext -import cn.fd.ratziel.function.argument.SimpleArgumentContext -import cn.fd.ratziel.function.argument.popOrNull +import cn.fd.ratziel.function.ArgumentContext +import cn.fd.ratziel.function.SimpleArgumentContext +import cn.fd.ratziel.function.popOrNull import taboolib.common.LifeCycle import taboolib.common.TabooLib import taboolib.common.platform.function.severe diff --git a/project/module-core/src/main/java/cn/fd/ratziel/function/ArgumentContext.java b/project/module-core/src/main/java/cn/fd/ratziel/function/ArgumentContext.java new file mode 100644 index 00000000..4e002935 --- /dev/null +++ b/project/module-core/src/main/java/cn/fd/ratziel/function/ArgumentContext.java @@ -0,0 +1,67 @@ +package cn.fd.ratziel.function; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * ArgumentContext - 参数上下文 + * 本质为一个参数容器 + * + * @author TheFloodDragon + * @since 2024/7/16 11:56 + */ +public interface ArgumentContext { + + /** + * 弹出第一个指定类型的参数 + * + * @throws NullPointerException 当无法找到指定类型的参数时抛出 + */ + @NotNull + default T pop(@NotNull Class type) throws NullPointerException { + T result = popOrNull(type); + if (result == null) throw new NullPointerException("Cannot find argument: " + type.getName() + " !"); + return result; + } + + /** + * 弹出第一个指定类型的参数 + * 若无法找到, 则返回空 + */ + @Nullable + T popOrNull(@NotNull Class type); + + /** + * 弹出第一个指定类型的参数 + * 若无法找到, 则返回默认值 + */ + @NotNull + default T popOr(@NotNull Class type, @NotNull T def) { + T result = popOrNull(type); + if (result == null) return def; + return result; + } + + /** + * 弹出所有指定类型的参数 + */ + @NotNull + Iterable popAll(@NotNull Class type); + + /** + * 添加一个参数元素 + */ + boolean add(Object element); + + /** + * 删除一个参数元素 + */ + boolean remove(Object element); + + /** + * 获取所有参数 + */ + @NotNull + Iterable args(); + +} diff --git a/project/module-core/src/main/kotlin/cn/fd/ratziel/function/argument/ArgumentUtil.kt b/project/module-core/src/main/kotlin/cn/fd/ratziel/function/ArgumentUtil.kt similarity index 73% rename from project/module-core/src/main/kotlin/cn/fd/ratziel/function/argument/ArgumentUtil.kt rename to project/module-core/src/main/kotlin/cn/fd/ratziel/function/ArgumentUtil.kt index 69e31bdb..6ca5e422 100644 --- a/project/module-core/src/main/kotlin/cn/fd/ratziel/function/argument/ArgumentUtil.kt +++ b/project/module-core/src/main/kotlin/cn/fd/ratziel/function/ArgumentUtil.kt @@ -1,5 +1,7 @@ -package cn.fd.ratziel.function.argument +package cn.fd.ratziel.function +import cn.fd.ratziel.function.argument.Argument +import cn.fd.ratziel.function.argument.ArgumentSupplier import cn.fd.ratziel.function.argument.exception.ArgumentException import cn.fd.ratziel.function.util.uncheck import java.util.function.Function @@ -41,10 +43,10 @@ inline fun Argument.ascertain( onFalse: Function, R> ): R = this.ascertain(T::class.java, onTrue, onFalse) -inline fun ArgumentContext.pop() = pop(T::class.java) +inline fun ArgumentContext.pop() = pop(T::class.java) -inline fun ArgumentContext.popAll() = popAll(T::class.java) +inline fun ArgumentContext.popAll() = popAll(T::class.java) -inline fun ArgumentContext.popOr(default: T) = popOr(T::class.java, default) +inline fun ArgumentContext.popOr(default: T) = popOr(T::class.java, default) -inline fun ArgumentContext.popOrNull() = popOrNull(T::class.java) \ No newline at end of file +inline fun ArgumentContext.popOrNull() = popOrNull(T::class.java) \ No newline at end of file diff --git a/project/module-core/src/main/kotlin/cn/fd/ratziel/function/argument/SimpleArgumentContext.kt b/project/module-core/src/main/kotlin/cn/fd/ratziel/function/SimpleArgumentContext.kt similarity index 59% rename from project/module-core/src/main/kotlin/cn/fd/ratziel/function/argument/SimpleArgumentContext.kt rename to project/module-core/src/main/kotlin/cn/fd/ratziel/function/SimpleArgumentContext.kt index 892bc823..e3d892d9 100644 --- a/project/module-core/src/main/kotlin/cn/fd/ratziel/function/argument/SimpleArgumentContext.kt +++ b/project/module-core/src/main/kotlin/cn/fd/ratziel/function/SimpleArgumentContext.kt @@ -1,6 +1,5 @@ -package cn.fd.ratziel.function.argument +package cn.fd.ratziel.function -import cn.fd.ratziel.function.argument.exception.ArgumentNotFoundException import cn.fd.ratziel.function.util.uncheck import java.util.concurrent.CopyOnWriteArraySet @@ -16,11 +15,11 @@ open class SimpleArgumentContext( constructor(vararg values: Any) : this(CopyOnWriteArraySet().apply { values.forEach { add(it) } }) - override fun popOrNull(type: Class): T? { + override fun popOrNull(type: Class): T? { return uncheck(collection.find { type.isAssignableFrom(it::class.java) }) } - override fun popAll(type: Class): Iterable { + override fun popAll(type: Class): Iterable { return uncheck(collection.filter { type.isAssignableFrom(it::class.java) }) } @@ -28,12 +27,4 @@ open class SimpleArgumentContext( return collection } - override fun pop(type: Class): T { - return popOrNull(type) ?: throw ArgumentNotFoundException(type) - } - - override fun popOr(type: Class, default: T): T { - return popOrNull(type) ?: default - } - } \ No newline at end of file diff --git a/project/module-core/src/main/kotlin/cn/fd/ratziel/function/argument/ArgumentContext.kt b/project/module-core/src/main/kotlin/cn/fd/ratziel/function/argument/ArgumentContext.kt deleted file mode 100644 index b305d4cf..00000000 --- a/project/module-core/src/main/kotlin/cn/fd/ratziel/function/argument/ArgumentContext.kt +++ /dev/null @@ -1,54 +0,0 @@ -package cn.fd.ratziel.function.argument - -import cn.fd.ratziel.function.argument.exception.ArgumentNotFoundException - -/** - * ArgumentContext - 参数上下文 - * - * 本质为一个参数容器 - * - * @author TheFloodDragon - * @since 2024/6/28 16:14 - */ -interface ArgumentContext { - - /** - * 弹出第一个指定类型的参数 - * @throws ArgumentNotFoundException 当无法找到指定类型的参数时抛出 - */ - @Throws(ArgumentNotFoundException::class) - fun pop(type: Class): T - - /** - * 弹出第一个指定类型的参数 - * 若无法找到, 则返回空 - */ - fun popOrNull(type: Class): T? - - /** - * 弹出第一个指定类型的参数 - * 若无法找到, 则返回默认值 - */ - fun popOr(type: Class, default: T): T - - /** - * 弹出所有指定类型的参数 - */ - fun popAll(type: Class): Iterable - - /** - * 添加一个参数元素 - */ - fun add(element: Any): Boolean - - /** - * 删除一个参数元素 - */ - fun remove(element: Any): Boolean - - /** - * 获取所有参数 - */ - fun args(): Collection - -} \ No newline at end of file diff --git a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/api/ArgumentResolver.kt b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/api/ArgumentResolver.kt index 03471cb9..38d132e4 100644 --- a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/api/ArgumentResolver.kt +++ b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/api/ArgumentResolver.kt @@ -1,7 +1,7 @@ package cn.fd.ratziel.module.item.api -import cn.fd.ratziel.function.argument.ArgumentContext -import cn.fd.ratziel.function.argument.SimpleArgumentContext +import cn.fd.ratziel.function.ArgumentContext +import cn.fd.ratziel.function.SimpleArgumentContext /** * ArgumentResolver diff --git a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/api/builder/ItemGenerator.kt b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/api/builder/ItemGenerator.kt index 2712f206..a9bc35da 100644 --- a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/api/builder/ItemGenerator.kt +++ b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/api/builder/ItemGenerator.kt @@ -1,7 +1,7 @@ package cn.fd.ratziel.module.item.api.builder -import cn.fd.ratziel.function.argument.ArgumentContext -import cn.fd.ratziel.function.argument.SimpleArgumentContext +import cn.fd.ratziel.function.ArgumentContext +import cn.fd.ratziel.function.SimpleArgumentContext import cn.fd.ratziel.module.item.api.NeoItem import java.util.concurrent.CompletableFuture diff --git a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/api/feature/ItemAction.kt b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/api/feature/ItemAction.kt index 1641bcc8..a3a74200 100644 --- a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/api/feature/ItemAction.kt +++ b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/api/feature/ItemAction.kt @@ -1,6 +1,6 @@ package cn.fd.ratziel.module.item.api.feature -import cn.fd.ratziel.function.argument.ArgumentContext +import cn.fd.ratziel.script.api.ScriptEnvironment /** * ItemAction - 物品动作 @@ -13,6 +13,6 @@ interface ItemAction { /** * 执行物品动作 */ - fun execute(context: ArgumentContext) + fun execute(context: ScriptEnvironment) } \ No newline at end of file diff --git a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/command/ItemCommand.kt b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/command/ItemCommand.kt index eb8e26ee..12d2a8f1 100644 --- a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/command/ItemCommand.kt +++ b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/command/ItemCommand.kt @@ -1,6 +1,6 @@ package cn.fd.ratziel.module.item.command -import cn.fd.ratziel.function.argument.SimpleArgumentContext +import cn.fd.ratziel.function.SimpleArgumentContext import cn.fd.ratziel.module.item.ItemManager import cn.fd.ratziel.module.item.nms.RefItemStack import org.bukkit.entity.Player diff --git a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/event/ItemBuildEvent.kt b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/event/ItemBuildEvent.kt index 5587869a..dc0b0db0 100644 --- a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/event/ItemBuildEvent.kt +++ b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/event/ItemBuildEvent.kt @@ -1,7 +1,7 @@ package cn.fd.ratziel.module.item.event import cn.fd.ratziel.core.Identifier -import cn.fd.ratziel.function.argument.ArgumentContext +import cn.fd.ratziel.function.ArgumentContext import cn.fd.ratziel.module.item.api.NeoItem import cn.fd.ratziel.module.item.api.builder.ItemGenerator diff --git a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/event/ItemResolvedEvent.kt b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/event/ItemResolvedEvent.kt index 438d5927..8fe7759b 100644 --- a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/event/ItemResolvedEvent.kt +++ b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/event/ItemResolvedEvent.kt @@ -1,7 +1,7 @@ package cn.fd.ratziel.module.item.event import cn.fd.ratziel.core.Identifier -import cn.fd.ratziel.function.argument.ArgumentContext +import cn.fd.ratziel.function.ArgumentContext import kotlinx.serialization.json.JsonElement /** diff --git a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/DefaultItemGenerator.kt b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/DefaultItemGenerator.kt index ea9c3d67..2eac4c36 100644 --- a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/DefaultItemGenerator.kt +++ b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/DefaultItemGenerator.kt @@ -6,7 +6,7 @@ import cn.fd.ratziel.core.Priority import cn.fd.ratziel.core.element.Element import cn.fd.ratziel.core.util.FutureFactory import cn.fd.ratziel.core.util.sortPriority -import cn.fd.ratziel.function.argument.ArgumentContext +import cn.fd.ratziel.function.ArgumentContext import cn.fd.ratziel.module.item.ItemElement import cn.fd.ratziel.module.item.ItemRegistry import cn.fd.ratziel.module.item.api.ItemData diff --git a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/BasicItemResolver.kt b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/BasicItemResolver.kt index fc6d55fa..64d725f8 100644 --- a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/BasicItemResolver.kt +++ b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/BasicItemResolver.kt @@ -5,7 +5,7 @@ import cn.fd.ratziel.core.serialization.asMutable import cn.fd.ratziel.core.serialization.handlePrimitives import cn.fd.ratziel.core.util.priority import cn.fd.ratziel.core.util.sortPriority -import cn.fd.ratziel.function.argument.ArgumentContext +import cn.fd.ratziel.function.ArgumentContext import cn.fd.ratziel.module.item.api.builder.ItemResolver import cn.fd.ratziel.module.item.impl.builder.DefaultItemSerializer import cn.fd.ratziel.module.item.impl.builder.resolver.sectionResolvers.PapiResolver diff --git a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/BasicTagResolver.kt b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/BasicTagResolver.kt index 97582aa8..9c640b7d 100644 --- a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/BasicTagResolver.kt +++ b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/BasicTagResolver.kt @@ -1,7 +1,7 @@ package cn.fd.ratziel.module.item.impl.builder.resolver import cn.fd.ratziel.core.util.splitNonEscaped -import cn.fd.ratziel.function.argument.ArgumentContext +import cn.fd.ratziel.function.ArgumentContext import cn.fd.ratziel.module.item.impl.builder.resolver.sectionResolvers.PapiResolver import cn.fd.ratziel.module.item.impl.builder.resolver.sectionResolvers.RandomResolver import taboolib.common.util.VariableReader diff --git a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/sectionResolvers/PapiResolver.kt b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/sectionResolvers/PapiResolver.kt index 8bdecb91..6f053ef9 100644 --- a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/sectionResolvers/PapiResolver.kt +++ b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/sectionResolvers/PapiResolver.kt @@ -1,7 +1,7 @@ package cn.fd.ratziel.module.item.impl.builder.resolver.sectionResolvers -import cn.fd.ratziel.function.argument.ArgumentContext -import cn.fd.ratziel.function.argument.popOrNull +import cn.fd.ratziel.function.ArgumentContext +import cn.fd.ratziel.function.popOrNull import cn.fd.ratziel.module.item.impl.builder.resolver.SectionResolver import org.bukkit.OfflinePlayer import taboolib.common.platform.ProxyPlayer diff --git a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/sectionResolvers/RandomResolver.kt b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/sectionResolvers/RandomResolver.kt index da637e03..2e83416e 100644 --- a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/sectionResolvers/RandomResolver.kt +++ b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/sectionResolvers/RandomResolver.kt @@ -1,6 +1,6 @@ package cn.fd.ratziel.module.item.impl.builder.resolver.sectionResolvers -import cn.fd.ratziel.function.argument.ArgumentContext +import cn.fd.ratziel.function.ArgumentContext import cn.fd.ratziel.module.item.impl.builder.resolver.SectionResolver import taboolib.common.util.random diff --git a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/feature/action/ActionManager.kt b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/feature/action/ActionManager.kt index b9b46962..b5821bed 100644 --- a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/feature/action/ActionManager.kt +++ b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/feature/action/ActionManager.kt @@ -1,7 +1,7 @@ package cn.fd.ratziel.module.item.impl.feature.action import cn.fd.ratziel.core.Identifier -import cn.fd.ratziel.function.argument.SimpleArgumentContext +import cn.fd.ratziel.function.SimpleArgumentContext import cn.fd.ratziel.module.item.api.feature.ItemTrigger import cn.fd.ratziel.module.item.impl.feature.action.triggers.* import cn.fd.ratziel.module.item.impl.service.NativeServiceRegistry diff --git a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/feature/action/ActionRegister.kt b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/feature/action/ActionRegister.kt index 0b69ca80..7cc79cbb 100644 --- a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/feature/action/ActionRegister.kt +++ b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/feature/action/ActionRegister.kt @@ -4,6 +4,7 @@ import cn.fd.ratziel.core.serialization.getBy import cn.fd.ratziel.core.serialization.toBasic import cn.fd.ratziel.module.item.event.ItemResolvedEvent import cn.fd.ratziel.script.ScriptBlockBuilder +import cn.fd.ratziel.script.ScriptManager import kotlinx.serialization.json.JsonObject import taboolib.common.platform.event.SubscribeEvent import taboolib.common.platform.function.severe @@ -36,7 +37,7 @@ object ActionRegister { continue } // 构建脚本块 - val block = ScriptBlockBuilder.build(raw.value.toBasic()) + val block = ScriptBlockBuilder.build(raw.value.toBasic(), ScriptManager.defaultScriptLanguage.executor) // 创建脚本动作, 放入表中 map[type] = ScriptedAction(block) } diff --git a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/feature/action/ScriptedAction.kt b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/feature/action/ScriptedAction.kt index d9177b5c..6eb12950 100644 --- a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/feature/action/ScriptedAction.kt +++ b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/feature/action/ScriptedAction.kt @@ -1,11 +1,8 @@ package cn.fd.ratziel.module.item.impl.feature.action -import cn.fd.ratziel.function.argument.ArgumentContext import cn.fd.ratziel.module.item.api.feature.ItemAction -import cn.fd.ratziel.script.ScriptTypes import cn.fd.ratziel.script.api.EvaluableScript import cn.fd.ratziel.script.api.ScriptEnvironment -import cn.fd.ratziel.script.impl.SimpleScriptEnvironment /** * ScriptedAction @@ -20,9 +17,8 @@ open class ScriptedAction( val script: EvaluableScript, ) : ItemAction { - override fun execute(context: ArgumentContext) { - val environment = context.popOr(ScriptEnvironment::class.java, SimpleScriptEnvironment(context)) - script.evaluate(ScriptTypes.KETHER.executor, environment) + override fun execute(context: ScriptEnvironment) { + script.evaluate(context) } } \ No newline at end of file diff --git a/project/module-script/src/main/java/cn/fd/ratziel/script/api/EvaluableScript.java b/project/module-script/src/main/java/cn/fd/ratziel/script/api/EvaluableScript.java index ec36be1b..e6f8212c 100644 --- a/project/module-script/src/main/java/cn/fd/ratziel/script/api/EvaluableScript.java +++ b/project/module-script/src/main/java/cn/fd/ratziel/script/api/EvaluableScript.java @@ -17,11 +17,18 @@ public interface EvaluableScript { /** * 评估脚本 * - * @param executor 覆写的脚本执行器 * @param environment 覆写的的脚本环境 * @throws ScriptException 当脚本评估中产生错误时抛出 */ @Nullable - Object evaluate(@NotNull ScriptExecutor executor, @NotNull ScriptEnvironment environment) throws ScriptException; + Object evaluate(@NotNull ScriptEnvironment environment) throws ScriptException; + + /** + * 获取脚本执行器 + * + * @return 覆写的脚本执行器 + */ + @NotNull + ScriptExecutor getExecutor(); } diff --git a/project/module-script/src/main/java/cn/fd/ratziel/script/api/ScriptEnvironment.java b/project/module-script/src/main/java/cn/fd/ratziel/script/api/ScriptEnvironment.java index 1d69ffd1..9384672c 100644 --- a/project/module-script/src/main/java/cn/fd/ratziel/script/api/ScriptEnvironment.java +++ b/project/module-script/src/main/java/cn/fd/ratziel/script/api/ScriptEnvironment.java @@ -1,10 +1,11 @@ package cn.fd.ratziel.script.api; -import cn.fd.ratziel.function.argument.ArgumentContext; +import cn.fd.ratziel.function.ArgumentContext; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.script.Bindings; +import java.util.function.Consumer; /** * ScriptEnvironment - 脚本环境 @@ -46,4 +47,13 @@ default void set(@NotNull String key, @Nullable Object value) { */ void setContext(@NotNull ArgumentContext context); + /** + * Applier - 环境信息转换和处理 + * + * @author TheFloodDragon + * @since 2024/7/16 12:15 + */ + interface Applier extends Consumer<@NotNull ScriptEnvironment> { + } + } diff --git a/project/module-script/src/main/java/cn/fd/ratziel/script/api/StorableScript.java b/project/module-script/src/main/java/cn/fd/ratziel/script/api/StorableScript.java index 54cf0307..d44fd12c 100644 --- a/project/module-script/src/main/java/cn/fd/ratziel/script/api/StorableScript.java +++ b/project/module-script/src/main/java/cn/fd/ratziel/script/api/StorableScript.java @@ -4,6 +4,7 @@ import org.jetbrains.annotations.Nullable; import javax.script.CompiledScript; +import javax.script.ScriptException; /** * StorableScript @@ -22,8 +23,14 @@ public interface StorableScript { CompiledScript getCompiled(); /** - * 设置编译后的脚本内容 + * 编译脚本 + * + * @param executor 脚本执行器 + * @return 脚本是否可编译 + * @throws ScriptException 编译过程中出现异常时抛出 */ - void setCompiled(@NotNull CompiledScript compiled); + default boolean compile(@NotNull ScriptExecutor executor) throws ScriptException { + return false; + } } diff --git a/project/module-script/src/main/java/cn/fd/ratziel/script/impl/SimpleScript.java b/project/module-script/src/main/java/cn/fd/ratziel/script/impl/SimpleScript.java index 5bea48cc..be8850de 100644 --- a/project/module-script/src/main/java/cn/fd/ratziel/script/impl/SimpleScript.java +++ b/project/module-script/src/main/java/cn/fd/ratziel/script/impl/SimpleScript.java @@ -16,41 +16,49 @@ */ public class SimpleScript implements EvaluableScript, StorableScript, ScriptContent { - public SimpleScript(@NotNull String content) { + public SimpleScript(@NotNull String content, @NotNull ScriptExecutor executor) { this.content = content; + this.executor = executor; } private final String content; + private final ScriptExecutor executor; private CompiledScript compiledScript = null; @Override - public @Nullable Object evaluate(@NotNull ScriptExecutor executor, @NotNull ScriptEnvironment environment) throws ScriptException { - // 若脚本没经过编译, 并且该脚本执行器可以编译此脚本 - if (compiledScript == null && executor instanceof Compilable) { - // 编译脚本 - CompiledScript compiled = ((Compilable) executor).compile(getContent()); - // 存储编译后的脚本 - setCompiled(compiled); - // 直接评估脚本 - return compiled.eval(environment.getBindings()); + public @Nullable Object evaluate(@NotNull ScriptEnvironment environment) throws ScriptException { + // 已存在编译过的脚本, 或者脚本可被编译(已通过compile方法编译) + if (compiledScript != null || compile(getExecutor())) { + // 直接用编译后的脚本评估 + return compiledScript.eval(environment.getBindings()); } else { // 通过执行器评估脚本 - return executor.evaluate(this, environment); + return getExecutor().evaluate(this, environment); } } + @Override + public boolean compile(@NotNull ScriptExecutor executor) throws ScriptException { + if (executor instanceof Compilable) { + // 编译脚本 + this.compiledScript = ((Compilable) executor).compile(getContent()); + return true; + } else return false; + } + @Override public @Nullable CompiledScript getCompiled() { return compiledScript; } + @Override - public void setCompiled(@NotNull CompiledScript compiled) { - this.compiledScript = compiled; + public @NotNull ScriptExecutor getExecutor() { + return executor; } @Override - public String getContent() { + public @NotNull String getContent() { return content; } diff --git a/project/module-script/src/main/java/cn/fd/ratziel/script/impl/SimpleScriptEnvironment.java b/project/module-script/src/main/java/cn/fd/ratziel/script/impl/SimpleScriptEnvironment.java index d450d087..37424b8a 100644 --- a/project/module-script/src/main/java/cn/fd/ratziel/script/impl/SimpleScriptEnvironment.java +++ b/project/module-script/src/main/java/cn/fd/ratziel/script/impl/SimpleScriptEnvironment.java @@ -1,7 +1,7 @@ package cn.fd.ratziel.script.impl; -import cn.fd.ratziel.function.argument.ArgumentContext; -import cn.fd.ratziel.function.argument.SimpleArgumentContext; +import cn.fd.ratziel.function.ArgumentContext; +import cn.fd.ratziel.function.SimpleArgumentContext; import cn.fd.ratziel.script.api.ScriptEnvironment; import org.jetbrains.annotations.NotNull; diff --git a/project/module-script/src/main/kotlin/cn/fd/ratziel/script/ScriptBlockBuilder.kt b/project/module-script/src/main/kotlin/cn/fd/ratziel/script/ScriptBlockBuilder.kt index 1501926f..8a1a49fc 100644 --- a/project/module-script/src/main/kotlin/cn/fd/ratziel/script/ScriptBlockBuilder.kt +++ b/project/module-script/src/main/kotlin/cn/fd/ratziel/script/ScriptBlockBuilder.kt @@ -1,9 +1,6 @@ package cn.fd.ratziel.script -import cn.fd.ratziel.script.api.EvaluableScript -import cn.fd.ratziel.script.api.ScriptContent -import cn.fd.ratziel.script.api.ScriptEnvironment -import cn.fd.ratziel.script.api.ScriptExecutor +import cn.fd.ratziel.script.api.* import cn.fd.ratziel.script.impl.SimpleScript @@ -15,12 +12,12 @@ import cn.fd.ratziel.script.impl.SimpleScript */ object ScriptBlockBuilder { - fun build(section: Any): ScriptBlock { + fun build(section: Any, executor: ScriptExecutor): ScriptBlock { when (section) { // BasicBlock - is String -> return BasicBlock(section) + is String -> return BasicBlock(section, executor) // ListBlock - is Iterable<*> -> return ListBlock(section.mapNotNull { l -> l?.let { build(it) } }) + is Iterable<*> -> return ListBlock(section.mapNotNull { l -> l?.let { build(it, executor) } }, executor) is Map<*, *> -> { // ConditionBlock val ifValue = section["if"] ?: section["condition"] @@ -28,9 +25,10 @@ object ScriptBlockBuilder { val thenValue = section["then"] val elseValue = section["else"] return ConditionBlock( - build(ifValue), - thenValue?.let { build(it) }, - elseValue?.let { build(it) } + build(ifValue, executor), + thenValue?.let { build(it, executor) }, + elseValue?.let { build(it, executor) }, + executor ) } else { // OverrideExecutorBlock @@ -39,34 +37,41 @@ object ScriptBlockBuilder { if (key.startsWith(MARK_TOGGLE)) { val type = ScriptTypes.matchOrThrow(key.drop(MARK_TOGGLE.length)) val value = e.value - if (value != null) return OverrideExecutorBlock(type.executor, build(value)) + if (value != null) return build(value, type.executor) } } } } // PrimitiveBlock - else -> return PrimitiveBlock(section) + else -> return PrimitiveBlock(section, executor) } - return PrimitiveBlock(null) + return PrimitiveBlock(null, executor) } const val MARK_TOGGLE = "\$" - interface ScriptBlock : EvaluableScript + abstract class ScriptBlock(private val exe: ScriptExecutor) : EvaluableScript { + override fun getExecutor() = exe + } + + class BasicBlock(val script: ScriptContent, executor: ScriptExecutor) : ScriptBlock(executor) { + constructor(content: String, executor: ScriptExecutor) : this(SimpleScript(content, executor), executor) - data class BasicBlock(val script: ScriptContent) : ScriptBlock { - constructor(content: String) : this(SimpleScript(content)) + init { + // 预编译 + if (script is StorableScript) script.compile(executor) + } - override fun evaluate(executor: ScriptExecutor, env: ScriptEnvironment): Any? = - if (script is EvaluableScript) script.evaluate(executor, env) else executor.evaluate(script, env) + override fun evaluate(enviornment: ScriptEnvironment): Any? = + if (script is EvaluableScript) script.evaluate(enviornment) else executor.evaluate(script, enviornment) } - data class PrimitiveBlock(val value: Any?) : ScriptBlock { - override fun evaluate(executor: ScriptExecutor, env: ScriptEnvironment) = value + class PrimitiveBlock(val value: Any?, executor: ScriptExecutor) : ScriptBlock(executor) { + override fun evaluate(enviornment: ScriptEnvironment) = value } - data class ListBlock(val list: Iterable) : ScriptBlock { - val handled = buildList { + class ListBlock(val array: Array, executor: ScriptExecutor) : ScriptBlock(executor) { + constructor(list: Iterable, executor: ScriptExecutor) : this(buildList { var combined = mutableListOf() fun combine() { if (combined.isEmpty()) return @@ -75,7 +80,7 @@ object ScriptBlockBuilder { // 清空 combined = mutableListOf() // 然后添加基础代码块 - add(BasicBlock(lined)) + add(BasicBlock(lined, executor)) } for (block in list) { if (block is BasicBlock) { @@ -89,12 +94,12 @@ object ScriptBlockBuilder { } // 尾处理: 检查合并一次 combine() - }.toTypedArray() + }.toTypedArray(), executor) - override fun evaluate(executor: ScriptExecutor, env: ScriptEnvironment): Any? { - val iterator = handled.iterator() + override fun evaluate(enviornment: ScriptEnvironment): Any? { + val iterator = array.iterator() while (iterator.hasNext()) { - val result = iterator.next().evaluate(executor, env) + val result = iterator.next().evaluate(enviornment) // 在没有下一个元素(最后一个脚本执行完后), 返回结果 if (!iterator.hasNext()) return result } @@ -102,18 +107,14 @@ object ScriptBlockBuilder { } } - data class OverrideExecutorBlock(val newExecutor: ScriptExecutor, val block: ScriptBlock) : ScriptBlock { - override fun evaluate(executor: ScriptExecutor, env: ScriptEnvironment): Any? = evaluate(env) - fun evaluate(env: ScriptEnvironment): Any? = block.evaluate(newExecutor, env) - } - - data class ConditionBlock( + class ConditionBlock( val ifBlock: ScriptBlock, val thenBlock: ScriptBlock?, - val elseBlock: ScriptBlock? - ) : ScriptBlock { - override fun evaluate(executor: ScriptExecutor, env: ScriptEnvironment): Any? { - return if (ifBlock.evaluate(executor, env) == true) thenBlock?.evaluate(executor, env) else elseBlock?.evaluate(executor, env) + val elseBlock: ScriptBlock?, + executor: ScriptExecutor + ) : ScriptBlock(executor) { + override fun evaluate(environment: ScriptEnvironment): Any? { + return if (ifBlock.evaluate(environment) == true) thenBlock?.evaluate(environment) else elseBlock?.evaluate(environment) } } diff --git a/project/module-script/src/main/kotlin/cn/fd/ratziel/script/ScriptManager.kt b/project/module-script/src/main/kotlin/cn/fd/ratziel/script/ScriptManager.kt new file mode 100644 index 00000000..75a119f9 --- /dev/null +++ b/project/module-script/src/main/kotlin/cn/fd/ratziel/script/ScriptManager.kt @@ -0,0 +1,16 @@ +package cn.fd.ratziel.script + +import cn.fd.ratziel.script.api.ScriptType + +/** + * ScriptManager + * + * @author TheFloodDragon + * @since 2024/7/16 11:30 + */ +object ScriptManager { + + var defaultScriptLanguage: ScriptType = ScriptTypes.KETHER + internal set + +} \ No newline at end of file diff --git a/project/module-script/src/main/kotlin/cn/fd/ratziel/script/ScriptTypes.kt b/project/module-script/src/main/kotlin/cn/fd/ratziel/script/ScriptTypes.kt index c1ae3e15..f099fd36 100644 --- a/project/module-script/src/main/kotlin/cn/fd/ratziel/script/ScriptTypes.kt +++ b/project/module-script/src/main/kotlin/cn/fd/ratziel/script/ScriptTypes.kt @@ -1,11 +1,13 @@ package cn.fd.ratziel.script +import cn.fd.ratziel.script.api.ScriptEnvironment import cn.fd.ratziel.script.api.ScriptExecutor import cn.fd.ratziel.script.api.ScriptType import cn.fd.ratziel.script.executors.JavaScriptExecutor import cn.fd.ratziel.script.executors.JexlExecutor import cn.fd.ratziel.script.executors.KetherExecutor import cn.fd.ratziel.script.executors.KotlinScriptExecutor +import java.util.concurrent.CopyOnWriteArrayList /** * ScriptTypes @@ -13,7 +15,20 @@ import cn.fd.ratziel.script.executors.KotlinScriptExecutor * @author TheFloodDragon * @since 2024/7/14 21:35 */ -enum class ScriptTypes(private val executor: ScriptExecutor, private vararg val names: String) : ScriptType { +enum class ScriptTypes( + /** + * 执行器 + */ + private val executor: ScriptExecutor, + /** + * 名称 + */ + private vararg val names: String, + /** + * [ScriptEnvironment.Applier] + */ + val appliers: MutableList = CopyOnWriteArrayList() +) : ScriptType { JAVASCRIPT(JavaScriptExecutor, "js", "JavaScript", "javascript", "java-script", "JS"), KETHER(KetherExecutor, "Kether", "kether", "ke", "ks"), diff --git a/project/module-script/src/main/kotlin/cn/fd/ratziel/script/internal/applier/BasicAppliers.kt b/project/module-script/src/main/kotlin/cn/fd/ratziel/script/internal/applier/BasicAppliers.kt new file mode 100644 index 00000000..6d995ffc --- /dev/null +++ b/project/module-script/src/main/kotlin/cn/fd/ratziel/script/internal/applier/BasicAppliers.kt @@ -0,0 +1,34 @@ +package cn.fd.ratziel.script.internal.applier + +import cn.fd.ratziel.script.ScriptTypes +import cn.fd.ratziel.script.api.ScriptEnvironment +import taboolib.common.platform.Awake +import taboolib.common.platform.ProxyCommandSender + +/** + * BasicAppliers + * + * @author TheFloodDragon + * @since 2024/7/16 12:21 + */ +@Awake +private object BasicAppliers { + + @Awake + fun register() { + ScriptTypes.KETHER.appliers.addAll(arrayOf( + fetch { + bindings["@Sender"] = it + } + )) + } + + inline fun fetch(noinline function: ScriptEnvironment.(T) -> Unit) = fetch(T::class.java, function) + + fun fetch(type: Class, function: ScriptEnvironment.(T) -> Unit) = + ScriptEnvironment.Applier { + val ins = it.context.popOrNull(type) ?: return@Applier + function(it, ins); + } + +} \ No newline at end of file diff --git a/project/module-script/src/main/kotlin/cn/fd/ratziel/script/internal/jsr223/KotlinJsr223DefaultScript.kt b/project/module-script/src/main/kotlin/cn/fd/ratziel/script/internal/jsr223/KotlinJsr223DefaultScript.kt index dac0c525..0a2d30ce 100644 --- a/project/module-script/src/main/kotlin/cn/fd/ratziel/script/internal/jsr223/KotlinJsr223DefaultScript.kt +++ b/project/module-script/src/main/kotlin/cn/fd/ratziel/script/internal/jsr223/KotlinJsr223DefaultScript.kt @@ -1,9 +1,9 @@ +@file:Suppress("unused") + package cn.fd.ratziel.script.internal.jsr223 import cn.fd.ratziel.script.kts.KotlinScriptConfiguration -import javax.script.Bindings import kotlin.script.experimental.annotations.KotlinScript -import kotlin.script.templates.standard.ScriptTemplateWithBindings /** * KotlinJsr223DefaultScript @@ -15,4 +15,4 @@ import kotlin.script.templates.standard.ScriptTemplateWithBindings compilationConfiguration = KotlinScriptConfiguration.Compilation::class, evaluationConfiguration = KotlinScriptConfiguration.Evaluation::class ) -abstract class KotlinJsr223DefaultScript(bindings: Bindings) : ScriptTemplateWithBindings(bindings) \ No newline at end of file +abstract class KotlinJsr223DefaultScript(val vars: Map) \ No newline at end of file diff --git a/project/runtime-bukkit/src/main/kotlin/cn/fd/ratziel/bukkit/element/action/ActionElement.kt b/project/runtime-bukkit/src/main/kotlin/cn/fd/ratziel/bukkit/element/action/ActionElement.kt index bf194b95..65cb890a 100644 --- a/project/runtime-bukkit/src/main/kotlin/cn/fd/ratziel/bukkit/element/action/ActionElement.kt +++ b/project/runtime-bukkit/src/main/kotlin/cn/fd/ratziel/bukkit/element/action/ActionElement.kt @@ -6,7 +6,7 @@ import cn.fd.ratziel.core.element.Element import cn.fd.ratziel.core.element.api.ElementHandler import cn.fd.ratziel.core.serialization.toBasic import cn.fd.ratziel.script.ScriptBlockBuilder -import cn.fd.ratziel.script.ScriptTypes +import cn.fd.ratziel.script.ScriptManager import cn.fd.ratziel.script.impl.SimpleScriptEnvironment import taboolib.common.LifeCycle @@ -25,9 +25,9 @@ object ActionElement : ElementHandler { override fun handle(element: Element) { element.property.let { json -> - val block = ScriptBlockBuilder.build(json.toBasic()) + val block = ScriptBlockBuilder.build(json.toBasic(), ScriptManager.defaultScriptLanguage.executor) println(block) - val result = block.evaluate(ScriptTypes.KETHER.executor, SimpleScriptEnvironment()) + val result = block.evaluate(SimpleScriptEnvironment()) println(result) } }