原生模拟核心(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。

相关条目