🔗 跨模组通信 API¶
通过 Pier,你的模组可以和服务器上任何语言写的模组对话;不是 Pier 模组的 LeviLamina 原生插件,也可以通过 bridge 加入进来。两边传的都是字符串,格式由你们约定(JSON、SNBT 都行),Pier 不看里面的内容。
| 形状 | 有回复吗 | 名字 | |
|---|---|---|---|
| 服务 | 一问一答 | 有 | 一个名字只能有一个提供者 |
| 总线 | 一个说,大家听 | 没有,但听众可以否决 | 谁都能订阅同一个主题 |
服务¶
提供一个服务¶
Rust:service::register(name, provider)
Go:levilamina.RegisterService(name, provider)
Zig:levilamina.registerService(name, provider)
- 参数:
- name : 字符串
服务名,建议加命名空间,比如plot:owner - provider : 函数
收到请求,返回回复;或者返回一个错误,错误信息会原样交给调用方,对方据此分清「没有这块地」和「数据库挂了」
- name : 字符串
- 返回值:服务的登记,留着它用来撤销
- 返回值类型:Rust
Result<Registration>,Go(*ServiceRegistration, error),Ziglevilamina.Error!ServiceRegistration- 提供函数运行在调用方的线程上。你的模组被禁用但还没卸载时,它仍然会被调用,因为别的模组可能在自己的加载阶段就要用你的服务。
- 对应槽位:
service_register -
示例:
- Rust
Rust - Go
Go - Zig
调用别人的服务¶
Rust:service::call(name, request)
Go:levilamina.CallService(name, request)
Zig:levilamina.callService(allocator, name, request)
- 参数:
- name : 字符串
服务名 - request : 字符串
请求内容
- name : 字符串
- 返回值:对方的回复
- 返回值类型:Rust
CallResult<String>,Go(string, error)(错误是*CallError),Ziglevilamina.Error!CallOutcome- 失败分四种:找不到(没人提供这个名字)、提供方拒绝(附带它给的原因)、宿主拒绝(名字不合法、调用了自己,或形成了循环)、不支持(这个 Pier 没有服务功能)。
- 对方没装也能工作的可选集成:Rust 用
service::call_optional,Go 用levilamina.CallServiceOptional。
- 对应槽位:
service_call -
示例:
- Rust
Rust - Go
Go - Zig
获取调用方¶
Rust:service::caller()
Go:levilamina.ServiceCaller()
Zig:levilamina.serviceCaller(allocator)
请求内容可以写任何东西。在提供函数里,向宿主询问正在运行的是哪个模组的调用。
- 返回值:调用方模组的名字。调用方是原生插件(通过 bridge)时为「没有」
- 返回值类型:Rust
Option<String>,Go(string, bool),Ziglevilamina.Error!?[]u8 - 对应槽位:
service_caller -
示例:
- Rust
Rust - Go
Go - Zig
Zig
总线¶
订阅一个主题¶
Rust:bus::subscribe(topic, handler)
Go:levilamina.BusSubscribe(topic, handler)
Zig:levilamina.busSubscribe(topic, handler)
- 参数:
- topic : 字符串
主题名,建议加命名空间,比如plot:enter - handler : 函数
收到消息时调用,运行在发布方的线程上。返回值是否决票:true表示反对,只有可否决的发布会看它
- topic : 字符串
- 返回值:订阅,留着它用来退订
- 返回值类型:Rust
Result<Subscription>,Go(*Subscription, error),Ziglevilamina.Error!Subscription- 订阅者崩溃(panic)时,Pier 按「没有意见」处理,这次发布照常进行。
- 对应槽位:
bus_subscribe -
示例:
- Rust
Rust - Go
Go - Zig
发布一条消息¶
Rust:bus::publish(topic, payload)
Go:levilamina.BusPublish(topic, payload)
Zig:levilamina.busPublish(topic, payload)
- 参数:
- topic : 字符串
主题名 - payload : 字符串
消息内容
- topic : 字符串
- 返回值:有多少订阅者收到了。返回 0 表示现在没人在听,发布本身是成功的
- 返回值类型:Rust
Result<u32>,Go(uint32, error),Ziglevilamina.Error!u32 - 对应槽位:
bus_publish -
示例:
- Rust
Rust - Go
Go - Zig
Zig
先问问大家同不同意¶
Rust:bus::publish_vetoable(topic, payload)
Go:levilamina.BusPublishVetoable(topic, payload)
Zig:levilamina.busPublishVetoable(topic, payload)
- 参数:
- topic : 字符串
主题名 - payload : 字符串
消息内容
- topic : 字符串
- 返回值:有没有人反对,以及有多少订阅者收到了
- 返回值类型:Rust
Result<Vetoable>,Go(Vetoable, error),Ziglevilamina.Error!Vetoable- 只要有一个订阅者返回
true,结果就是「被否决」;被否决后,其余订阅者照样会收到消息。
- 只要有一个订阅者返回
- 对应槽位:
bus_publish_vetoable -
示例:
- Rust
- Go
Go - Zig