-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1aa6533
commit 9c45bd4
Showing
6 changed files
with
289 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,56 @@ | ||
module examples::counter_component { | ||
use examples::world::{Self , World}; | ||
|
||
// Systems | ||
module examples::counter_comp { | ||
use std::ascii::{String, string}; | ||
use std::option::none; | ||
use std::vector; | ||
use sui::bcs; | ||
use examples::entity_key; | ||
use examples::world::{Self , World}; | ||
|
||
// Systems | ||
friend examples::counter_system; | ||
|
||
const COMPONENT_NAME: vector<u8> = b"Counter Component"; | ||
|
||
struct CounterData has drop, store { | ||
value: u64 | ||
|
||
public fun id() : address { | ||
entity_key::from_bytes(b"Examples Counter Comp") | ||
} | ||
|
||
public fun new(value: u64): CounterData { | ||
CounterData { | ||
value | ||
} | ||
public fun field_types() : vector<String> { | ||
vector[string(b"u64")] | ||
} | ||
|
||
public fun register(world: &mut World) { | ||
world::add_component<CounterData>( | ||
/// value: u64 | ||
struct Field has drop, store { | ||
data: vector<u8> | ||
} | ||
|
||
public fun register(world: &mut World) { | ||
world::add_component<Field>( | ||
world, | ||
COMPONENT_NAME, | ||
new(0) | ||
id(), | ||
Field { data: encode(10) } | ||
); | ||
} | ||
|
||
public(friend) fun update(world: &mut World, value: u64) { | ||
world::get_mut_component<CounterData>(world, COMPONENT_NAME).value = value; | ||
let data = encode(value); | ||
world::get_mut_component<Field>(world, id()).data = data; | ||
world::emit_update_event(id(), none(), data) | ||
} | ||
|
||
public fun get(world: &World): u64 { | ||
world::get_component<CounterData>(world, COMPONENT_NAME).value | ||
let field = world::get_component<Field>(world, id()); | ||
decode(field.data) | ||
} | ||
|
||
public fun encode(value: u64): vector<u8> { | ||
let data = vector::empty<u8>(); | ||
vector::append(&mut data, bcs::to_bytes(&value)); | ||
data | ||
} | ||
|
||
public fun decode(bytes: vector<u8>): u64 { | ||
let data = bcs::new(bytes); | ||
( | ||
bcs::peel_u64(&mut data) | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
module examples::state_comp { | ||
use std::ascii::{String, string}; | ||
use std::option::some; | ||
use std::vector; | ||
use sui::bcs; | ||
use sui::tx_context::TxContext; | ||
use sui::table::{ Self, Table }; | ||
use examples::entity_key; | ||
use examples::world::{ Self , World }; | ||
|
||
public fun id() : address { | ||
entity_key::from_bytes(b"Examples State Comp") | ||
} | ||
|
||
public fun field_types() : vector<String> { | ||
vector[string(b"vector<u8>"), string(b"u64")] | ||
} | ||
|
||
/// state: vector<u8> | ||
/// last_update_time: u64 | ||
struct Field has drop, store { | ||
data: vector<u8> | ||
} | ||
|
||
public fun register(world: &mut World, ctx: &mut TxContext) { | ||
world::add_component<Table<address,Field>>( | ||
world, | ||
id(), | ||
table::new<address,Field>(ctx) | ||
); | ||
} | ||
|
||
public(friend) fun add(world : &mut World, key: address, state: vector<u8>, last_update_time: u64) { | ||
let component = world::get_mut_component<Table<address,Field>>(world, id()); | ||
let data = encode(state, last_update_time); | ||
table::add(component, key, Field { data }); | ||
world::emit_add_event(id(), key, data) | ||
} | ||
|
||
public(friend) fun remove(world : &mut World, key: address) { | ||
let component = world::get_mut_component<Table<address,Field>>(world, id()); | ||
table::remove(component, key); | ||
world::emit_remove_event(id(), key) | ||
} | ||
|
||
public(friend) fun update(world : &mut World, key: address, state: vector<u8>, last_update_time: u64) { | ||
let component = world::get_mut_component<Table<address,Field>>(world, id()); | ||
let field = table::borrow_mut<address, Field>(component, key); | ||
let data = encode(state, last_update_time); | ||
field.data = data; | ||
world::emit_update_event(id(), some(key), data) | ||
} | ||
|
||
public(friend) fun update_state(world : &mut World, key: address, state: vector<u8>) { | ||
let component = world::get_mut_component<Table<address,Field>>(world, id()); | ||
let field = table::borrow_mut<address, Field>(component, key); | ||
let (_, last_update_time) = decode(field.data); | ||
let data = encode(state, last_update_time); | ||
field.data = data; | ||
world::emit_update_event(id(), some(key), data) | ||
} | ||
|
||
public(friend) fun update_last_update_time(world : &mut World, key: address, last_update_time: u64) { | ||
let component = world::get_mut_component<Table<address,Field>>(world, id()); | ||
let field = table::borrow_mut<address, Field>(component, key); | ||
let (state, _) = decode(field.data); | ||
let data = encode(state, last_update_time); | ||
field.data = data; | ||
world::emit_update_event(id(), some(key), data) | ||
} | ||
|
||
public fun get(world : &World, key: address) : (vector<u8>, u64) { | ||
let component = world::get_component<Table<address,Field>>(world, id()); | ||
let field = table::borrow<address, Field>(component, key); | ||
decode(field.data) | ||
} | ||
|
||
public fun get_state(world : &World, key: address) : vector<u8> { | ||
let component = world::get_component<Table<address,Field>>(world, id()); | ||
let field = table::borrow<address, Field>(component, key); | ||
let (state,_) = decode(field.data); | ||
state | ||
} | ||
|
||
public fun get_last_update_time(world : &World, key: address) : u64 { | ||
let component = world::get_component<Table<address,Field>>(world, id()); | ||
let field = table::borrow<address, Field>(component, key); | ||
let (_,last_update_time) = decode(field.data); | ||
last_update_time | ||
} | ||
|
||
public fun contains(world : &World, key: address): bool { | ||
let component = world::get_component<Table<address,Field>>(world, id()); | ||
table::contains<address, Field>(component, key) | ||
} | ||
|
||
public fun encode(state: vector<u8>, last_update_time: u64): vector<u8> { | ||
let data = vector::empty<u8>(); | ||
vector::append(&mut data, bcs::to_bytes(&state)); | ||
vector::append(&mut data, bcs::to_bytes(&last_update_time)); | ||
data | ||
} | ||
|
||
public fun decode(bytes: vector<u8>): (vector<u8>, u64) { | ||
let data = bcs::new(bytes); | ||
( | ||
bcs::peel_vec_u8(&mut data), | ||
bcs::peel_u64(&mut data) | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,82 @@ | ||
module examples::world { | ||
use std::ascii::String; | ||
use std::option::Option; | ||
use sui::event; | ||
use sui::tx_context::TxContext; | ||
use sui::hash::keccak256; | ||
use sui::bag::{ Self, Bag }; | ||
use sui::object::{ Self, UID }; | ||
|
||
const CompDoesNotExist: u64 = 0; | ||
const CompAlreadyExists: u64 = 1; | ||
|
||
struct World has key, store{ | ||
id: UID, | ||
/// Name of the world | ||
name: String, | ||
/// Description of the world | ||
description: String, | ||
/// Components of the world | ||
/// K256(component_name) <=> Table<entity_key,T> | ||
components: Bag, | ||
} | ||
|
||
public fun create_world(ctx: &mut TxContext): World { | ||
struct CompRemoveField has copy, drop { | ||
comp: address, | ||
key: address | ||
} | ||
|
||
struct CompAddField has copy, drop { | ||
comp: address, | ||
key: address, | ||
data: vector<u8> | ||
} | ||
|
||
struct CompUpdateField has copy, drop { | ||
comp: address, | ||
key: Option<address>, | ||
data: vector<u8> | ||
} | ||
|
||
public fun create(name: String, description: String, ctx: &mut TxContext): World { | ||
World { | ||
id: object::new(ctx), | ||
name, | ||
description, | ||
components: bag::new(ctx), | ||
} | ||
} | ||
|
||
public fun get_component<T : store>(world: &World, component_name: vector<u8>): &T { | ||
let component_id = keccak256(&component_name); | ||
bag::borrow<vector<u8>, T>(&world.components, component_id) | ||
public fun info(world: &World): (String, String) { | ||
(world.name, world.description) | ||
} | ||
|
||
public fun get_component<T : store>(world: &World, id: address): &T { | ||
assert!(bag::contains(&world.components, id), CompDoesNotExist); | ||
bag::borrow<address, T>(&world.components, id) | ||
} | ||
|
||
public fun get_mut_component<T : store>(world: &mut World, id: address): &mut T { | ||
assert!(bag::contains(&world.components, id), CompDoesNotExist); | ||
bag::borrow_mut<address, T>(&mut world.components, id) | ||
} | ||
|
||
public fun add_component<T : store>(world: &mut World, id: address, component: T){ | ||
assert!(!bag::contains(&world.components, id), CompAlreadyExists); | ||
bag::add<address,T>(&mut world.components, id, component); | ||
} | ||
|
||
public fun contains(world: &mut World, id: address): bool { | ||
bag::contains(&mut world.components, id) | ||
} | ||
|
||
public fun get_mut_component<T : store>(world: &mut World, component_name: vector<u8>): &mut T { | ||
let component_id = keccak256(&component_name); | ||
bag::borrow_mut<vector<u8>, T>(&mut world.components, component_id) | ||
public fun emit_remove_event(comp: address, key: address) { | ||
event::emit(CompRemoveField { comp, key }) | ||
} | ||
|
||
public fun add_component<T : store>(world: &mut World, component_name: vector<u8>, component: T){ | ||
let component_id = keccak256(&component_name); | ||
bag::add<vector<u8>,T>(&mut world.components, component_id, component); | ||
public fun emit_add_event(comp: address, key: address, data: vector<u8>) { | ||
event::emit(CompAddField { comp, key, data}) | ||
} | ||
|
||
public fun contains(world: &mut World, component_name: vector<u8>): bool { | ||
let component_id = keccak256(&component_name); | ||
bag::contains(&mut world.components, component_id) | ||
public fun emit_update_event(comp: address, key: Option<address>, data: vector<u8>) { | ||
event::emit(CompUpdateField { comp, key, data}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,38 @@ | ||
module examples::entity_key { | ||
use std::vector; | ||
use sui::address; | ||
use sui::object; | ||
|
||
public fun object_to_entity_key<T: key + store>(object: &T): vector<u8> { | ||
object::id_bytes(object) | ||
public fun from_object<T: key + store>(object: &T): address { | ||
object::id_address(object) | ||
} | ||
|
||
public fun from_bytes(bytes: vector<u8>): address { | ||
let len = vector::length(&bytes); | ||
assert!(len != 0 && len <= 32, 0); | ||
|
||
let offset = address::length() - len; | ||
|
||
let i = 0; | ||
while (i < offset) { | ||
vector::push_back(&mut bytes,0u8); | ||
i = i + 1; | ||
}; | ||
|
||
address::from_bytes(bytes) | ||
} | ||
|
||
public fun from_u256(x: u256): address { | ||
address::from_u256(x) | ||
} | ||
|
||
#[test] | ||
public fun test_from_bytes() { | ||
assert!(from_bytes(b"Hello") == @0x48656c6c6f000000000000000000000000000000000000000000000000000000, 0); | ||
} | ||
|
||
#[test] | ||
public fun test_from_u256() { | ||
assert!(from_u256(1) == @0x1, 0); | ||
} | ||
} |
Oops, something went wrong.