系统
系统 = 逻辑
系统是世界逻辑的基础。虽然系统本质上是无状态的,但其主要作用是修改组件的状态。每个系统都有一个'execute'函数,可在世界内部交互时调用。
让我们来看一个最简单的系统,它可以改变 Moves
组件的状态。
#[system]
mod Spawn {
use array::ArrayTrait;
use traits::Into;
use dojo::world::Context;
use dojo_examples::components::Position;
use dojo_examples::components::Moves;
fn execute(ctx: Context) {
set !(
ctx.world, ctx.origin, (
Moves { player: ctx.origin, remaining: 10 }
)
);
return ();
}
}
执行函数
execute
函数在系统中是强制性的,调用时以 Context
为第一个参数。更多信息请参阅 Context。
系统中的其他函数
您可以自由地在系统中添加其他函数,但这些函数不能从世界中调用。这对于将你的逻辑分割成小块非常有用。
使用视图函数
有时,我们需要动态地计算组件的值,而不是获取其静态状态。例如,在 VRGDA 中,如果要确定当前价格,仅查询组件状态是不够的。相反,您需要根据某些参数和当前状态来计算价格。
这就是视图函数发挥作用的地方。
什么是视图函数?
视图函数是从组件的现有状态推导或计算值的一种方法。它们由世界调用,并接收组件的当前状态作为参数。随后,这些函数会返回一个基于该状态的计算值。
来自 VRGDA 的示例:
下面的片段摘自 这个链接 中的 VRGDA 示例,说明了如何实现视图函数:
#[system]
mod view_price {
//... other code ...
fn execute(ctx: Context, game_id: u64, item_id: u128, amount: u128) -> Fixed {
let mut auction = get!(ctx.world, (game_id, item_id), Auction);
// Convert auction to VRGDA
let VRGDA = auction.to_LogisticVRGDA();
// Calculate time since the auction began
let time_since_start: u128 = get_block_timestamp().into() - auction.start_time.into();
// Compute the current price
VRGDA.get_vrgda_price(
FixedTrait::new(time_since_start, false), // Time elapsed since auction start
FixedTrait::new(auction.sold, false) // Quantity sold
)
}
}
在此示例中,函数根据正在进行的拍卖状态计算并返回 VRGDA 的当前价格。
如何调用视图函数?
我希望修订后的版本能使您想要传达的信息更加清晰流畅!
系统验证
系统必须获得写入组件的权限。默认情况下,它们没有权限。不过,我们可以通过 sozo
赋予系统写入组件的权限。
sozo auth writer Moves Spawn
在这里,我们授权 Spawn
系统写入Moves
组件。
阅读 sozo 文档中的更多内容。