Skip to content

Commit

Permalink
feat(dojo-core): add support for making multiple model pointers (#2940)
Browse files Browse the repository at this point in the history
feat(model): add support for multiple model pointers and serialization methods

Co-authored-by: glihm <[email protected]>
  • Loading branch information
bengineer42 and glihm authored Jan 24, 2025
1 parent 01111f4 commit 94e6e16
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 5 deletions.
29 changes: 27 additions & 2 deletions crates/dojo/core-cairo-test/src/tests/model/model.cairo
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use dojo::model::{Model, ModelValue, ModelStorage, ModelValueStorage};
use dojo::model::{Model, ModelValue, ModelStorage, ModelValueStorage, ModelPtr};
use dojo::world::WorldStorage;
use dojo_cairo_test::{spawn_test_world, NamespaceDef, TestResource};

#[derive(Copy, Drop, Serde, Debug)]
#[derive(Copy, Drop, Serde, Debug, PartialEq)]
#[dojo::model]
struct Foo {
#[key]
Expand Down Expand Up @@ -194,3 +194,28 @@ fn test_model_ptr_from_entity_id() {
let v1 = world.read_member(ptr, selector!("v1"));
assert!(foo.v1 == v1);
}

#[test]
fn test_ptr_from() {
let foo = Foo { k1: 1, k2: 2, v1: 3, v2: 4 };
let ptr_a = ModelPtr::<Foo> { id: foo.entity_id() };
let ptr_b = Model::<Foo>::ptr_from_keys(foo.keys());
let ptr_c = Model::<Foo>::ptr_from_serialized_keys([foo.k1.into(), foo.k2].span());
let ptr_d = Model::<Foo>::ptr_from_id(foo.entity_id());
assert!(ptr_a == ptr_b && ptr_a == ptr_c && ptr_a == ptr_d);
}

fn test_ptrs_from() {
let foo = Foo { k1: 1, k2: 2, v1: 3, v2: 4 };
let foo2 = Foo { k1: 3, k2: 4, v1: 5, v2: 6 };
let ptrs_a = [ModelPtr::<Foo> { id: foo.entity_id() }, ModelPtr::<Foo> { id: foo2.entity_id() }]
.span();
let ptrs_b = Model::<Foo>::ptrs_from_keys([foo.keys(), foo2.keys()].span());
let ptrs_c = Model::<
Foo,
>::ptrs_from_serialized_keys(
[[foo.k1.into(), foo.k2].span(), [foo2.k1.into(), foo2.k2].span()].span(),
);
let ptrs_d = Model::<Foo>::ptrs_from_ids([foo.entity_id(), foo2.entity_id()].span());
assert!(ptrs_a == ptrs_b && ptrs_a == ptrs_c && ptrs_a == ptrs_d);
}
36 changes: 33 additions & 3 deletions crates/dojo/core/src/model/model.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,23 @@ pub trait Model<M> {
fn definition() -> ModelDef;
/// Returns the selector of the model computed for the given namespace hash.
fn selector(namespace_hash: felt252) -> felt252;
/// Returns the pointer to the model from the key.
fn ptr_from_keys<K, +Serde<K>, +Drop<K>>(keys: K) -> ModelPtr<M>;
/// Returns the pointer to the model from the keys.
fn ptr_from_keys<K, +Serde<K>, +Drop<K>>(keys: K) -> ModelPtr<M>;
/// Returns the pointer to the model from the serialised keys.
fn ptr_from_serialized_keys(keys: Span<felt252>) -> ModelPtr<M>;
/// Returns the pointer to the model from the entity id.
fn ptr_from_id(entity_id: felt252) -> ModelPtr<M>;
/// Returns the pointers to models from the keys.
fn ptrs_from_keys<K, +Serde<K>, +Drop<K>>(keys: Span<K>) -> Span<ModelPtr<M>>;
/// Returns the pointers to models from the serialised keys.
fn ptrs_from_serialized_keys(keys: Span<Span<felt252>>) -> Span<ModelPtr<M>>;
/// Returns the pointers to models from the entity ids.
fn ptrs_from_ids(entity_ids: Span<felt252>) -> Span<ModelPtr<M>>;
/// Returns the ptr of the model.
fn ptr(self: @M) -> ModelPtr<M>;
}

pub impl ModelImpl<M, +ModelParser<M>, +ModelDefinition<M>, +Serde<M>> of Model<M> {
pub impl ModelImpl<M, +ModelParser<M>, +ModelDefinition<M>, +Serde<M>, +Drop<M>> of Model<M> {
fn keys<K, +KeyParser<M, K>>(self: @M) -> K {
KeyParser::<M, K>::parse_key(self)
}
Expand Down Expand Up @@ -147,6 +153,30 @@ pub impl ModelImpl<M, +ModelParser<M>, +ModelDefinition<M>, +Serde<M>> of Model<
ModelPtr::<M> { id: entity_id }
}

fn ptrs_from_keys<K, +Serde<K>, +Drop<K>>(keys: Span<K>) -> Span<ModelPtr<M>> {
let mut ptrs = ArrayTrait::<ModelPtr<M>>::new();
for key in keys {
ptrs.append(ModelPtr { id: entity_id_from_keys(key) });
};
ptrs.span()
}

fn ptrs_from_serialized_keys(keys: Span<Span<felt252>>) -> Span<ModelPtr<M>> {
let mut ptrs = ArrayTrait::<ModelPtr<M>>::new();
for key in keys {
ptrs.append(Self::ptr_from_serialized_keys(*key));
};
ptrs.span()
}

fn ptrs_from_ids(entity_ids: Span<felt252>) -> Span<ModelPtr<M>> {
let mut ptrs = ArrayTrait::<ModelPtr<M>>::new();
for entity_id in entity_ids {
ptrs.append(Self::ptr_from_id(*entity_id));
};
ptrs.span()
}

fn ptr(self: @M) -> ModelPtr<M> {
ModelPtr::<M> { id: self.entity_id() }
}
Expand Down

0 comments on commit 94e6e16

Please sign in to comment.