From fdd32ceb19b4d8ff312fc5b33e9950a608d4f571 Mon Sep 17 00:00:00 2001 From: "remy.baranx@gmail.com" Date: Tue, 9 Jul 2024 09:27:45 +0200 Subject: [PATCH] wip --- ._target | Bin 0 -> 4096 bytes crates/dojo-core/src/model.cairo | 25 +- crates/dojo-core/src/resource_metadata.cairo | 67 +-- crates/dojo-core/src/utils.cairo | 30 ++ crates/dojo-core/src/world.cairo | 386 +++++------------- crates/dojo-lang/src/inline_macros/delete.rs | 2 +- crates/dojo-lang/src/inline_macros/get.rs | 4 +- crates/dojo-lang/src/inline_macros/set.rs | 2 +- crates/dojo-lang/src/model.rs | 135 +++--- examples/spawn-and-move/._target | Bin 0 -> 4096 bytes .../manifests/dev/base/abis/dojo-world.json | 220 ++-------- .../dojo_examples-actions-40b6994c.toml | 4 +- .../dojo_examples-mock_token-31599eb2.toml | 4 +- .../manifests/dev/base/dojo-world.toml | 4 +- .../dev/deployment/abis/dojo-world.json | 220 ++-------- .../manifests/dev/deployment/manifest.json | 242 ++--------- .../manifests/dev/deployment/manifest.toml | 22 +- 17 files changed, 362 insertions(+), 1005 deletions(-) create mode 100644 ._target create mode 100644 examples/spawn-and-move/._target diff --git a/._target b/._target new file mode 100644 index 0000000000000000000000000000000000000000..dc27ea21b83aa811079476f17dfcb4aab9d7105e GIT binary patch literal 4096 zcmeH~y$ZrW498PJ)J1f0D&?L)ilZRnC@6wY*0{y@t)gaym7NXuLx3(`Dd hVWKcmVVZC$PfTK>0kICV0_;Hy2u2ps%{hBJWBuo literal 0 HcmV?d00001 diff --git a/crates/dojo-core/src/model.cairo b/crates/dojo-core/src/model.cairo index bb536db3f4..e5250576a5 100644 --- a/crates/dojo-core/src/model.cairo +++ b/crates/dojo-core/src/model.cairo @@ -1,4 +1,4 @@ -use dojo::world::IWorldDispatcher; +use dojo::world::{IWorldDispatcher, ModelIndex, ModelValue}; use starknet::SyscallResult; /// Trait that is implemented at Cairo level for each struct that is a model. @@ -11,34 +11,23 @@ trait ModelValues { } trait Model { - fn entity( - world: IWorldDispatcher, keys: Span, layout: dojo::database::introspect::Layout - ) -> T; - - fn set_entity( - world: IWorldDispatcher, - keys: Span, - values: Span, - layout: dojo::database::introspect::Layout - ); - - fn delete_entity( - world: IWorldDispatcher, keys: Span, layout: dojo::database::introspect::Layout - ); + fn entity(world: IWorldDispatcher, keys: Span) -> T; + // Note: `get` is implemented with a generated trait because it takes + // the list of model keys as separated parameters. + fn set(self: @T, world: IWorldDispatcher); + fn delete(self: @T, world: IWorldDispatcher); fn entity_member( world: IWorldDispatcher, keys: Span, member_id: felt252, - layout: dojo::database::introspect::Layout ) -> Span; fn set_entity_member( + self: @T, world: IWorldDispatcher, - keys: Span, member_id: felt252, values: Span, - layout: dojo::database::introspect::Layout ); /// Returns the name of the model as it was written in Cairo code. diff --git a/crates/dojo-core/src/resource_metadata.cairo b/crates/dojo-core/src/resource_metadata.cairo index a730fd2d31..f35454f63d 100644 --- a/crates/dojo-core/src/resource_metadata.cairo +++ b/crates/dojo-core/src/resource_metadata.cairo @@ -3,8 +3,9 @@ //! Manually expand to ensure that dojo-core //! does not depend on dojo plugin to be built. //! -use dojo::world::{IWorldDispatcherTrait}; +use dojo::world::{IWorldDispatcherTrait, ModelIndex}; use dojo::model::Model; +use dojo::utils; fn initial_address() -> starknet::ContractAddress { starknet::contract_address_const::<0>() @@ -26,10 +27,9 @@ struct ResourceMetadata { impl ResourceMetadataModel of dojo::model::Model { fn entity( world: dojo::world::IWorldDispatcher, - keys: Span, - layout: dojo::database::introspect::Layout + keys: Span ) -> ResourceMetadata { - let values = world.entity(Self::selector(), keys, layout); + let values = world.entity(Self::selector(), ModelIndex::Keys(keys), Self::layout()); let mut serialized = core::array::ArrayTrait::new(); core::array::serialize_array_helper(keys, ref serialized); core::array::serialize_array_helper(values, ref serialized); @@ -45,46 +45,61 @@ impl ResourceMetadataModel of dojo::model::Model { core::option::OptionTrait::::unwrap(entity) } - fn set_entity( + fn set( + self: @ResourceMetadata, world: dojo::world::IWorldDispatcher, - keys: Span, - values: Span, - layout: dojo::database::introspect::Layout ) { dojo::world::IWorldDispatcherTrait::set_entity( - world, Self::selector(), keys, values, layout + world, Self::selector(), ModelIndex::Keys(self.keys()), self.values(), Self::layout() ); } - fn delete_entity( + fn delete( + self: @ResourceMetadata, world: dojo::world::IWorldDispatcher, - keys: Span, - layout: dojo::database::introspect::Layout ) { - dojo::world::IWorldDispatcherTrait::delete_entity(world, Self::selector(), keys, layout); + world.delete_entity( + Self::selector(), + ModelIndex::Keys(self.keys()), + Self::layout() + ); } fn entity_member( world: dojo::world::IWorldDispatcher, keys: Span, - member_id: felt252, - layout: dojo::database::introspect::Layout + member_id: felt252 ) -> Span { - dojo::world::IWorldDispatcherTrait::entity_member( - world, Self::selector(), keys, member_id, layout - ) + match utils::find_model_field_layout(Self::layout(), member_id) { + Option::Some(field_layout) => { + let entity_id = utils::entity_id_from_keys(keys); + world.entity( + Self::selector(), + ModelIndex::MemberId((entity_id, member_id)), + field_layout + ) + }, + Option::None => panic_with_felt252('bad member id') + } } fn set_entity_member( + self: @ResourceMetadata, world: dojo::world::IWorldDispatcher, - keys: Span, member_id: felt252, - values: Span, - layout: dojo::database::introspect::Layout + values: Span ) { - dojo::world::IWorldDispatcherTrait::set_entity_member( - world, Self::selector(), keys, member_id, values, layout - ); + match utils::find_model_field_layout(Self::layout(), member_id) { + Option::Some(field_layout) => { + world.set_entity( + Self::selector(), + ModelIndex::MemberId((self.entity_id(), member_id)), + values, + field_layout + ) + }, + Option::None => panic_with_felt252('bad member id') + } } #[inline(always)] @@ -116,11 +131,11 @@ impl ResourceMetadataModel of dojo::model::Model { } fn name_hash() -> felt252 { - dojo::utils::hash(@Self::name()) + utils::hash(@Self::name()) } fn namespace_hash() -> felt252 { - dojo::utils::hash(@Self::namespace()) + utils::hash(@Self::namespace()) } #[inline(always)] diff --git a/crates/dojo-core/src/utils.cairo b/crates/dojo-core/src/utils.cairo index 80e318194b..70b772c7b9 100644 --- a/crates/dojo-core/src/utils.cairo +++ b/crates/dojo-core/src/utils.cairo @@ -17,3 +17,33 @@ fn hash(data: @ByteArray) -> felt252 { fn entity_id_from_keys(keys: Span) -> felt252 { poseidon::poseidon_hash_span(keys) } + +/// TODO +fn find_model_field_layout( + model_layout: dojo::database::introspect::Layout, + member_id: felt252 +) -> Option { + match model_layout { + dojo::database::introspect::Layout::Struct(struct_layout) => { + let mut i = 0; + let layout = loop { + if i >= struct_layout.len() { + break Option::None; + } + + let field_layout = *struct_layout.at(i); + if field_layout.selector == member_id { + break Option::Some(field_layout.layout); + } + i += 1; + }; + + layout + }, + _ => { + // should never happen as model layouts are always struct layouts. + panic_with_felt252('Unexpected model layout'); + Option::None + } + } +} \ No newline at end of file diff --git a/crates/dojo-core/src/world.cairo b/crates/dojo-core/src/world.cairo index cc97ad2b85..74c7c40fca 100644 --- a/crates/dojo-core/src/world.cairo +++ b/crates/dojo-core/src/world.cairo @@ -3,6 +3,21 @@ use traits::{Into, TryInto}; use option::OptionTrait; use dojo::resource_metadata::ResourceMetadata; +#[derive(Copy, Drop, Serde, Debug, PartialEq)] +enum ModelIndex { + Keys: Span, + Id: felt252, + // (entity_id, member_id) + MemberId: (felt252, felt252) +} + +#[derive(Copy, Drop, Serde, Debug, PartialEq)] +enum ModelValue { + Full: Span, + // (selector, serialized value) + Member: (felt252, Span), +} + #[starknet::interface] trait IWorld { fn metadata(self: @T, resource_id: felt252) -> ResourceMetadata; @@ -16,67 +31,24 @@ trait IWorld { fn upgrade_contract(ref self: T, address: ContractAddress, class_hash: ClassHash) -> ClassHash; fn uuid(ref self: T) -> usize; fn emit(self: @T, keys: Array, values: Span); + fn entity( - self: @T, model: felt252, keys: Span, layout: dojo::database::introspect::Layout - ) -> Span; - fn entity_by_id( - self: @T, model_id: felt252, entity_id: felt252, layout: dojo::database::introspect::Layout + self: @T, + model_selector: felt252, + index: ModelIndex, + layout: dojo::database::introspect::Layout ) -> Span; fn set_entity( ref self: T, - model: felt252, - keys: Span, - values: Span, - layout: dojo::database::introspect::Layout - ); - fn set_entity_by_id( - ref self: T, - model_id: felt252, - entity_id: felt252, + model_selector: felt252, + index: ModelIndex, values: Span, layout: dojo::database::introspect::Layout ); fn delete_entity( - ref self: T, model: felt252, keys: Span, layout: dojo::database::introspect::Layout - ); - fn delete_entity_by_id( ref self: T, - model_id: felt252, - entity_id: felt252, - layout: dojo::database::introspect::Layout - ); - - fn entity_member( - self: @T, - model_id: felt252, - keys: Span, - member_id: felt252, - layout: dojo::database::introspect::Layout - ) -> Span; - - fn set_entity_member( - self: @T, - model_id: felt252, - keys: Span, - member_id: felt252, - values: Span, - layout: dojo::database::introspect::Layout - ); - - fn entity_member_by_id( - self: @T, - model_id: felt252, - entity_id: felt252, - member_id: felt252, - layout: dojo::database::introspect::Layout - ) -> Span; - - fn set_entity_member_by_id( - self: @T, - model_id: felt252, - entity_id: felt252, - member_id: felt252, - values: Span, + model_selector: felt252, + index: ModelIndex, layout: dojo::database::introspect::Layout ); @@ -94,7 +66,7 @@ trait IWorld { fn revoke_writer(ref self: T, resource: felt252, contract: ContractAddress); fn can_write_resource(self: @T, resource_id: felt252, contract: ContractAddress) -> bool; - fn can_write_model(self: @T, model_id: felt252, contract: ContractAddress) -> bool; + fn can_write_model(self: @T, model_selector: felt252, contract: ContractAddress) -> bool; fn can_write_namespace(self: @T, namespace_id: felt252, contract: ContractAddress) -> bool; } @@ -125,6 +97,7 @@ mod Errors { const NAMESPACE_ALREADY_REGISTERED: felt252 = 'namespace already registered'; const NO_ACCESS_TO_MEMBERS: felt252 = 'cannot access to model members'; const INVALID_MEMBER_ID: felt252 = 'invalid member id'; + const DELETE_ENTITY_MEMBER: felt252 = 'cannot delete entity member'; const UNEXPECTED_ERROR: felt252 = 'unexpected error'; } @@ -163,7 +136,7 @@ mod world { use dojo::resource_metadata::ResourceMetadata; use dojo::utils::entity_id_from_keys; - use super::Errors; + use super::{Errors, ModelIndex}; const WORLD: felt252 = 0; @@ -259,7 +232,7 @@ mod world { #[derive(Drop, starknet::Event)] struct StoreUpdateRecord { - model_id: felt252, + table: felt252, entity_id: felt252, values: Span, } @@ -536,20 +509,20 @@ mod world { /// /// # Arguments /// - /// * `model_id` - The model selector. + /// * `model_selector` - The model selector. /// * `contract` - The name of the contract. /// /// # Returns /// /// * `bool` - True if the contract can write to the model, false otherwise fn can_write_model( - self: @ContractState, model_id: felt252, contract: ContractAddress + self: @ContractState, model_selector: felt252, contract: ContractAddress ) -> bool { // TODO: use match self.resources... directly when https://github.com/starkware-libs/cairo/pull/5743 fixed - let resource: ResourceData = self.resources.read(model_id); + let resource: ResourceData = self.resources.read(model_selector); match resource { ResourceData::Model((_, model_address)) => self - ._check_model_write_access(model_id, model_address, contract), + ._check_model_write_access(model_selector, model_address, contract), _ => panic_with_felt252(Errors::INVALID_RESOURCE_SELECTOR) } } @@ -784,208 +757,77 @@ mod world { emit_event_syscall(keys.span(), values).unwrap_syscall(); } - /// Sets the model value for an entity. - /// - /// # Arguments - /// - /// * `model` - The selector of the model to be set. - /// * `keys` - The key to be used to find the entity. - /// * `value_names` - The name of model fields which are not a key. - /// * `values` - The value to be set. - /// * `layout` - The memory layout of the entity. - fn set_entity( - ref self: ContractState, - model: felt252, - keys: Span, - values: Span, + fn entity( + self: @ContractState, + model_selector: felt252, + index: ModelIndex, layout: dojo::database::introspect::Layout - ) { - assert( - self.can_write_model(model, get_caller_address()), Errors::NO_MODEL_WRITE_ACCESS - ); - - let entity_id = entity_id_from_keys(keys); - self._write_model_entity(model, entity_id, values, layout); - EventEmitter::emit(ref self, StoreSetRecord { table: model, keys, values }); + ) -> Span { + match index { + ModelIndex::Keys(keys) => { + let entity_id = entity_id_from_keys(keys); + self._read_model_entity(model_selector, entity_id, layout) + }, + ModelIndex::Id(entity_id) => { + self._read_model_entity(model_selector, entity_id, layout) + }, + ModelIndex::MemberId((entity_id, member_id)) => { + self._read_model_member(model_selector, entity_id, member_id, layout) + } + } } - /// Sets the model value for an entity. - /// - /// # Arguments - /// - /// * `model` - The selector of the model to be set. - /// * `entity_id` - The id of the entity to set. - /// * `value_names` - The name of model fields which are not a key. - /// * `values` - The value to be set. - /// * `layout` - The memory layout of the entity. - fn set_entity_by_id( + fn set_entity( ref self: ContractState, - model_id: felt252, - entity_id: felt252, + model_selector: felt252, + index: ModelIndex, values: Span, layout: dojo::database::introspect::Layout ) { assert( - self.can_write_model(model_id, get_caller_address()), Errors::NO_MODEL_WRITE_ACCESS + self.can_write_model(model_selector, get_caller_address()), Errors::NO_MODEL_WRITE_ACCESS ); - self._write_model_entity(model_id, entity_id, values, layout); - EventEmitter::emit(ref self, StoreUpdateRecord { model_id, entity_id, values }); + match index { + ModelIndex::Keys(keys) => { + let entity_id = entity_id_from_keys(keys); + self._write_model_entity(model_selector, entity_id, values, layout); + EventEmitter::emit(ref self, StoreSetRecord { table: model_selector, keys, values }); + }, + ModelIndex::Id(entity_id) => { + self._write_model_entity(model_selector, entity_id, values, layout); + EventEmitter::emit(ref self, StoreUpdateRecord { table: model_selector, entity_id, values }); + }, + ModelIndex::MemberId((entity_id, member_id)) => { + self._write_model_member(model_selector, entity_id, member_id, values, layout) + } + } } - - /// Deletes an existing entity. - /// Deleting is setting all the values to 0 in the given layout. - /// - /// # Arguments - /// - /// * `model` - The selector of the model to be deleted. - /// * `keys` - The key to be used to find the entity. - /// * `value_names` - The name of model fields which are not a key. - /// * `layout` - The memory layout of the entity. + fn delete_entity( ref self: ContractState, - model: felt252, - keys: Span, - layout: dojo::database::introspect::Layout - ) { - let entity_id = entity_id_from_keys(keys); - self.delete_entity_by_id(model, entity_id, layout); - } - - /// Deletes an existing entity. - /// Deleting is setting all the values to 0 in the given layout. - /// - /// # Arguments - /// - /// * `model_id` - The selector of the model to be deleted. - /// * `entity_id` - The id to be used to find the entity. - /// * `value_names` - The name of model fields which are not a key. - /// * `layout` - The memory layout of the entity. - fn delete_entity_by_id( - ref self: ContractState, - model_id: felt252, - entity_id: felt252, + model_selector: felt252, + index: ModelIndex, layout: dojo::database::introspect::Layout ) { assert( - self.can_write_model(model_id, get_caller_address()), Errors::NO_MODEL_WRITE_ACCESS + self.can_write_model(model_selector, get_caller_address()), Errors::NO_MODEL_WRITE_ACCESS ); - self._delete_model_entity(model_id, entity_id, layout); - EventEmitter::emit(ref self, StoreDelRecord { table: model_id, entity_id }); - } - - /// Gets the model value for an entity. Returns a zero initialized - /// model value if the entity has not been set. - /// - /// # Arguments - /// - /// * `model` - The selector of the model to be retrieved. - /// * `keys` - The keys used to find the entity. - /// * `value_names` - The name of model fields which are not a key. - /// * `layout` - The memory layout of the entity. - /// - /// # Returns - /// - /// * `Span` - The serialized value of the model, zero initialized if not set. - fn entity( - self: @ContractState, - model: felt252, - keys: Span, - layout: dojo::database::introspect::Layout - ) -> Span { - let entity_id = entity_id_from_keys(keys); - self._read_model_entity(model, entity_id, layout) - } - - /// Gets the model value for an entity. Returns a zero initialized - /// model value if the entity has not been set. - /// - /// # Arguments - /// - /// * `model` - The selector of the model to be retrieved. - /// * `entity_id` - The id used to find the entity. - /// * `value_names` - The name of model fields which are not a key. - /// * `layout` - The memory layout of the entity. - /// - /// # Returns - /// - /// * `Span` - The serialized value of the model, zero initialized if not set. - fn entity_by_id( - self: @ContractState, - model_id: felt252, - entity_id: felt252, - layout: dojo::database::introspect::Layout - ) -> Span { - self._read_model_entity(model_id, entity_id, layout) - } - - /// - fn entity_member( - self: @ContractState, - model_id: felt252, - keys: Span, - member_id: felt252, - layout: dojo::database::introspect::Layout - ) -> Span { - let entity_id = entity_id_from_keys(keys); - self.entity_member_by_id(model_id, entity_id, member_id, layout) - } - - /// - fn set_entity_member( - self: @ContractState, - model_id: felt252, - keys: Span, - member_id: felt252, - values: Span, - layout: dojo::database::introspect::Layout - ) { - let entity_id = entity_id_from_keys(keys); - self.set_entity_member_by_id(model_id, entity_id, member_id, values, layout); - } - - /// - fn entity_member_by_id( - self: @ContractState, - model_id: felt252, - entity_id: felt252, - member_id: felt252, - layout: dojo::database::introspect::Layout - ) -> Span { - match layout { - dojo::database::introspect::Layout::Struct(field_layouts) => { - let field_layout = SelfTrait::_find_member_layout(field_layouts, member_id); - match field_layout { - Option::Some(l) => self - ._read_entity_member(model_id, entity_id, member_id, l), - Option::None => panic_with_felt252(Errors::INVALID_MEMBER_ID) - } + match index { + ModelIndex::Keys(keys) => { + let entity_id = entity_id_from_keys(keys); + self._delete_model_entity(model_selector, entity_id, layout); + EventEmitter::emit(ref self, StoreDelRecord { table: model_selector, entity_id }); }, - _ => panic_with_felt252(Errors::NO_ACCESS_TO_MEMBERS) - } - } - - /// - fn set_entity_member_by_id( - self: @ContractState, - model_id: felt252, - entity_id: felt252, - member_id: felt252, - values: Span, - layout: dojo::database::introspect::Layout - ) { - match layout { - dojo::database::introspect::Layout::Struct(field_layouts) => { - let field_layout = SelfTrait::_find_member_layout(field_layouts, member_id); - match field_layout { - Option::Some(l) => self - ._write_entity_member(model_id, entity_id, member_id, values, l), - Option::None => panic_with_felt252(Errors::INVALID_MEMBER_ID) - }; + ModelIndex::Id(entity_id) => { + self._delete_model_entity(model_selector, entity_id, layout); + EventEmitter::emit(ref self, StoreDelRecord { table: model_selector, entity_id }); }, - _ => panic_with_felt252(Errors::NO_ACCESS_TO_MEMBERS) - }; + ModelIndex::MemberId(_) => { + panic_with_felt252(Errors::DELETE_ENTITY_MEMBER); + } + } } /// Gets the base contract class hash. @@ -1142,7 +984,7 @@ mod world { /// - the calling account has the owner and/or writer role for the model namespace. /// /// # Arguments - /// * `model_id` - the model selector to check. + /// * `model_selector` - the model selector to check. /// * `model_address` - the model contract address. /// * `contract` - the calling contract. /// @@ -1151,13 +993,13 @@ mod world { /// fn _check_model_write_access( self: @ContractState, - model_id: felt252, + model_selector: felt252, model_address: ContractAddress, contract: ContractAddress ) -> bool { - if !self.is_writer(model_id, contract) - && !self.is_account_owner(model_id) - && !self.is_account_writer(model_id) { + if !self.is_writer(model_selector, contract) + && !self.is_account_owner(model_selector) + && !self.is_account_writer(model_selector) { let model = IModelDispatcher { contract_address: model_address }; self._check_basic_write_access(model.namespace_hash(), contract) } else { @@ -1198,13 +1040,13 @@ mod world { /// Write a new entity. /// /// # Arguments - /// * `model_id` - the model selector + /// * `model_selector` - the model selector /// * `entity_id` - the id used to identify the record /// * `values` - the field values of the record /// * `layout` - the model layout fn _write_model_entity( ref self: ContractState, - model_id: felt252, + model_selector: felt252, entity_id: felt252, values: Span, layout: dojo::database::introspect::Layout @@ -1213,10 +1055,10 @@ mod world { match layout { Layout::Fixed(layout) => { - Self::_write_fixed_layout(model_id, entity_id, values, ref offset, layout); + Self::_write_fixed_layout(model_selector, entity_id, values, ref offset, layout); }, Layout::Struct(layout) => { - Self::_write_struct_layout(model_id, entity_id, values, ref offset, layout); + Self::_write_struct_layout(model_selector, entity_id, values, ref offset, layout); }, _ => { panic!("Unexpected layout type for a model."); } }; @@ -1230,16 +1072,16 @@ mod world { /// * `layout` - the model layout fn _delete_model_entity( ref self: ContractState, - model_id: felt252, + model_selector: felt252, entity_id: felt252, layout: dojo::database::introspect::Layout ) { match layout { Layout::Fixed(layout) => { - Self::_delete_fixed_layout(model_id, entity_id, layout); + Self::_delete_fixed_layout(model_selector, entity_id, layout); }, Layout::Struct(layout) => { - Self::_delete_struct_layout(model_id, entity_id, layout); + Self::_delete_struct_layout(model_selector, entity_id, layout); }, _ => { panic!("Unexpected layout type for a model."); } }; @@ -1253,7 +1095,7 @@ mod world { /// * `layout` - the model layout fn _read_model_entity( self: @ContractState, - model_id: felt252, + model_selector: felt252, entity_id: felt252, layout: dojo::database::introspect::Layout ) -> Span { @@ -1261,10 +1103,10 @@ mod world { match layout { Layout::Fixed(layout) => { - Self::_read_fixed_layout(model_id, entity_id, ref read_data, layout); + Self::_read_fixed_layout(model_selector, entity_id, ref read_data, layout); }, Layout::Struct(layout) => { - Self::_read_struct_layout(model_id, entity_id, ref read_data, layout); + Self::_read_struct_layout(model_selector, entity_id, ref read_data, layout); }, _ => { panic!("Unexpected layout type for a model."); } }; @@ -1273,25 +1115,25 @@ mod world { } /// - fn _read_entity_member( + fn _read_model_member( self: @ContractState, - model_id: felt252, + model_selector: felt252, entity_id: felt252, member_id: felt252, layout: dojo::database::introspect::Layout ) -> Span { let mut read_data = ArrayTrait::::new(); Self::_read_layout( - model_id, Self::_combine_key(entity_id, member_id), ref read_data, layout + model_selector, Self::_combine_key(entity_id, member_id), ref read_data, layout ); read_data.span() } /// - fn _write_entity_member( + fn _write_model_member( self: @ContractState, - model_id: felt252, + model_selector: felt252, entity_id: felt252, member_id: felt252, values: Span, @@ -1299,30 +1141,10 @@ mod world { ) { let mut offset = 0; Self::_write_layout( - model_id, Self::_combine_key(entity_id, member_id), values, ref offset, layout + model_selector, Self::_combine_key(entity_id, member_id), values, ref offset, layout ) } - /// - fn _find_member_layout( - field_layouts: Span, member_id: felt252 - ) -> Option { - let mut i = 0; - let layout = loop { - if i >= field_layouts.len() { - break Option::None; - } - - let field_layout = *field_layouts.at(i); - if field_layout.selector == member_id { - break Option::Some(field_layout.layout); - } - i += 1; - }; - - layout - } - /// Combine parent and child keys to build one full key. fn _combine_key(parent_key: felt252, child_key: felt252) -> felt252 { poseidon::poseidon_hash_span(array![parent_key, child_key].span()) diff --git a/crates/dojo-lang/src/inline_macros/delete.rs b/crates/dojo-lang/src/inline_macros/delete.rs index 51b3e56229..32f9a4fbdc 100644 --- a/crates/dojo-lang/src/inline_macros/delete.rs +++ b/crates/dojo-lang/src/inline_macros/delete.rs @@ -148,7 +148,7 @@ impl InlineMacroExprPlugin for DeleteMacro { let __delete_macro_value__ = {}; {}.delete_entity( dojo::model::Model::instance_selector(@__delete_macro_value__), - dojo::model::Model::keys(@__delete_macro_value__), + dojo::world::ModelIndex::Keys(dojo::model::Model::keys(@__delete_macro_value__)), dojo::model::Model::instance_layout(@__delete_macro_value__) );", entity, diff --git a/crates/dojo-lang/src/inline_macros/get.rs b/crates/dojo-lang/src/inline_macros/get.rs index 91cba669fd..4a1264e91c 100644 --- a/crates/dojo-lang/src/inline_macros/get.rs +++ b/crates/dojo-lang/src/inline_macros/get.rs @@ -109,9 +109,7 @@ impl InlineMacroExprPlugin for GetMacro { builder.add_str(&format!( "\n - let __{model}_layout__ = dojo::model::Model::<{model}>::layout(); - let __{model}: {model} = dojo::model::Model::entity({}, __get_macro_keys__, \ - __{model}_layout__);\n", + let __{model}: {model} = dojo::model::Model::entity({}, __get_macro_keys__);\n", world.as_syntax_node().get_text(db), )); } diff --git a/crates/dojo-lang/src/inline_macros/set.rs b/crates/dojo-lang/src/inline_macros/set.rs index 493384644e..f82bffbfc9 100644 --- a/crates/dojo-lang/src/inline_macros/set.rs +++ b/crates/dojo-lang/src/inline_macros/set.rs @@ -162,7 +162,7 @@ impl InlineMacroExprPlugin for SetMacro { let __set_model_instance__ = {}; {}.set_entity( dojo::model::Model::instance_selector(@__set_model_instance__), - dojo::model::Model::keys(@__set_model_instance__), + dojo::world::ModelIndex::Keys(dojo::model::Model::keys(@__set_model_instance__)), dojo::model::Model::values(@__set_model_instance__), dojo::model::Model::instance_layout(@__set_model_instance__), );", diff --git a/crates/dojo-lang/src/model.rs b/crates/dojo-lang/src/model.rs index d8c2862e6d..53b3a04dfb 100644 --- a/crates/dojo-lang/src/model.rs +++ b/crates/dojo-lang/src/model.rs @@ -307,6 +307,7 @@ pub fn handle_model_struct( pub struct $type_name$Values { $members_values$ } + #[generate_trait] impl $type_name$Model of $type_name$Trait { fn entity_id_from_keys($param_keys$) -> felt252 { @@ -314,39 +315,24 @@ impl $type_name$Model of $type_name$Trait { $serialized_param_keys$ core::poseidon::poseidon_hash_span(serialized.span()) } + fn get(world: dojo::world::IWorldDispatcher, $param_keys$) -> $type_name$ { let mut serialized = core::array::ArrayTrait::new(); $serialized_param_keys$ - dojo::model::Model::<$type_name$>::entity( - world, - serialized.span(), - dojo::model::Model::<$type_name$>::layout() - ) - } - fn set(self: @$type_name$, world: dojo::world::IWorldDispatcher) { - dojo::model::Model::<$type_name$>::set_entity( - world, - dojo::model::Model::<$type_name$>::keys(self), - dojo::model::Model::<$type_name$>::values(self), - dojo::model::Model::<$type_name$>::layout() - ) - } - fn delete(self: @$type_name$, world: dojo::world::IWorldDispatcher) { - dojo::model::Model::<$type_name$>::delete_entity( - world, - dojo::model::Model::<$type_name$>::keys(self), - dojo::model::Model::<$type_name$>::layout() - ) + + dojo::model::Model::<$type_name$>::entity(world, serialized.span()) } $field_accessors$ } + impl $type_name$ModelValues of dojo::model::ModelValues<$type_name$Values> { fn values(self: @$type_name$Values) -> Span { let mut serialized = core::array::ArrayTrait::new(); $serialized_values$ core::array::ArrayTrait::span(@serialized) } + fn from_values(values: Span) -> $type_name$Values { let mut serialized = values; let entity_values = core::serde::Serde::<$type_name$Values>::deserialize(ref serialized); @@ -357,41 +343,44 @@ impl $type_name$ModelValues of dojo::model::ModelValues<$type_name$Values> { } core::option::OptionTrait::<$type_name$Values>::unwrap(entity_values) } + fn get(world: dojo::world::IWorldDispatcher, id: felt252) -> $type_name$Values { - let values = dojo::world::IWorldDispatcherTrait::entity_by_id( + let values = dojo::world::IWorldDispatcherTrait::entity( world, dojo::model::Model::<$type_name$>::selector(), - id, + dojo::world::ModelIndex::Id(id), dojo::model::Model::<$type_name$>::layout() ); Self::from_values(values) } + fn update(self: @$type_name$Values, world: dojo::world::IWorldDispatcher, id: felt252) { - dojo::world::IWorldDispatcherTrait::set_entity_by_id( + dojo::world::IWorldDispatcherTrait::set_entity( world, dojo::model::Model::<$type_name$>::selector(), - id, + dojo::world::ModelIndex::Id(id), self.values(), dojo::model::Model::<$type_name$>::layout() ); } + fn delete(self: @$type_name$Values, world: dojo::world::IWorldDispatcher, id: felt252) { - dojo::world::IWorldDispatcherTrait::delete_entity_by_id( + dojo::world::IWorldDispatcherTrait::delete_entity( world, dojo::model::Model::<$type_name$>::selector(), - id, + dojo::world::ModelIndex::Id(id), dojo::model::Model::<$type_name$>::layout() ); } } + impl $type_name$Impl of dojo::model::Model<$type_name$> { - fn entity(world: dojo::world::IWorldDispatcher, keys: Span, layout: \ - dojo::database::introspect::Layout) -> $type_name$ { + fn entity(world: dojo::world::IWorldDispatcher, keys: Span) -> $type_name$ { let values = dojo::world::IWorldDispatcherTrait::entity( world, Self::selector(), - keys, - layout + dojo::world::ModelIndex::Keys(keys), + Self::layout() ); // TODO: Generate method to deserialize from keys / values directly to avoid @@ -413,64 +402,68 @@ impl $type_name$Impl of dojo::model::Model<$type_name$> { core::option::OptionTrait::<$type_name$>::unwrap(entity) } - fn set_entity( - world: dojo::world::IWorldDispatcher, - keys: Span, - values: Span, - layout: dojo::database::introspect::Layout + fn set( + self: @$type_name$, + world: dojo::world::IWorldDispatcher ) { dojo::world::IWorldDispatcherTrait::set_entity( world, Self::selector(), - keys, - values, - layout + dojo::world::ModelIndex::Keys(Self::keys(self)), + Self::values(self), + Self::layout() ); } - fn delete_entity( - world: dojo::world::IWorldDispatcher, - keys: Span, - layout: dojo::database::introspect::Layout + fn delete( + self: @$type_name$, + world: dojo::world::IWorldDispatcher ) { dojo::world::IWorldDispatcherTrait::delete_entity( world, Self::selector(), - keys, - layout + dojo::world::ModelIndex::Keys(Self::keys(self)), + Self::layout() ); } fn entity_member( world: dojo::world::IWorldDispatcher, keys: Span, - member_id: felt252, - layout: dojo::database::introspect::Layout + member_id: felt252 ) -> Span { - dojo::world::IWorldDispatcherTrait::entity_member( - world, - Self::selector(), - keys, - member_id, - layout - ) + match dojo::utils::find_model_field_layout(Self::layout(), member_id) { + Option::Some(field_layout) => { + let entity_id = dojo::utils::entity_id_from_keys(keys); + dojo::world::IWorldDispatcherTrait::entity( + world, + Self::selector(), + dojo::world::ModelIndex::MemberId((entity_id, member_id)), + field_layout + ) + }, + Option::None => core::panic_with_felt252('bad member id') + } } fn set_entity_member( + self: @$type_name$, world: dojo::world::IWorldDispatcher, - keys: Span, member_id: felt252, - values: Span, - layout: dojo::database::introspect::Layout + values: Span ) { - dojo::world::IWorldDispatcherTrait::set_entity_member( - world, - Self::selector(), - keys, - member_id, - values, - layout - ); + match dojo::utils::find_model_field_layout(Self::layout(), member_id) { + Option::Some(field_layout) => { + dojo::world::IWorldDispatcherTrait::set_entity( + world, + Self::selector(), + dojo::world::ModelIndex::MemberId((self.entity_id(), member_id)), + values, + field_layout + ) + }, + Option::None => core::panic_with_felt252('bad member id') + } } #[inline(always)] @@ -512,7 +505,7 @@ impl $type_name$Impl of dojo::model::Model<$type_name$> { fn namespace_hash() -> felt252 { $model_namespace_hash$ } - + #[inline(always)] fn entity_id(self: @$type_name$) -> felt252 { core::poseidon::poseidon_hash_span(self.keys()) @@ -713,8 +706,7 @@ fn generate_field_accessors( let values = dojo::model::Model::<$type_name$>::entity_member( world, serialized.span(), - $field_selector$, - dojo::model::Model::<$type_name$>::layout() + $field_selector$ ); let mut serialized = core::array::ArrayTrait::new(); @@ -732,17 +724,14 @@ fn generate_field_accessors( core::option::OptionTrait::<$field_type$>::unwrap(field_value) } - fn set_$field_name$(self: @$type_name$, world: dojo::world::IWorldDispatcher, value: \ - $field_type$) { + fn set_$field_name$(self: @$type_name$, world: dojo::world::IWorldDispatcher, value: $field_type$) { let mut serialized = core::array::ArrayTrait::new(); core::serde::Serde::serialize(@value, ref serialized); - dojo::model::Model::<$type_name$>::set_entity_member( + self.set_entity_member( world, - dojo::model::Model::<$type_name$>::keys(self), $field_selector$, - serialized.span(), - dojo::model::Model::<$type_name$>::layout() + serialized.span() ); } ", diff --git a/examples/spawn-and-move/._target b/examples/spawn-and-move/._target new file mode 100644 index 0000000000000000000000000000000000000000..7a6a71237f99d60bcab0516a4b0cb2dffab28f29 GIT binary patch literal 4096 zcmeH~y$ZrW498PJ)TQX+B<1h{q&Nx=jt(Md2e)#)Ml8L4&|X2`%E4Fh1$+?e)%t-h z?vg-A@+TqWw*{L07Bm1BT(ISuZP>#q4LaJ#0OnCgU7HsG!_xT=n>o&^yq<^k1e|pH z^lQY>^+UHs5{-D8N*qO~xX%@zXvw`xuE#}Kq%Q7-EPR|Ri~zh;2D!3rx7&Nq){TC< zUSw1YDtpGd0vJ3KibQ}25CI}U1c(3;AOb{y2oM1x@OK2NAMo`DTFx%WS%!I1WCGbX k$wC&y3S$){F_-edByJV+B#%S=3;zR*&--5&4ZteP8=kg2wg3PC literal 0 HcmV?d00001 diff --git a/examples/spawn-and-move/manifests/dev/base/abis/dojo-world.json b/examples/spawn-and-move/manifests/dev/base/abis/dojo-world.json index 45a552a772..6dd9a18e1a 100644 --- a/examples/spawn-and-move/manifests/dev/base/abis/dojo-world.json +++ b/examples/spawn-and-move/manifests/dev/base/abis/dojo-world.json @@ -46,6 +46,24 @@ } ] }, + { + "type": "enum", + "name": "dojo::world::ModelIndex", + "variants": [ + { + "name": "Keys", + "type": "core::array::Span::" + }, + { + "name": "Id", + "type": "core::felt252" + }, + { + "name": "MemberId", + "type": "(core::felt252, core::felt252)" + } + ] + }, { "type": "struct", "name": "core::array::Span::", @@ -282,36 +300,12 @@ "name": "entity", "inputs": [ { - "name": "model", + "name": "model_selector", "type": "core::felt252" }, { - "name": "keys", - "type": "core::array::Span::" - }, - { - "name": "layout", - "type": "dojo::database::introspect::Layout" - } - ], - "outputs": [ - { - "type": "core::array::Span::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "entity_by_id", - "inputs": [ - { - "name": "model_id", - "type": "core::felt252" - }, - { - "name": "entity_id", - "type": "core::felt252" + "name": "index", + "type": "dojo::world::ModelIndex" }, { "name": "layout", @@ -330,36 +324,12 @@ "name": "set_entity", "inputs": [ { - "name": "model", + "name": "model_selector", "type": "core::felt252" }, { - "name": "keys", - "type": "core::array::Span::" - }, - { - "name": "values", - "type": "core::array::Span::" - }, - { - "name": "layout", - "type": "dojo::database::introspect::Layout" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "set_entity_by_id", - "inputs": [ - { - "name": "model_id", - "type": "core::felt252" - }, - { - "name": "entity_id", - "type": "core::felt252" + "name": "index", + "type": "dojo::world::ModelIndex" }, { "name": "values", @@ -378,32 +348,12 @@ "name": "delete_entity", "inputs": [ { - "name": "model", - "type": "core::felt252" - }, - { - "name": "keys", - "type": "core::array::Span::" - }, - { - "name": "layout", - "type": "dojo::database::introspect::Layout" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "delete_entity_by_id", - "inputs": [ - { - "name": "model_id", + "name": "model_selector", "type": "core::felt252" }, { - "name": "entity_id", - "type": "core::felt252" + "name": "index", + "type": "dojo::world::ModelIndex" }, { "name": "layout", @@ -413,118 +363,6 @@ "outputs": [], "state_mutability": "external" }, - { - "type": "function", - "name": "entity_member", - "inputs": [ - { - "name": "model_id", - "type": "core::felt252" - }, - { - "name": "keys", - "type": "core::array::Span::" - }, - { - "name": "member_id", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::database::introspect::Layout" - } - ], - "outputs": [ - { - "type": "core::array::Span::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "set_entity_member", - "inputs": [ - { - "name": "model_id", - "type": "core::felt252" - }, - { - "name": "keys", - "type": "core::array::Span::" - }, - { - "name": "member_id", - "type": "core::felt252" - }, - { - "name": "values", - "type": "core::array::Span::" - }, - { - "name": "layout", - "type": "dojo::database::introspect::Layout" - } - ], - "outputs": [], - "state_mutability": "view" - }, - { - "type": "function", - "name": "entity_member_by_id", - "inputs": [ - { - "name": "model_id", - "type": "core::felt252" - }, - { - "name": "entity_id", - "type": "core::felt252" - }, - { - "name": "member_id", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::database::introspect::Layout" - } - ], - "outputs": [ - { - "type": "core::array::Span::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "set_entity_member_by_id", - "inputs": [ - { - "name": "model_id", - "type": "core::felt252" - }, - { - "name": "entity_id", - "type": "core::felt252" - }, - { - "name": "member_id", - "type": "core::felt252" - }, - { - "name": "values", - "type": "core::array::Span::" - }, - { - "name": "layout", - "type": "dojo::database::introspect::Layout" - } - ], - "outputs": [], - "state_mutability": "view" - }, { "type": "function", "name": "base", @@ -665,7 +503,7 @@ "name": "can_write_model", "inputs": [ { - "name": "model_id", + "name": "model_selector", "type": "core::felt252" }, { @@ -1085,7 +923,7 @@ "kind": "struct", "members": [ { - "name": "model_id", + "name": "table", "type": "core::felt252", "kind": "data" }, diff --git a/examples/spawn-and-move/manifests/dev/base/contracts/dojo_examples-actions-40b6994c.toml b/examples/spawn-and-move/manifests/dev/base/contracts/dojo_examples-actions-40b6994c.toml index 4a16b04d7a..db6aee3dcf 100644 --- a/examples/spawn-and-move/manifests/dev/base/contracts/dojo_examples-actions-40b6994c.toml +++ b/examples/spawn-and-move/manifests/dev/base/contracts/dojo_examples-actions-40b6994c.toml @@ -1,6 +1,6 @@ kind = "DojoContract" -class_hash = "0x2ade67f41a4f566fa398de2d4dd5d332f4d896e37df9e9a5b0ba20235d47b8a" -original_class_hash = "0x2ade67f41a4f566fa398de2d4dd5d332f4d896e37df9e9a5b0ba20235d47b8a" +class_hash = "0x74797c6e9747725624677cf1b644f2cc2c78ba2dd5060ff445e17c2327fdd2e" +original_class_hash = "0x74797c6e9747725624677cf1b644f2cc2c78ba2dd5060ff445e17c2327fdd2e" base_class_hash = "0x0" abi = "manifests/dev/base/abis/contracts/dojo_examples-actions-40b6994c.json" reads = [] diff --git a/examples/spawn-and-move/manifests/dev/base/contracts/dojo_examples-mock_token-31599eb2.toml b/examples/spawn-and-move/manifests/dev/base/contracts/dojo_examples-mock_token-31599eb2.toml index bff0f27750..5a1e70cb03 100644 --- a/examples/spawn-and-move/manifests/dev/base/contracts/dojo_examples-mock_token-31599eb2.toml +++ b/examples/spawn-and-move/manifests/dev/base/contracts/dojo_examples-mock_token-31599eb2.toml @@ -1,6 +1,6 @@ kind = "DojoContract" -class_hash = "0x26a365084df1a672ce1b4547a57c0459e6509e9cecfcdc96d9d2497001618d3" -original_class_hash = "0x26a365084df1a672ce1b4547a57c0459e6509e9cecfcdc96d9d2497001618d3" +class_hash = "0x3d04e3dd18b2a2d9a8847be8ef2a6dc32abee5171b77feb26d02b772b067c5c" +original_class_hash = "0x3d04e3dd18b2a2d9a8847be8ef2a6dc32abee5171b77feb26d02b772b067c5c" base_class_hash = "0x0" abi = "manifests/dev/base/abis/contracts/dojo_examples-mock_token-31599eb2.json" reads = [] diff --git a/examples/spawn-and-move/manifests/dev/base/dojo-world.toml b/examples/spawn-and-move/manifests/dev/base/dojo-world.toml index b0786997ac..03f06ebea5 100644 --- a/examples/spawn-and-move/manifests/dev/base/dojo-world.toml +++ b/examples/spawn-and-move/manifests/dev/base/dojo-world.toml @@ -1,6 +1,6 @@ kind = "Class" -class_hash = "0x53125b807356a0a8d476e96ccac4a601a56ad7d534ffe66a8769526877bcf6" -original_class_hash = "0x53125b807356a0a8d476e96ccac4a601a56ad7d534ffe66a8769526877bcf6" +class_hash = "0x2bcf11feac030c5ec81496dfc73ae256568c5b7518f8542e25dd0e42938de7e" +original_class_hash = "0x2bcf11feac030c5ec81496dfc73ae256568c5b7518f8542e25dd0e42938de7e" abi = "manifests/dev/base/abis/dojo-world.json" tag = "dojo-world" manifest_name = "dojo-world" diff --git a/examples/spawn-and-move/manifests/dev/deployment/abis/dojo-world.json b/examples/spawn-and-move/manifests/dev/deployment/abis/dojo-world.json index 45a552a772..6dd9a18e1a 100644 --- a/examples/spawn-and-move/manifests/dev/deployment/abis/dojo-world.json +++ b/examples/spawn-and-move/manifests/dev/deployment/abis/dojo-world.json @@ -46,6 +46,24 @@ } ] }, + { + "type": "enum", + "name": "dojo::world::ModelIndex", + "variants": [ + { + "name": "Keys", + "type": "core::array::Span::" + }, + { + "name": "Id", + "type": "core::felt252" + }, + { + "name": "MemberId", + "type": "(core::felt252, core::felt252)" + } + ] + }, { "type": "struct", "name": "core::array::Span::", @@ -282,36 +300,12 @@ "name": "entity", "inputs": [ { - "name": "model", + "name": "model_selector", "type": "core::felt252" }, { - "name": "keys", - "type": "core::array::Span::" - }, - { - "name": "layout", - "type": "dojo::database::introspect::Layout" - } - ], - "outputs": [ - { - "type": "core::array::Span::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "entity_by_id", - "inputs": [ - { - "name": "model_id", - "type": "core::felt252" - }, - { - "name": "entity_id", - "type": "core::felt252" + "name": "index", + "type": "dojo::world::ModelIndex" }, { "name": "layout", @@ -330,36 +324,12 @@ "name": "set_entity", "inputs": [ { - "name": "model", + "name": "model_selector", "type": "core::felt252" }, { - "name": "keys", - "type": "core::array::Span::" - }, - { - "name": "values", - "type": "core::array::Span::" - }, - { - "name": "layout", - "type": "dojo::database::introspect::Layout" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "set_entity_by_id", - "inputs": [ - { - "name": "model_id", - "type": "core::felt252" - }, - { - "name": "entity_id", - "type": "core::felt252" + "name": "index", + "type": "dojo::world::ModelIndex" }, { "name": "values", @@ -378,32 +348,12 @@ "name": "delete_entity", "inputs": [ { - "name": "model", - "type": "core::felt252" - }, - { - "name": "keys", - "type": "core::array::Span::" - }, - { - "name": "layout", - "type": "dojo::database::introspect::Layout" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "delete_entity_by_id", - "inputs": [ - { - "name": "model_id", + "name": "model_selector", "type": "core::felt252" }, { - "name": "entity_id", - "type": "core::felt252" + "name": "index", + "type": "dojo::world::ModelIndex" }, { "name": "layout", @@ -413,118 +363,6 @@ "outputs": [], "state_mutability": "external" }, - { - "type": "function", - "name": "entity_member", - "inputs": [ - { - "name": "model_id", - "type": "core::felt252" - }, - { - "name": "keys", - "type": "core::array::Span::" - }, - { - "name": "member_id", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::database::introspect::Layout" - } - ], - "outputs": [ - { - "type": "core::array::Span::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "set_entity_member", - "inputs": [ - { - "name": "model_id", - "type": "core::felt252" - }, - { - "name": "keys", - "type": "core::array::Span::" - }, - { - "name": "member_id", - "type": "core::felt252" - }, - { - "name": "values", - "type": "core::array::Span::" - }, - { - "name": "layout", - "type": "dojo::database::introspect::Layout" - } - ], - "outputs": [], - "state_mutability": "view" - }, - { - "type": "function", - "name": "entity_member_by_id", - "inputs": [ - { - "name": "model_id", - "type": "core::felt252" - }, - { - "name": "entity_id", - "type": "core::felt252" - }, - { - "name": "member_id", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::database::introspect::Layout" - } - ], - "outputs": [ - { - "type": "core::array::Span::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "set_entity_member_by_id", - "inputs": [ - { - "name": "model_id", - "type": "core::felt252" - }, - { - "name": "entity_id", - "type": "core::felt252" - }, - { - "name": "member_id", - "type": "core::felt252" - }, - { - "name": "values", - "type": "core::array::Span::" - }, - { - "name": "layout", - "type": "dojo::database::introspect::Layout" - } - ], - "outputs": [], - "state_mutability": "view" - }, { "type": "function", "name": "base", @@ -665,7 +503,7 @@ "name": "can_write_model", "inputs": [ { - "name": "model_id", + "name": "model_selector", "type": "core::felt252" }, { @@ -1085,7 +923,7 @@ "kind": "struct", "members": [ { - "name": "model_id", + "name": "table", "type": "core::felt252", "kind": "data" }, diff --git a/examples/spawn-and-move/manifests/dev/deployment/manifest.json b/examples/spawn-and-move/manifests/dev/deployment/manifest.json index 11c5cc1ecd..28d89ef246 100644 --- a/examples/spawn-and-move/manifests/dev/deployment/manifest.json +++ b/examples/spawn-and-move/manifests/dev/deployment/manifest.json @@ -1,8 +1,8 @@ { "world": { "kind": "WorldContract", - "class_hash": "0x53125b807356a0a8d476e96ccac4a601a56ad7d534ffe66a8769526877bcf6", - "original_class_hash": "0x53125b807356a0a8d476e96ccac4a601a56ad7d534ffe66a8769526877bcf6", + "class_hash": "0x2bcf11feac030c5ec81496dfc73ae256568c5b7518f8542e25dd0e42938de7e", + "original_class_hash": "0x2bcf11feac030c5ec81496dfc73ae256568c5b7518f8542e25dd0e42938de7e", "abi": [ { "type": "impl", @@ -51,6 +51,24 @@ } ] }, + { + "type": "enum", + "name": "dojo::world::ModelIndex", + "variants": [ + { + "name": "Keys", + "type": "core::array::Span::" + }, + { + "name": "Id", + "type": "core::felt252" + }, + { + "name": "MemberId", + "type": "(core::felt252, core::felt252)" + } + ] + }, { "type": "struct", "name": "core::array::Span::", @@ -287,36 +305,12 @@ "name": "entity", "inputs": [ { - "name": "model", + "name": "model_selector", "type": "core::felt252" }, { - "name": "keys", - "type": "core::array::Span::" - }, - { - "name": "layout", - "type": "dojo::database::introspect::Layout" - } - ], - "outputs": [ - { - "type": "core::array::Span::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "entity_by_id", - "inputs": [ - { - "name": "model_id", - "type": "core::felt252" - }, - { - "name": "entity_id", - "type": "core::felt252" + "name": "index", + "type": "dojo::world::ModelIndex" }, { "name": "layout", @@ -335,36 +329,12 @@ "name": "set_entity", "inputs": [ { - "name": "model", + "name": "model_selector", "type": "core::felt252" }, { - "name": "keys", - "type": "core::array::Span::" - }, - { - "name": "values", - "type": "core::array::Span::" - }, - { - "name": "layout", - "type": "dojo::database::introspect::Layout" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "set_entity_by_id", - "inputs": [ - { - "name": "model_id", - "type": "core::felt252" - }, - { - "name": "entity_id", - "type": "core::felt252" + "name": "index", + "type": "dojo::world::ModelIndex" }, { "name": "values", @@ -383,32 +353,12 @@ "name": "delete_entity", "inputs": [ { - "name": "model", - "type": "core::felt252" - }, - { - "name": "keys", - "type": "core::array::Span::" - }, - { - "name": "layout", - "type": "dojo::database::introspect::Layout" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "delete_entity_by_id", - "inputs": [ - { - "name": "model_id", + "name": "model_selector", "type": "core::felt252" }, { - "name": "entity_id", - "type": "core::felt252" + "name": "index", + "type": "dojo::world::ModelIndex" }, { "name": "layout", @@ -418,118 +368,6 @@ "outputs": [], "state_mutability": "external" }, - { - "type": "function", - "name": "entity_member", - "inputs": [ - { - "name": "model_id", - "type": "core::felt252" - }, - { - "name": "keys", - "type": "core::array::Span::" - }, - { - "name": "member_id", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::database::introspect::Layout" - } - ], - "outputs": [ - { - "type": "core::array::Span::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "set_entity_member", - "inputs": [ - { - "name": "model_id", - "type": "core::felt252" - }, - { - "name": "keys", - "type": "core::array::Span::" - }, - { - "name": "member_id", - "type": "core::felt252" - }, - { - "name": "values", - "type": "core::array::Span::" - }, - { - "name": "layout", - "type": "dojo::database::introspect::Layout" - } - ], - "outputs": [], - "state_mutability": "view" - }, - { - "type": "function", - "name": "entity_member_by_id", - "inputs": [ - { - "name": "model_id", - "type": "core::felt252" - }, - { - "name": "entity_id", - "type": "core::felt252" - }, - { - "name": "member_id", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::database::introspect::Layout" - } - ], - "outputs": [ - { - "type": "core::array::Span::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "set_entity_member_by_id", - "inputs": [ - { - "name": "model_id", - "type": "core::felt252" - }, - { - "name": "entity_id", - "type": "core::felt252" - }, - { - "name": "member_id", - "type": "core::felt252" - }, - { - "name": "values", - "type": "core::array::Span::" - }, - { - "name": "layout", - "type": "dojo::database::introspect::Layout" - } - ], - "outputs": [], - "state_mutability": "view" - }, { "type": "function", "name": "base", @@ -670,7 +508,7 @@ "name": "can_write_model", "inputs": [ { - "name": "model_id", + "name": "model_selector", "type": "core::felt252" }, { @@ -1090,7 +928,7 @@ "kind": "struct", "members": [ { - "name": "model_id", + "name": "table", "type": "core::felt252", "kind": "data" }, @@ -1315,8 +1153,8 @@ ] } ], - "address": "0x779a3cdeb3eb10214831b0567a696c86bbe643bcd8052a757a3cbffcd1ed1f8", - "transaction_hash": "0x40cd02130b923efa48f93d37226f68c96185cf13cfa62e9fa7ab662ed3b9069", + "address": "0x6d95c696211b4453e1f4b1b2dc9fb9d91602d4a7a1550567362bd9b8bcd9a82", + "transaction_hash": "0x3290c6ba1226811dcf2c971b005dffd18965e93d0c11f9d8f2ae853d6890ab4", "block_number": 3, "seed": "dojo_examples", "metadata": { @@ -1336,9 +1174,9 @@ "contracts": [ { "kind": "DojoContract", - "address": "0x4ad8156f623243ebf2690990d863a93c2e31d793de590cc16ee03b7b34cf8e6", - "class_hash": "0x2ade67f41a4f566fa398de2d4dd5d332f4d896e37df9e9a5b0ba20235d47b8a", - "original_class_hash": "0x2ade67f41a4f566fa398de2d4dd5d332f4d896e37df9e9a5b0ba20235d47b8a", + "address": "0x1a0504af4ffec1a748ae115e8d36b8cd7913298308ae4eb39e1eee8fc19d516", + "class_hash": "0x74797c6e9747725624677cf1b644f2cc2c78ba2dd5060ff445e17c2327fdd2e", + "original_class_hash": "0x74797c6e9747725624677cf1b644f2cc2c78ba2dd5060ff445e17c2327fdd2e", "base_class_hash": "0x26a4f5d2d9638877a2648297339275df5eaab0adb3cdf0010887c2dbf2be4", "abi": [ { @@ -1743,9 +1581,9 @@ }, { "kind": "DojoContract", - "address": "0x232d3cb46856ece8348ff09b3ef57664469ae755f26fb2ab8109438c0456fbc", - "class_hash": "0x26a365084df1a672ce1b4547a57c0459e6509e9cecfcdc96d9d2497001618d3", - "original_class_hash": "0x26a365084df1a672ce1b4547a57c0459e6509e9cecfcdc96d9d2497001618d3", + "address": "0x5a8f0aacc5fa9b30fdffee908d7e6093dedda92ad6deefff31aa06b473312e8", + "class_hash": "0x3d04e3dd18b2a2d9a8847be8ef2a6dc32abee5171b77feb26d02b772b067c5c", + "original_class_hash": "0x3d04e3dd18b2a2d9a8847be8ef2a6dc32abee5171b77feb26d02b772b067c5c", "base_class_hash": "0x26a4f5d2d9638877a2648297339275df5eaab0adb3cdf0010887c2dbf2be4", "abi": [ { @@ -1962,7 +1800,7 @@ }, { "kind": "DojoContract", - "address": "0x722d2c5926b5fdcde0ffe9ecd8e1d89c35bc40be91b80e6bea1c4aa8595903f", + "address": "0x5958b21ca9debb6bf444aebefef92305d3b0f3fd39e20097161282078666873", "class_hash": "0x479bfb12dcba5398d77303e7a665fc3fedb16f2d7f9cb1f5d7e2beb3b7e2ba7", "original_class_hash": "0x479bfb12dcba5398d77303e7a665fc3fedb16f2d7f9cb1f5d7e2beb3b7e2ba7", "base_class_hash": "0x26a4f5d2d9638877a2648297339275df5eaab0adb3cdf0010887c2dbf2be4", diff --git a/examples/spawn-and-move/manifests/dev/deployment/manifest.toml b/examples/spawn-and-move/manifests/dev/deployment/manifest.toml index 88602a609a..df4d035f2d 100644 --- a/examples/spawn-and-move/manifests/dev/deployment/manifest.toml +++ b/examples/spawn-and-move/manifests/dev/deployment/manifest.toml @@ -1,10 +1,10 @@ [world] kind = "WorldContract" -class_hash = "0x53125b807356a0a8d476e96ccac4a601a56ad7d534ffe66a8769526877bcf6" -original_class_hash = "0x53125b807356a0a8d476e96ccac4a601a56ad7d534ffe66a8769526877bcf6" +class_hash = "0x2bcf11feac030c5ec81496dfc73ae256568c5b7518f8542e25dd0e42938de7e" +original_class_hash = "0x2bcf11feac030c5ec81496dfc73ae256568c5b7518f8542e25dd0e42938de7e" abi = "manifests/dev/deployment/abis/dojo-world.json" -address = "0x779a3cdeb3eb10214831b0567a696c86bbe643bcd8052a757a3cbffcd1ed1f8" -transaction_hash = "0x40cd02130b923efa48f93d37226f68c96185cf13cfa62e9fa7ab662ed3b9069" +address = "0x6d95c696211b4453e1f4b1b2dc9fb9d91602d4a7a1550567362bd9b8bcd9a82" +transaction_hash = "0x3290c6ba1226811dcf2c971b005dffd18965e93d0c11f9d8f2ae853d6890ab4" block_number = 3 seed = "dojo_examples" manifest_name = "dojo-world" @@ -23,9 +23,9 @@ manifest_name = "dojo-base" [[contracts]] kind = "DojoContract" -address = "0x4ad8156f623243ebf2690990d863a93c2e31d793de590cc16ee03b7b34cf8e6" -class_hash = "0x2ade67f41a4f566fa398de2d4dd5d332f4d896e37df9e9a5b0ba20235d47b8a" -original_class_hash = "0x2ade67f41a4f566fa398de2d4dd5d332f4d896e37df9e9a5b0ba20235d47b8a" +address = "0x1a0504af4ffec1a748ae115e8d36b8cd7913298308ae4eb39e1eee8fc19d516" +class_hash = "0x74797c6e9747725624677cf1b644f2cc2c78ba2dd5060ff445e17c2327fdd2e" +original_class_hash = "0x74797c6e9747725624677cf1b644f2cc2c78ba2dd5060ff445e17c2327fdd2e" base_class_hash = "0x26a4f5d2d9638877a2648297339275df5eaab0adb3cdf0010887c2dbf2be4" abi = "manifests/dev/deployment/abis/contracts/dojo_examples-actions-40b6994c.json" reads = [] @@ -40,9 +40,9 @@ manifest_name = "dojo_examples-actions-40b6994c" [[contracts]] kind = "DojoContract" -address = "0x232d3cb46856ece8348ff09b3ef57664469ae755f26fb2ab8109438c0456fbc" -class_hash = "0x26a365084df1a672ce1b4547a57c0459e6509e9cecfcdc96d9d2497001618d3" -original_class_hash = "0x26a365084df1a672ce1b4547a57c0459e6509e9cecfcdc96d9d2497001618d3" +address = "0x5a8f0aacc5fa9b30fdffee908d7e6093dedda92ad6deefff31aa06b473312e8" +class_hash = "0x3d04e3dd18b2a2d9a8847be8ef2a6dc32abee5171b77feb26d02b772b067c5c" +original_class_hash = "0x3d04e3dd18b2a2d9a8847be8ef2a6dc32abee5171b77feb26d02b772b067c5c" base_class_hash = "0x26a4f5d2d9638877a2648297339275df5eaab0adb3cdf0010887c2dbf2be4" abi = "manifests/dev/deployment/abis/contracts/dojo_examples-mock_token-31599eb2.json" reads = [] @@ -54,7 +54,7 @@ manifest_name = "dojo_examples-mock_token-31599eb2" [[contracts]] kind = "DojoContract" -address = "0x722d2c5926b5fdcde0ffe9ecd8e1d89c35bc40be91b80e6bea1c4aa8595903f" +address = "0x5958b21ca9debb6bf444aebefef92305d3b0f3fd39e20097161282078666873" class_hash = "0x479bfb12dcba5398d77303e7a665fc3fedb16f2d7f9cb1f5d7e2beb3b7e2ba7" original_class_hash = "0x479bfb12dcba5398d77303e7a665fc3fedb16f2d7f9cb1f5d7e2beb3b7e2ba7" base_class_hash = "0x26a4f5d2d9638877a2648297339275df5eaab0adb3cdf0010887c2dbf2be4"