Skip to content

Commit

Permalink
feat: add some world events
Browse files Browse the repository at this point in the history
  • Loading branch information
notV4l committed Oct 3, 2023
1 parent cb79f2b commit e3c0902
Showing 1 changed file with 65 additions and 24 deletions.
89 changes: 65 additions & 24 deletions crates/dojo-core/src/world.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,7 @@ trait IWorld<T> {
fn uuid(ref self: T) -> usize;
fn emit(self: @T, keys: Array<felt252>, values: Span<felt252>);
fn entity(
self: @T,
model: felt252,
keys: Span<felt252>,
offset: u8,
length: usize,
layout: Span<u8>
self: @T, model: felt252, keys: Span<felt252>, offset: u8, length: usize, layout: Span<u8>
) -> Span<felt252>;
fn set_entity(
ref self: T,
Expand All @@ -25,7 +20,12 @@ trait IWorld<T> {
layout: Span<u8>
);
fn entities(
self: @T, model: felt252, index: Option<felt252>, values: Span<felt252>, values_length: usize, values_layout: Span<u8>
self: @T,
model: felt252,
index: Option<felt252>,
values: Span<felt252>,
values_length: usize,
values_layout: Span<u8>
) -> (Span<felt252>, Span<Span<felt252>>);
fn set_executor(ref self: T, contract_address: ContractAddress);
fn executor(self: @T) -> ContractAddress;
Expand Down Expand Up @@ -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)]
Expand All @@ -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)]
Expand All @@ -98,6 +102,27 @@ mod world {
keys: Span<felt252>,
}

#[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,
Expand All @@ -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,
Expand Down Expand Up @@ -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.
Expand All @@ -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.
Expand Down Expand Up @@ -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.
Expand All @@ -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,
Expand All @@ -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.
Expand Down Expand Up @@ -379,7 +410,12 @@ mod world {
/// * `Span<felt252>` - The entity IDs.
/// * `Span<Span<felt252>>` - The entities.
fn entities(
self: @ContractState, model: felt252, index: Option<felt252>, values: Span<felt252>, values_length: usize, values_layout: Span<u8>
self: @ContractState,
model: felt252,
index: Option<felt252>,
values: Span<felt252>,
values_length: usize,
values_layout: Span<u8>
) -> (Span<felt252>, Span<Span<felt252>>) {
let class_hash = self.models.read(model);

Expand All @@ -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.
Expand Down

0 comments on commit e3c0902

Please sign in to comment.