服务

几乎一切(事件,权限等)都是通过服务(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 的标记。

这样子其他的插件开发者就可以编写自己对于你的服务的实现(也就是实现了这一接口的对象),并且替换掉你的版本。

Sponge.getServiceManager().setProvider(plugin, WarpService.class, new SimpleWarpService());

其他的插件就可以通过服务管理器获取到你的服务了:

Sponge.getServiceManager().provide(WarpService.class);

小技巧

如果你不想使用接口,只需要把 service 设置为你的类(作为示例,这里是 SimpleWarpService.class )。