Skip to content

Commit

Permalink
Support for fixed sized arrays in models dojoengine#2785: Added redin…
Browse files Browse the repository at this point in the history
…g, writing and deleting of fixed arrays
  • Loading branch information
bengineer42 committed Dec 30, 2024
1 parent 1c3ff08 commit 15292f5
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 1 deletion.
2 changes: 1 addition & 1 deletion crates/dojo/core-cairo-test/Scarb.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ version = 1

[[package]]
name = "dojo"
version = "1.0.0-rc.0"
version = "1.0.9"
dependencies = [
"dojo_plugin",
]
Expand Down
2 changes: 2 additions & 0 deletions crates/dojo/core/src/meta/layout.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub enum Layout {
// And `Box` is not serializable. So using a Span, even if it's to have
// one element, does the trick.
Array: Span<Layout>,
FixedArray: Span<(Layout, u32)>,
ByteArray,
// there is one layout per variant.
// the `selector` field identifies the variant
Expand All @@ -30,6 +31,7 @@ pub impl LayoutCompareImpl of LayoutCompareTrait {
(Layout::Struct(_), Layout::Struct(_)) => true,
(Layout::Tuple(_), Layout::Tuple(_)) => true,
(Layout::Array(_), Layout::Array(_)) => true,
(Layout::FixedArray(_), Layout::FixedArray(_)) => true,
(Layout::ByteArray, Layout::ByteArray) => true,
(Layout::Enum(_), Layout::Enum(_)) => true,
_ => false
Expand Down
74 changes: 74 additions & 0 deletions crates/dojo/core/src/storage/layout.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ pub fn write_layout(
Layout::Fixed(layout) => { write_fixed_layout(model, key, values, ref offset, layout); },
Layout::Struct(layout) => { write_struct_layout(model, key, values, ref offset, layout); },
Layout::Array(layout) => { write_array_layout(model, key, values, ref offset, layout); },
Layout::FixedArray(layout) => {
write_fixed_array_layout(model, key, values, ref offset, layout);
},
Layout::Tuple(layout) => { write_tuple_layout(model, key, values, ref offset, layout); },
Layout::ByteArray => { write_byte_array_layout(model, key, values, ref offset); },
Layout::Enum(layout) => { write_enum_layout(model, key, values, ref offset, layout); }
Expand Down Expand Up @@ -81,6 +84,38 @@ pub fn write_array_layout(
};
}

/// Write array layout model record to the world storage.
///
/// # Arguments
/// * `model` - the model selector.
/// * `key` - the model record key.
/// * `values` - the model record values.
/// * `offset` - the start of model record values in the `values` parameter.
/// * `item_layout` - the model record layout (temporary a Span because of type recursion issue).
pub fn write_fixed_array_layout(
model: felt252,
key: felt252,
values: Span<felt252>,
ref offset: u32,
mut item_layout: Span<(Layout, u32)>
) {
let (item_layout, array_len): (Layout, u32) = *item_layout.pop_front().unwrap();
assert((values.len() - offset) >= array_len, 'Invalid values length');

// first, read array size which is the first felt252 from values
assert(array_len.into() <= database::MAX_ARRAY_LENGTH, 'invalid array length');

// then, write the array size
database::set(model, key, values, offset, [packing::PACKING_MAX_BITS].span());
offset += 1;

// and then, write array items
for i in 0
..array_len {
write_layout(model, combine_key(key, i.into()), values, ref offset, item_layout);
};
}

///
pub fn write_byte_array_layout(
model: felt252, key: felt252, values: Span<felt252>, ref offset: u32
Expand Down Expand Up @@ -212,6 +247,14 @@ pub fn delete_array_layout(model: felt252, key: felt252) {
database::delete(model, key, [packing::PACKING_MAX_BITS].span());
}

pub fn delete_fixed_array_layout(model: felt252, key: felt252, mut layout: Span<(Layout, u32)>) {
let (item_layout, array_len): (Layout, u32) = *layout.pop_front().unwrap();
database::delete(model, key, [packing::PACKING_MAX_BITS].span());
for i in 0..array_len {
delete_layout(model, combine_key(key, i.into()), item_layout);
}
}

///
pub fn delete_byte_array_layout(model: felt252, key: felt252) {
// The ByteArray internal structure is
Expand Down Expand Up @@ -241,6 +284,7 @@ pub fn delete_layout(model: felt252, key: felt252, layout: Layout) {
Layout::Fixed(layout) => { delete_fixed_layout(model, key, layout); },
Layout::Struct(layout) => { delete_struct_layout(model, key, layout); },
Layout::Array(_) => { delete_array_layout(model, key); },
Layout::FixedArray(layout) => { delete_fixed_array_layout(model, key, layout); },
Layout::Tuple(layout) => { delete_tuple_layout(model, key, layout); },
Layout::ByteArray => { delete_byte_array_layout(model, key); },
Layout::Enum(layout) => { delete_enum_layout(model, key, layout); }
Expand Down Expand Up @@ -323,6 +367,7 @@ pub fn read_layout(model: felt252, key: felt252, ref read_data: Array<felt252>,
Layout::Fixed(layout) => read_fixed_layout(model, key, ref read_data, layout),
Layout::Struct(layout) => read_struct_layout(model, key, ref read_data, layout),
Layout::Array(layout) => read_array_layout(model, key, ref read_data, layout),
Layout::FixedArray(layout) => read_fixed_array_layout(model, key, ref read_data, layout),
Layout::Tuple(layout) => read_tuple_layout(model, key, ref read_data, layout),
Layout::ByteArray => read_byte_array_layout(model, key, ref read_data),
Layout::Enum(layout) => read_enum_layout(model, key, ref read_data, layout),
Expand Down Expand Up @@ -378,6 +423,35 @@ pub fn read_array_layout(
};
}

pub fn read_fixed_array_layout(
model: felt252, key: felt252, ref read_data: Array<felt252>, mut layout: Span<(Layout, u32)>
) {
// read number of array items
let (item_layout, array_len): (Layout, u32) = *layout.pop_front().unwrap();
let res = database::get(model, key, [packing::PACKING_MAX_BITS].span());
assert(res.len() == 1, 'internal database error');

assert(array_len.into() <= database::MAX_ARRAY_LENGTH, 'invalid array length');

read_data.append(array_len.into());

let mut i = 0;
loop {
if i >= array_len {
break;
}

let field_key = combine_key(key, i.into());
read_layout(model, field_key, ref read_data, item_layout);

i += 1;
};
for i in 0
..array_len {
read_layout(model, combine_key(key, i.into()), ref read_data, item_layout);
};
}

///
pub fn read_byte_array_layout(model: felt252, key: felt252, ref read_data: Array<felt252>) {
// The ByteArray internal structure is
Expand Down

0 comments on commit 15292f5

Please sign in to comment.