Documentation Index
Fetch the complete documentation index at: https://fluxon.tabooproject.org/llms.txt
Use this file to discover all available pages before exploring further.
支持不同 ClassLoader 中的 Fluxon 运行时实例之间共享普通函数和扩展函数。典型场景:Bukkit 服务器中多个插件间共享脚本函数。
使用 System.getProperties() 作为 JVM 全局单例锚点,存储 MethodHandle + 元数据的版本化 Object[] 元组。所有元素类型均来自 java.base,天然跨 ClassLoader 可见。
设置共享身份
每个 Fluxon 运行时实例在导出前需要设置身份标识,用于区分函数来源:
FluxonRuntime runtime = FluxonRuntime.getInstance();
runtime.setSharingIdentity("MyPlugin"); // 通常用 plugin.getName()
导出函数
方式 1:直接导出 MethodHandle
MethodHandle mh = MethodHandles.lookup().findStatic(
MyClass.class, "heal",
MethodType.methodType(int.class, int.class));
runtime.exportFunction("heal", mh);
方式 2:导出已注册的函数
runtime.registerFunction("greet", signature, ctx -> {
ctx.setReturnRef("Hello, " + ctx.getRef(0) + "!");
});
runtime.exportRegisteredFunction("greet");
方式 3:ExtensionBuilder 一步注册 + 导出
runtime.registerExtension(Player.class)
.sharedFunction("heal", signature, ctx -> {
// 实现
})
.sharedAsyncFunction("save", signature, ctx -> {
// 异步实现
})
.sharedSyncFunction("teleport", signature, ctx -> {
// 主线程实现
});
方式 4:@Export 注解自动导出
public class PlayerAPI {
@Export(shared = true)
public static int heal(int amount) {
return amount * 2;
}
}
当 ExportRegistry.registerClass() 扫描到 shared = true 的方法时,会自动注册到全局共享注册表(前提是 sharingIdentity 已设置)。
导入函数
// 导入指定插件的指定函数
runtime.importSharedFunction("OtherPlugin", "heal");
// 导入指定插件的所有共享函数
runtime.importAllSharedFunctions("OtherPlugin");
// 导入所有插件的所有共享函数
runtime.importAllSharedFunctions();
导入后的函数注册为本地 NativeFunction,可通过 Fluxon.eval() 或 Environment 正常调用。
显式查找(不自动注册)
Function f = env.getSharedFunction("OtherPlugin", "heal");
返回适配后的 NativeFunction 实例,但不注册到本地运行时。适用于一次性调用或条件导入。
插件卸载
在插件 onDisable 中调用,移除所有已导出的共享函数:
版本安全
共享条目使用版本化协议(当前 v1)。当遇到更高版本的条目时:
- 不会在导入时崩溃 — 返回一个 stub 函数
- 调用时抛出
UnsupportedOperationException,包含版本差异的详细提示
- 低版本读取高版本条目时,安全忽略末尾多余字段
版本演进规则
entry[0] 永远是版本号,位置不变
- 新版本只能在
Object[] 末尾追加字段,不能修改已有字段
- 所有元素类型必须来自
java.base(避免 ClassLoader 隔离问题)
性能特征
跨 ClassLoader 调用通过 MethodHandle.invokeWithArguments() + Object[] 装箱,单次调用约 15-30ns 开销。适用于跨插件 API 调用(冷路径)。
对于热路径函数,建议使用源码级共享(本地 parse/compile)。
完整生命周期示例
// Plugin A: onEnable
FluxonRuntime runtime = FluxonRuntime.getInstance();
runtime.setSharingIdentity("QuestPlugin");
// 注册并导出
runtime.registerFunction("check_quest", signature, ctx -> { ... });
runtime.exportRegisteredFunction("check_quest");
runtime.registerExtension(Player.class)
.sharedFunction("get_quest_progress", signature, ctx -> { ... });
// Plugin B: onEnable
FluxonRuntime runtime = FluxonRuntime.getInstance();
// 导入 QuestPlugin 的所有共享函数
runtime.importAllSharedFunctions("QuestPlugin");
// 现在可以在脚本中使用
Fluxon.eval("check_quest('main_story')");
// Plugin A: onDisable
runtime.unexportAll(); // 清理所有已导出的函数
相关链接