服務
几乎一切(事件,权限等)都是通过服务(Service)来处理的。所有服务都可以通过服务管理器(Service Manager)访问:
import org.spongepowered.api.Sponge;
Sponge.getServiceManager().provide(EventManager.class);
如果你想要从什么地方获取到一个对象的引用,服务管理器可能是你获取引用的最合适选择。
使用准则
关于服务的相关注册应于
POST_INITIALIZATION
,也就是游戏初始化的最后阶段进行。服务应在
SERVER_ABOUT_TO_START
阶段完全可用。
你可以参阅 插件的生命週期 页面了解关于游戏生命周期的更多知识。
備註
一个好的做法是尽快注册服务,以便其他插件可以注意到对应的服务已被提供。
提供您自己的服务
你的插件可以通过提供一个核心接口的实现,如 PermissionService 来提供服务,或者通过提供一个不属于 SpongeAPI 的一部分的接口来提供服务(如经济、Web 服务器等):
Sponge.getServiceManager().setProvider(Object plugin, Class<T> service, T provider);
provider
对象需要实现 service
对应的接口或类。
这样的 API 设计使得 Sponge 非常模块化。
備註
插件应该有不提供对应服务的选项,除非插件专用于某项功能。
示例:创建一个简单的用于标记地理位置的服务
虽然第一步是可选的,但我们十分建议你这么做。这一步就是指定你的服务类的接口的公开方法:
import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World;
import java.util.Optional;
public interface WarpService {
void setWarp(String name, Location<World> location);
Optional<Location<World>> getWarp(String name);
}
然后你就可以编写代码实现这一接口了:
import java.util.HashMap;
public class SimpleWarpService implements WarpService {
HashMap<String, Location<World>> warpMap = new HashMap<String, Location<World>>();
@Override
public Optional<Location<World>> getWarp(String name) {
if(!warpMap.containsKey(name)) {
return Optional.empty();
} else {
return Optional.of(warpMap.get(name));
}
}
@Override
public void setWarp(String name, Location<World> location) {
warpMap.put(name, location);
}
}
现在我们可以把一个崭新的实现注册进服务管理器中。我们把 WarpService.class
用做 service
的标记。
这样子其他的插件开发者就可以编写自己对于你的服务的实现(也就是实现了这一接口的对象),并且替换掉你的版本。
PluginContainer plugin = ...;
Sponge.getServiceManager().setProvider(plugin, WarpService.class, new SimpleWarpService());
其他的插件就可以通过服务管理器获取到你的服务了:
Sponge.getServiceManager().provide(WarpService.class);
小訣竅
如果你不想使用接口,只需要把 service
设置为你的类(作为示例,这里是 SimpleWarpService.class
)。