diff --git a/Scarb.toml b/Scarb.toml index c78a283..f122028 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -7,7 +7,7 @@ version = "0.1.0" sierra-replace-ids = true [dependencies] -dojo = { git = "https://github.com/dojoengine/dojo", tag = "v0.3.0-rc8" } +dojo = { git = "https://github.com/dojoengine/dojo", rev = "4e820e29feb2fe076ef64c592b2f19fbd13b9e38" } [[target.dojo]] @@ -19,7 +19,6 @@ rpc_url = "http://localhost:5050/" # Default account for katana with seed = 0 account_address = "0x517ececd29116499f4a1b64b094da79ba08dfd54a3edaa316134c41f8160973" private_key = "0x1800000000300000180000000000030000000000003006001800006600" -# world_address = "0x7d1f066a910bd86f532fa9ca66766722c20d47462fb99fb2fb0e1030262f9c5" # Madara testnet # rpc_url = "https://api.cartridge.gg/x/shinai/madara" diff --git a/src/systems/with_decorator.cairo b/src/actions.cairo similarity index 75% rename from src/systems/with_decorator.cairo rename to src/actions.cairo index 6e03729..f3fd039 100644 --- a/src/systems/with_decorator.cairo +++ b/src/actions.cairo @@ -2,19 +2,18 @@ use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; use dojo_examples::models::{Position, Moves, Direction}; use starknet::{ContractAddress, ClassHash}; -// trait: specify functions to implement #[starknet::interface] -trait IPlayerActions { +trait IActions { fn spawn(self: @TContractState); fn move(self: @TContractState, direction: Direction); } #[dojo::contract] -mod player_actions { +mod actions { use starknet::{ContractAddress, get_caller_address}; use dojo_examples::models::{Position, Moves, Direction, Vec2}; use dojo_examples::utils::next_position; - use super::IPlayerActions; + use super::IActions; #[event] #[derive(Drop, starknet::Event)] @@ -30,17 +29,23 @@ mod player_actions { // impl: implement functions specified in trait #[external(v0)] - impl PlayerActionsImpl of IPlayerActions { + impl ActionsImpl of IActions { // ContractState is defined by system decorator expansion fn spawn(self: @ContractState) { let world = self.world_dispatcher.read(); let player = get_caller_address(); let position = get!(world, player, (Position)); + let moves = get!(world, player, (Moves)); + set!( world, ( - Moves { player, remaining: 10, last_direction: Direction::None(()) }, - Position { player, vec: Vec2 { x: 10, y: 10 } }, + Moves { + player, remaining: moves.remaining + 1, last_direction: Direction::None(()) + }, + Position { + player, vec: Vec2 { x: position.vec.x + 10, y: position.vec.y + 10 } + }, ) ); } @@ -61,8 +66,7 @@ mod player_actions { #[cfg(test)] mod tests { - use core::traits::Into; - use array::{ArrayTrait}; + use starknet::class_hash::Felt252TryIntoClassHash; use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; @@ -70,7 +74,7 @@ mod tests { use dojo_examples::models::{position, moves}; use dojo_examples::models::{Position, Moves, Direction, Vec2}; - use super::{player_actions, IPlayerActionsDispatcher, IPlayerActionsDispatcherTrait}; + use super::{actions, IActionsDispatcher, IActionsDispatcherTrait}; #[test] #[available_gas(30000000)] @@ -84,17 +88,17 @@ mod tests { // deploy systems contract let contract_address = world - .deploy_contract('salt', player_actions::TEST_CLASS_HASH.try_into().unwrap()); - let player_actions_system = IPlayerActionsDispatcher { contract_address }; + .deploy_contract('salt', actions::TEST_CLASS_HASH.try_into().unwrap()); + let actions_system = IActionsDispatcher { contract_address }; // System calls - player_actions_system.spawn(); - player_actions_system.move(Direction::Right(())); + actions_system.spawn(); + actions_system.move(Direction::Right(())); let moves = get!(world, caller, Moves); let right_dir_felt: felt252 = Direction::Right(()).into(); - assert(moves.remaining == 9, 'moves is wrong'); + assert(moves.remaining == 0, 'moves is wrong'); assert(moves.last_direction.into() == right_dir_felt, 'last direction is wrong'); let new_position = get!(world, caller, Position); diff --git a/src/lib.cairo b/src/lib.cairo index b0a80e5..e3149f1 100644 --- a/src/lib.cairo +++ b/src/lib.cairo @@ -1,11 +1,3 @@ +mod actions; mod models; - -mod systems { - // example with #[system] decorator - mod with_decorator; - - // raw example with #[starknet::contract] decorator - mod raw_contract; -} - mod utils; diff --git a/src/systems/raw_contract.cairo b/src/systems/raw_contract.cairo deleted file mode 100644 index 02e6bc2..0000000 --- a/src/systems/raw_contract.cairo +++ /dev/null @@ -1,114 +0,0 @@ -use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; -use dojo_examples::models::{Direction}; - -// trait: specify functions to implement -#[starknet::interface] -trait IPlayerActions { - fn spawn(self: @TContractState); - fn move(self: @TContractState, direction: Direction); -} - -// exact same functionality as examples/ecs/src/systems/with_decorator.cairo -// requires some additional code without using system decorator -#[starknet::contract] -mod player_actions_external { - use starknet::{ContractAddress, get_caller_address}; - use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; - use dojo_examples::models::{Position, Moves, Direction, Vec2}; - use dojo_examples::utils::next_position; - use super::IPlayerActions; - - #[storage] - struct Storage { - world_dispatcher: IWorldDispatcher, - } - - #[event] - #[derive(Drop, starknet::Event)] - enum Event { - Moved: Moved, - } - - #[derive(Drop, starknet::Event)] - struct Moved { - player: ContractAddress, - direction: Direction - } - - // impl: implement functions specified in trait - #[external(v0)] - impl PlayerActionsImpl of IPlayerActions { - fn spawn(self: @ContractState) { - let world = self.world_dispatcher.read(); - let player = get_caller_address(); - let position = get!(world, player, (Position)); - set!( - world, - ( - Moves { player, remaining: 10, last_direction: Direction::None(()) }, - Position { player, vec: Vec2 { x: 10, y: 10 } }, - ) - ); - } - - fn move(self: @ContractState, direction: Direction) { - let world = self.world_dispatcher.read(); - let player = get_caller_address(); - let (mut position, mut moves) = get!(world, player, (Position, Moves)); - moves.remaining -= 1; - moves.last_direction = direction; - let next = next_position(position, direction); - set!(world, (moves, next)); - emit!(world, Moved { player, direction }); - return (); - } - } -} - -#[cfg(test)] -mod tests { - use core::traits::Into; - use array::{ArrayTrait}; - use starknet::class_hash::Felt252TryIntoClassHash; - - use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; - use dojo::test_utils::{spawn_test_world, deploy_contract}; - - use dojo_examples::models::{position, moves}; - use dojo_examples::models::{Position, Moves, Direction, Vec2}; - - use super::{ - IPlayerActionsDispatcher, IPlayerActionsDispatcherTrait, - player_actions_external as player_actions - }; - - #[test] - #[available_gas(30000000)] - fn test_move() { - let caller = starknet::contract_address_const::<0x0>(); - - // models - let mut models = array![position::TEST_CLASS_HASH, moves::TEST_CLASS_HASH,]; - // deploy world with models - let world = spawn_test_world(models); - - // deploy systems contract - let contract_address = world - .deploy_contract('salt', player_actions::TEST_CLASS_HASH.try_into().unwrap()); - let player_actions_system = IPlayerActionsDispatcher { contract_address }; - - // System calls - player_actions_system.spawn(); - player_actions_system.move(Direction::Right(())); - - let moves = get!(world, caller, Moves); - let right_dir_felt: felt252 = Direction::Right(()).into(); - - assert(moves.remaining == 9, 'moves is wrong'); - assert(moves.last_direction.into() == right_dir_felt, 'last direction is wrong'); - - let new_position = get!(world, caller, Position); - assert(new_position.vec.x == 11, 'position x is wrong'); - assert(new_position.vec.y == 10, 'position y is wrong'); - } -}