From e3c0902aa304b8594c0cc7f649e3eb61f9a00baa Mon Sep 17 00:00:00 2001 From: notV4l Date: Tue, 3 Oct 2023 20:31:19 +0200 Subject: [PATCH] feat: add some world events --- crates/dojo-core/src/world.cairo | 89 +++++++++++++++++++++++--------- 1 file changed, 65 insertions(+), 24 deletions(-) diff --git a/crates/dojo-core/src/world.cairo b/crates/dojo-core/src/world.cairo index fb792c34e3..3af28af0af 100644 --- a/crates/dojo-core/src/world.cairo +++ b/crates/dojo-core/src/world.cairo @@ -9,12 +9,7 @@ trait IWorld { fn uuid(ref self: T) -> usize; fn emit(self: @T, keys: Array, values: Span); fn entity( - self: @T, - model: felt252, - keys: Span, - offset: u8, - length: usize, - layout: Span + self: @T, model: felt252, keys: Span, offset: u8, length: usize, layout: Span ) -> Span; fn set_entity( ref self: T, @@ -25,7 +20,12 @@ trait IWorld { layout: Span ); fn entities( - self: @T, model: felt252, index: Option, values: Span, values_length: usize, values_layout: Span + self: @T, + model: felt252, + index: Option, + values: Span, + values_length: usize, + values_layout: Span ) -> (Span, Span>); fn set_executor(ref self: T, contract_address: ContractAddress); fn executor(self: @T) -> ContractAddress; @@ -69,7 +69,10 @@ mod world { WorldSpawned: WorldSpawned, ModelRegistered: ModelRegistered, StoreSetRecord: StoreSetRecord, - StoreDelRecord: StoreDelRecord + StoreDelRecord: StoreDelRecord, + WriterUpdated: WriterUpdated, + OwnerUpdated: OwnerUpdated, + ExecutorUpdated: ExecutorUpdated } #[derive(Drop, starknet::Event)] @@ -81,7 +84,8 @@ mod world { #[derive(Drop, starknet::Event)] struct ModelRegistered { name: felt252, - class_hash: ClassHash + class_hash: ClassHash, + prev_class_hash: ClassHash } #[derive(Drop, starknet::Event)] @@ -98,6 +102,27 @@ mod world { keys: Span, } + #[derive(Drop, starknet::Event)] + struct WriterUpdated { + model: felt252, + system: ContractAddress, + value: bool + } + + #[derive(Drop, starknet::Event)] + struct OwnerUpdated { + address: ContractAddress, + target: felt252, + value: bool, + } + + #[derive(Drop, starknet::Event)] + struct ExecutorUpdated { + address: ContractAddress, + prev_address: ContractAddress, + } + + #[storage] struct Storage { executor_dispatcher: IExecutorDispatcher, @@ -113,11 +138,7 @@ mod world { #[constructor] fn constructor(ref self: ContractState, executor: ContractAddress) { self.executor_dispatcher.write(IExecutorDispatcher { contract_address: executor }); - self - .owners - .write( - (WORLD, starknet::get_tx_info().unbox().account_contract_address), bool::True(()) - ); + self.owners.write((WORLD, starknet::get_tx_info().unbox().account_contract_address), true); EventEmitter::emit( ref self, @@ -172,7 +193,9 @@ mod world { fn grant_owner(ref self: ContractState, address: ContractAddress, target: felt252) { let caller = get_caller_address(); assert(self.is_owner(caller, target) || self.is_owner(caller, WORLD), 'not owner'); - self.owners.write((target, address), bool::True(())); + self.owners.write((target, address), true); + + EventEmitter::emit(ref self, OwnerUpdated { address, target, value: true }); } /// Revokes owner permission to the system for the model. @@ -185,7 +208,9 @@ mod world { fn revoke_owner(ref self: ContractState, address: ContractAddress, target: felt252) { let caller = get_caller_address(); assert(self.is_owner(caller, target) || self.is_owner(caller, WORLD), 'not owner'); - self.owners.write((target, address), bool::False(())); + self.owners.write((target, address), false); + + EventEmitter::emit(ref self, OwnerUpdated { address, target, value: false }); } /// Checks if the provided system is a writer of the model. @@ -213,10 +238,11 @@ mod world { let caller = get_caller_address(); assert( - self.is_owner(caller, model) || self.is_owner(caller, WORLD), - 'not owner or writer' + self.is_owner(caller, model) || self.is_owner(caller, WORLD), 'not owner or writer' ); - self.writers.write((model, system), bool::True(())); + self.writers.write((model, system), true); + + EventEmitter::emit(ref self, WriterUpdated { model, system, value: true }); } /// Revokes writer permission to the system for the model. @@ -235,7 +261,9 @@ mod world { || self.is_owner(caller, WORLD), 'not owner or writer' ); - self.writers.write((model, system), bool::False(())); + self.writers.write((model, system), false); + + EventEmitter::emit(ref self, WriterUpdated { model, system, value: false }); } /// Registers a model in the world. If the model is already registered, @@ -248,16 +276,19 @@ mod world { let caller = get_caller_address(); let calldata = ArrayTrait::new(); let name = *class_call(@self, class_hash, NAME_ENTRYPOINT, calldata.span())[0]; + let mut prev_class_hash = starknet::class_hash::ClassHashZeroable::zero(); // If model is already registered, validate permission to update. - if self.models.read(name).is_non_zero() { + let current_class_hash = self.models.read(name); + if current_class_hash.is_non_zero() { assert(self.is_owner(caller, name), 'only owner can update'); + prev_class_hash = current_class_hash; } else { - self.owners.write((name, caller), bool::True(())); + self.owners.write((name, caller), true); }; self.models.write(name, class_hash); - EventEmitter::emit(ref self, ModelRegistered { name, class_hash }); + EventEmitter::emit(ref self, ModelRegistered { name, class_hash, prev_class_hash }); } /// Gets the class hash of a registered model. @@ -379,7 +410,12 @@ mod world { /// * `Span` - The entity IDs. /// * `Span>` - The entities. fn entities( - self: @ContractState, model: felt252, index: Option, values: Span, values_length: usize, values_layout: Span + self: @ContractState, + model: felt252, + index: Option, + values: Span, + values_length: usize, + values_layout: Span ) -> (Span, Span>) { let class_hash = self.models.read(model); @@ -395,9 +431,14 @@ mod world { fn set_executor(ref self: ContractState, contract_address: ContractAddress) { // Only owner can set executor assert(self.is_owner(get_caller_address(), WORLD), 'only owner can set executor'); + let prev_address = self.executor_dispatcher.read().contract_address; self .executor_dispatcher .write(IExecutorDispatcher { contract_address: contract_address }); + + EventEmitter::emit( + ref self, ExecutorUpdated { address: contract_address, prev_address } + ); } /// Gets the executor contract address.