数据操作记录

分析结果

对于每一次数据访问器的 offer 方法的调用,其都会返回一个 DataTransactionResult 。这一返回值包括:

类型

DataTransactionResult.Type 指示操作是否成功,如果失败了,指示其如何失败的。

UNDEFINED

并不清楚操作的结果是什么——意味着在某些地方出了错

SUCCESS

操作成功

FAILURE

操作由于明确的原因失败了(例如不支持的数据)

ERROR

操作由于意料之外的原因失败了

CANCELLED

操作触发的事件被取消了

受到影响的数据

结果同时提供了一个包含了若干个不可修改的容器的列表,用于储存参与操作的数据。

getSuccessfulData()

包含了所有被成功设置的数据

getReplacedData()

包含了所有被成功设置的数据替换的旧数据

getRejectedData()

包含所有并未被成功设置的数据

示例

治疗一个玩家

你一定记得在 使用数据键 这一页面中关于治疗的示例。现在想像玩家的生命值只有半颗心(一点生命值),然后以之前提到的示例得以救治。那么在这种情况下, DataTransactionResult 应该是这个样子:

  • getType() 方法将会返回 SUCCESS

  • getRejectedData() 方法将会返回一个空的列表

  • getReplacedData() 方法将会返回一个包含有 Keys.HEALTH 数据键和对应的包含 1.0 的数据值的键值对

  • getSuccessfulData() 方法将会返回一个包含有 Keys.HEALTH 数据键和对应的包含 20.0 的数据值的键值对

现在如果我们去使用 操作数据 这一页面提供的治疗方法呢?因为 HealthData 同时包含着当前生命值和最大生命值,所以除了上面的结果, getReplacedData()getSuccessfulData() 两个方法返回的列表分别还会包含一个新的元素:一个包含有 Keys.HEALTH 数据键和对应的包含 20.0 的数据值的键值对。

设置一块石头的生命值

如果上面的示例应用于一块石头,那么它会静默地返回一个失败结果,而不是尝试设置不兼容的数据。不过现在我们想象一下我们从一个(满血的)玩家那里获取到一个 HealthData 再把它应用于他脚下的 Location 对应的石头上。我们当然可以这么做,因为 Location 实现了数据访问器。然后如果我们这么做了,返回的 DataTransactionResult 便会是这样子的:

  • getType() 方法将会返回 FAILURE

  • getRejectedData() 方法将会返回两个分别包含有 Keys.HEALTHMAX_HEALTH 的数据键,然后它们对应的数据值都是 20.0

  • getReplacedData()getSuccessfulData() 方法将分别返回空的列表

撤回操作

因为操作结果是不可变的,所以把它用于存储数据更改是可信的。同时,对于这种更改的撤回是可行的。为此,只需要调用数据访问器的 undo() 方法,并传入欲撤回的操作结果。在一些部分数据设置成功的场合,撤回这一行为是很有用的。因为只有部分数据设置成功了,所以很多时候不妨把部分设置成功这一操作也撤回掉。

代码示例:撤回操作

import org.spongepowered.api.data.DataHolder;
import org.spongepowered.api.data.DataTransactionResult;
import org.spongepowered.api.data.manipulator.DataManipulator;

public void safeOffer(DataHolder target, DataManipulator data) {
    DataTransactionResult result = target.offer(data);
    if (result.getType() != DataTransactionResult.Type.SUCCESS) {
        target.undo(result);
    }
}