Structs of Arrays is a way of rearranging the layout of the data fields of a struct. Specifically, Structs of Arrays (SoA) is a data layout separating elements of a record into one parallel array per field. Take the following example:
// this is just a normal struct, no SOA
Vec3 :: struct {
x: float;
y: float;
z: float;
}
// this is a SOA Vec3 struct
SOA_Vec3 :: struct {
x: [100] float;
y: [100] float;
z: [100] float;
}
Using a combination of #insert
directives, metaprogramming, and generating code at compile time, we can generalize the concept of SOA to any structs using the following:
Vec3 :: struct {
x: float;
y: float;
z: float;
}
Person :: struct {
age: int;
is_cool: bool;
}
SOA :: struct(T: Type, count: int) {
#insert -> string {
t_info := type_info(T);
builder: String_Builder;
defer free_buffers(*builder);
for fields: t_info.members {
print_to_builder(*builder, " %1: [%2] type_of(T.%1);\n", fields.name, count);
}
result := builder_to_string(*builder);
return result;
}
}
// create an soa_vec3
soa_vec: SOA(Vec3, 10);
for i: 0..soa_vec.count-1 {
print("soa_vec.x[i]=%, soa_vec.y[i]=%, soa_vec.z[i]=%\n", soa_vec.x[i], soa_vec.y[i], soa_vec.z[i]);
}
// create an soa_person
soa_person: SOA(Person, 10);
for i: 0..soa_person.count-1 {
print("soa_person.age[i]=%, soa_person.is_cool[i]=%\n", soa_person.age[i], soa_person.is_cool[i]);
}