原生模拟核心(Rust + JNI)
pV=nRT 的气体运算是原生代码做的,不在 JVM 里。仓库内含一个独立的 Rust crate gas-sim/,通过 JNI 被 Java 侧调用。
加载方式
NativeGasSimulator.init()(pvnrt/rust/NativeGasSimulator.java:39-44)在 preInit 被调用(CommonProxy.preInit),用 System.load() 加载动态库。
🚨 该路径是硬编码的开发机相对路径:
System.load(Paths.get("..", "..", "gas-sim", "target", "release", "libgas_sim.so")它假定当前工作目录是仓库内某个子目录(通常
src/main/java/...或run/),并要求gas-sim已用cargo build --release编出libgas_sim.so。在任何正常安装环境下这行都会抛UnsatisfiedLinkError,且.so并未随 jar 打包(src/main/resources下无 native 库)。详见 源码缺陷。
Java ↔ Rust 接口
Java 侧的 NativeGasSimulator 通过 native 方法与 Rust 的 #[jni_export] 函数配对。Rust 侧导出集中在 gas-sim/src/jni.rs:
| Java | Rust 导出 |
|---|---|
getVoxelStatus(x,y,z) |
get_voxel_status |
getVoxelContents(x,y,z) |
get_voxel_contents |
addGas(...) |
add_gas |
addEBS(x,y,z) |
add_ebs |
patchEBS(...) |
patch_ebs |
saveEBS(...) |
save_ebs |
零拷贝缓冲区
Java 侧的 pvnrt.rust 包是一组 AutoCloseable 的 direct ByteBuffer 包装,用于避免跨语言拷贝:
| 类 | 作用 |
|---|---|
GasDataBuffer |
整张气体注册表(ID、摩尔质量、比热)打包成 direct buffer |
GasStackBuffer |
单个 GasList 打包成 direct buffer |
VoxelPatchBuffer |
待更新体素的 patch 队列 |
Voxel / VoxelLike |
体素位打包与掩码常量 |
NativeGasSimulator 构造时把 GasDataBuffer.fromGasRegistry() 和 GasStackBuffer.fromGasList(atmosphere) 各自 .toDirectBuffer() 后交给 init(),Rust 侧直接以指针读取。
生命周期
GasManager 构造时 new NativeGasSimulator(...) 创建守护进程句柄(pvnrt/core/world/GasManager.java:28-30),并实现 AutoCloseable,close() 调用原生 free(daemon)。
⚠️ 调试用的 ebs_patch_dump.bin 落盘代码在构造器与 close() 中整段被注释掉,因此 out 字段恒为 null(NativeGasSimulator.java:28-35, 46-51)——即该类目前不产出任何调试文件。
依赖
Rust crate 有两组构建目标:benches/(my_benchmark.rs、tick_ebses.rs)与 src/bin/tick_ebses.rs(独立 tick 压测程序)。核心模块为 gas.rs、sparse_set.rs、array_3d.rs、simple_sparse_set.rs、lib.rs。