#matrix #ecs #编译时 #游戏状态 #异构 #连续内存 #实体

h_mat

一个类型安全的异构矩阵类型

5个版本

0.1.14 2023年7月9日
0.1.13 2023年7月8日

#526 in 游戏开发

每月 22 次下载

Unlicense

39KB
939

h_mat

一个类型安全且便捷的异构矩阵类型,用于Rust。旨在用于具有编译时类型检查的ECS。

在本文档中,HMat 表示 一个包含任意 Option 类型 Vec 的列表,例如,具有三行的 HMat 将具有以下类型: Vec<Option<T1>>Vec<Option<T2>>Vec<Option<T3>> 其中 T1 != T2 != T3。在ECS设置中,HMat 将表示游戏状态,行将存储连续内存中的组件实例,而列将对应实体。

基本用法

创建和行访问

使用 extend 构建矩阵,并使用 get_row_ref/mut 方法(带有类型注解)来访问单个行。

// Creating a HMat with i32, f32, usize rows.
let mat: HMat<i32, HMat<f32, HMat<usize, ()>>> = 
    HMat::new::<usize>().extend::<f32>().extend::<i32>();
// Access the rows explicitly as a reference.
let usize_row_ref: &Row<usize> = mat.get_row_ref();
let i32_row_ref: &Row<i32> = mat.get_row_ref();
// ... or as a mutable reference.
let mut mat = mat;
let i32_row_mut: &mut Row<i32> = mat.get_row_mut();

列访问

可以通过 get_col_ref/muttake_col 方法访问特定列。注意,以下列类型是明确编写的,以便于参考。一般来说,列类型可以直接从矩阵的类型推断出来。

let mat = HMat::new::<usize>().extend::<f32>().extend::<i32>();
// Access a single column as a reference.
let col_ref: HCol<&i32, HCol<&f32, HCol<&usize, ()>>> = mat.get_col_ref(0);
// ... or as a mutable reference...
let mut mat = mat;
let col_mut: HCol<&mut i32, HCol<&mut f32, HCol<&mut usize, ()>>> = mat.get_col_mut(0);
// ... or directly move it out of the matrix.
let col: HCol<i32, HCol<f32, HCol<usize, ()>>> = mat.take_col(0);
// Then we can place it back to a different position.
mat.place_col(1, col);

切片

我们可以调用 HMatRef::slice 来提取一个引用矩阵,该矩阵包含原始矩阵的子集行,即一个 HMatRef,其字段由类型注解指示,无论是绑定还是参数。

let mat = HMat::new::<usize>().extend::<f32>().extend::<i32>();
// Slice as a heterogenous matrix of f32, and i32 rows (type annotations are necessary!)
let mat_ref: HMatRef<f32, HMatRef<i32, ()>> = HMatRef::slice(&mat);
// ... also works as an argument!
fn receive_sliced(_: HMatRef<f32, HMatRef<i32, ()>>) {}
receive_sliced(HMatRef::slice(&mat));
// Of course, we can access the rows/cols of the original matrix.
let i32_row_ref: &Row<i32> = mat_ref.get_row_ref();
let first_col_ref = mat_ref.get_col_ref(0);

写入

除了调用返回底层对象可变引用的方法外,还可以收集将来要应用的所有修改。这很有用,因为在持有指向该矩阵的 HMatRef 指针时,无法修改原始矩阵。

let mut mat = h_mat::HMat::new::<usize>().extend::<f32>().extend::<i32>();
let ref_mat: HMatRef<f32, HMatRef<i32, ()>> = HMatRef::slice(&mat);
// Create a new writer from the `HMatRef`.
let mut writer = ref_mat.new_writer();
// Set the column 0 of the i32 row.
writer.get_writer().set_col(0, 3);
// Update the column 0 of the i32 row.
writer.get_writer().update_col(0, |val: &mut i32| {
    *val += 1;
});
// Apply the modifications at once. This is the only place where we borrow `mat` by mutable reference.
mat.apply(writer);

依赖项

~0.8–1.4MB
~32K SLoC