-
Notifications
You must be signed in to change notification settings - Fork 68
插件机制
[TOC]
AVG.js 的插件系统使用信号(Signals)供外部调用。
信号机制只是 AVG.js 中的订阅/发布模式的名称,与其他程序库的同名概念(如 Qt 的信号)并不相同。信号与一般概念上的事件机制十分相似,都由订阅和发布两个部分组成。不同的是,AVG.js 的信号系统采用了 koa2 的中间件模型,每一个发布出去的「信号」等同于网络访问中的一个请求,而插件系统则是信号的监听和处理者(中间件),中间件的执行顺序采用「洋葱」形式,后面会对其优点进行详细解释。
import { core } from 'avg-core';
// 监听一个信号
core.use('signal-name', async (ctx, next) => {
// do something...
console.log(ctx.hello);
console.log(1);
await next();
// do something else...
console.log(4);
});
// 第二处监听
core.use('signal-name', async (ctx, next) => {
console.log(2)
await next();
console.log(3)
});
// 发送一个信号
core.post('signal-name', { hello: 'world!' });
发送信号后,控制台将打印:
world!
1
2
3
发送信号时 .post()
方法的第二个参数可以为空,即传输一个空的 ctx = {}
。
中间件将按照监听(即执行 .use()
方法)的顺序按照洋葱方式逐层执行。
AVG.js 提供了一些默认的信号供使用,同时,在你制定自己的信号名时,注意不要与他们重复。原则上,为了风格统一,我们建议使用全小写字母和短线分隔的方式命名信号,如 my-signal
,save-archive
。
用于传递剧情脚本内容。各个功能模块必须监听此信号才能获取到脚本内容。
// 背景音乐模块处理 [bgm ...] 形式的脚本行
core.use('script-exec', async (ctx, next) => {
const { command, flags, params } = ctx;
if (command === 'bgm') {
// play sound
}
await next();
});
该信号通常由脚本模块触发,在 AVG.js 默认配置中,该信号由 Storyscript 模块解析脚本后发送。
注:当脚本处在 Auto 或 Skip 模式时,会自动包含 _auto_
或 _skip_
flag。
脚本触发信号,该信号用于通知脚本模块发送下一行脚本的 script-exec
信号。如可监听全局点击、空格键按下等事件,令其发送 script-trigger
信号。
有时我们需要「打断」功能,如点击鼠标跳过当前场景变换或点击鼠标立即完成文本打印,也可以监听 script-trigger
信号,此时不要执行 await next()
。
标记脚本及资源开始加载,可监听此信号以启动 Loading 画面
通知脚本及资源加载进度,传递的 context 对象为当前使用的 PIXI Resources Loader 实例。
通知脚本及资源加载完成,可监听此信号以关闭 Loading 画面
通知脚本模块开启 Auto 或 Skip 模式,如 core.post('script-mode', { mode: 'skip' })
为开启 Skip 模式。
Auto 或 Skip 模式将在下次 script-trigger
消息投递时终止。
设置/获取 Auto 模式的等待时间,即每句话打印完成后等待多少毫秒打印下一句话,设置和获取都通过 ctx.autoInterval
值为数字,单位是毫秒。
存档信号,只用于向各个功能模块收取要存储的数据,并不负责实际的存储功能。
只包含脚本位置和存档变量、处于生命周期中的临时变量,不存储全局存档变量,下同。
// 在 bgm 模块中监听
core.use('save-archive', async (ctx, next) => {
ctx.data.bgm = { ...要存储的状态信息 }
await next();
});
// 发送信号
core.post('save-archive', { name: 'save-1', extra: { 任意的额外数据,如预览图和预览文本 } });
该信号可在任何时候发出,如在存档界面点击存档按钮时。
前面提到,该信号不包含数据的存储功能,数据存储功能将由存储插件提供,存储插件中包含对该信号的监听,会自动将数据存入。AVG.js 默认配置中,将自动存储到浏览器存储(Localstorage/IndexesDB)中,下同。
读取信号,只用于向各个功能模块分发之前存储的数据,并不负责实际的读取功能。
// 发送信号
core.post('load-archive', { name: 'save-1' });
// 在 bgm 模块中监听
core.use('load-archive', async (ctx, next) => {
// 还原状态信息
restore(ctx.data.bgm);
console.log(ctx.time); // 打印存档时间
console.log(ctx.extra) // 打印额外数据
await next();
});
该信号可在任何时候发出,如在存档界面点击读取按钮时。
删除特定名称的存档,名称通过 ctx.name
传递。
判断特定名称的存档是否存在,名称通过 ctx.name
传递,结果通过 ctx.exist
返回。
列出当前的存档名列表,以数组的形式在 ctx.list
中返回。
获取存档列表及存档信息(存档时间和额外数据),供存档界面等使用。
数据在 ctx.infos
中返回,格式如:
{
"save-1": {
"time": 1485927056049,
"extra": { ... }
}
}
存储全局存档变量,该信号应该由脚本模块发出,由存储模块处理。变量表通过 ctx.globalData
传递,下同。
读取全局存档变量,该信号应该由脚本模块发出,由存储模块处理。
流程控制功能的初始化信号,为脚本系统提供 [flow wait time=1000]
等功能。
AVG.js 默认的存储插件初始化信号。
AVG.js 默认的脚本插件初始化信号。
AVG.js 默认的音频播放插件初始化信号,为脚本系统提供声音播放等功能。
截屏插件初始化信号。
截屏信号,可传递参数
{
// 返回的格式,备选:canvas, image, pixels,分别为 Canvas 对象,Image 对象,ArrayBuffer,默认为 Base64 字符串
type: 'base64',
// 截屏缩放尺寸,默认为不缩放(画面尺寸)
width: 800,
height: 600,
// 名称,指定名称可缓存多个截图在内存中,默认名为 default
name: 'default'
}
数据通过 ctx.data
返回,格式为参数规定的格式。
获取之前的截屏对象,通过 ctx.name
指定名称,通过 ctx.data
返回。
目前对插件的格式、引入方式没有统一要求,只要符合解耦的原则,正确使用信号机制即可。