> ## 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 函数共享

> 在不同 ClassLoader 的 Fluxon 运行时之间共享函数

支持不同 ClassLoader 中的 Fluxon 运行时实例之间共享普通函数和扩展函数。典型场景：Bukkit 服务器中多个插件间共享脚本函数。

## 原理

使用 `System.getProperties()` 作为 JVM 全局单例锚点，存储 `MethodHandle` + 元数据的版本化 `Object[]` 元组。所有元素类型均来自 `java.base`，天然跨 ClassLoader 可见。

<img src="https://mintcdn.com/taboolib/dujTvJvuvR8PNOrQ/image/sfr.png?fit=max&auto=format&n=dujTvJvuvR8PNOrQ&q=85&s=23e43d97e21c8e2d2b611b4809666f9c" alt="跨 ClassLoader 函数共享架构" width="7168" height="1732" data-path="image/sfr.png" />

## 设置共享身份

每个 Fluxon 运行时实例在导出前需要设置身份标识，用于区分函数来源：

```java theme={null}
FluxonRuntime runtime = FluxonRuntime.getInstance();
runtime.setSharingIdentity("MyPlugin");  // 通常用 plugin.getName()
```

## 导出函数

### 方式 1：直接导出 MethodHandle

```java theme={null}
MethodHandle mh = MethodHandles.lookup().findStatic(
    MyClass.class, "heal",
    MethodType.methodType(int.class, int.class));
runtime.exportFunction("heal", mh);
```

### 方式 2：导出已注册的函数

```java theme={null}
runtime.registerFunction("greet", signature, ctx -> {
    ctx.setReturnRef("Hello, " + ctx.getRef(0) + "!");
});
runtime.exportRegisteredFunction("greet");
```

### 方式 3：ExtensionBuilder 一步注册 + 导出

```java theme={null}
runtime.registerExtension(Player.class)
    .sharedFunction("heal", signature, ctx -> {
        // 实现
    })
    .sharedAsyncFunction("save", signature, ctx -> {
        // 异步实现
    })
    .sharedSyncFunction("teleport", signature, ctx -> {
        // 主线程实现
    });
```

### 方式 4：@Export 注解自动导出

```java theme={null}
public class PlayerAPI {
    @Export(shared = true)
    public static int heal(int amount) {
        return amount * 2;
    }
}
```

当 `ExportRegistry.registerClass()` 扫描到 `shared = true` 的方法时，会自动注册到全局共享注册表（前提是 `sharingIdentity` 已设置）。

## 导入函数

```java theme={null}
// 导入指定插件的指定函数
runtime.importSharedFunction("OtherPlugin", "heal");

// 导入指定插件的所有共享函数
runtime.importAllSharedFunctions("OtherPlugin");

// 导入所有插件的所有共享函数
runtime.importAllSharedFunctions();
```

导入后的函数注册为本地 `NativeFunction`，可通过 `Fluxon.eval()` 或 `Environment` 正常调用。

### 显式查找（不自动注册）

```java theme={null}
Function f = env.getSharedFunction("OtherPlugin", "heal");
```

返回适配后的 `NativeFunction` 实例，但不注册到本地运行时。适用于一次性调用或条件导入。

## 插件卸载

在插件 `onDisable` 中调用，移除所有已导出的共享函数：

```java theme={null}
runtime.unexportAll();
```

## 版本安全

共享条目使用版本化协议（当前 v1）。当遇到更高版本的条目时：

* **不会在导入时崩溃** — 返回一个 stub 函数
* **调用时抛出 `UnsupportedOperationException`**，包含版本差异的详细提示
* 低版本读取高版本条目时，安全忽略末尾多余字段

### 版本演进规则

1. `entry[0]` 永远是版本号，位置不变
2. 新版本只能在 `Object[]` 末尾追加字段，不能修改已有字段
3. 所有元素类型必须来自 `java.base`（避免 ClassLoader 隔离问题）

## 性能特征

跨 ClassLoader 调用通过 `MethodHandle.invokeWithArguments()` + `Object[]` 装箱，单次调用约 15-30ns 开销。适用于跨插件 API 调用（冷路径）。

对于热路径函数，建议使用源码级共享（本地 parse/compile）。

## 完整生命周期示例

```java theme={null}
// 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();  // 清理所有已导出的函数
```

## 相关链接

* [运行时注册 API](/developer/runtime-registry)
* [扩展函数 API](/developer/extension-api)
* [@Export 与桥接](/developer/export-bridge)
