Skip to content

Commit

Permalink
Refactor examples
Browse files Browse the repository at this point in the history
  • Loading branch information
web3olalala committed Sep 20, 2023
1 parent 1aa6533 commit 9c45bd4
Show file tree
Hide file tree
Showing 6 changed files with 289 additions and 45 deletions.
62 changes: 42 additions & 20 deletions examples/sources/codegen/components/counter.move
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)
)
}
}
111 changes: 111 additions & 0 deletions examples/sources/codegen/components/state.move
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)
)
}
}
72 changes: 57 additions & 15 deletions examples/sources/codegen/eps/world.move
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})
}
}
8 changes: 4 additions & 4 deletions examples/sources/codegen/init.move
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
module examples::init {
use std::ascii::string;
use sui::transfer;
use sui::tx_context::TxContext;
use examples::world;

use examples::counter_component;
use examples::counter_comp;

fun init(ctx: &mut TxContext) {
let world = world::create_world(ctx);
let world = world::create(string(b"Examples Name"), string(b"Examples Description"),ctx);

// Add Component

counter_component::register(&mut world);
counter_comp::register(&mut world);

transfer::public_share_object(world);
}
Expand Down
35 changes: 33 additions & 2 deletions examples/sources/entity_key.move
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);
}
}
Loading

0 comments on commit 9c45bd4

Please sign in to comment.