mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-01-18 20:09:27 +08:00
feat: 流式加载器 & fix: gl2 注释
This commit is contained in:
parent
6dde0334e1
commit
231a72e78c
@ -1531,7 +1531,7 @@ export class GL2Program extends EventEmitter<ShaderProgramEvent> {
|
||||
/**
|
||||
* 定义一个 attribute 常量,并存入本着色器程序的 attribute 常量映射,在 es 300 版本中叫做 in
|
||||
* @param attrib attribute 常量名
|
||||
* @param type attribute 类型,可选 {@link Shader.Attrib1f} 至 {@link Shader.AttribI4uiv}
|
||||
* @param type attribute 类型,可选 {@link GL2.ATTRIB_1f} 至 {@link GL2.ATTRIB_I4uiv}
|
||||
* @returns attribute 常量的操作对象,可用于设置其值
|
||||
*/
|
||||
defineAttribute<T extends AttribType>(
|
||||
|
@ -69,7 +69,6 @@ Mota.require('var', 'loading').once('coreInit', () => {
|
||||
</layer-group>
|
||||
<Textbox id="main-textbox" {...mainTextboxProps}></Textbox>
|
||||
<FloorChange id="floor-change" zIndex={50}></FloorChange>
|
||||
<icon icon={13} animate></icon>
|
||||
</container>
|
||||
);
|
||||
});
|
||||
|
93
src/module/loader/stream.ts
Normal file
93
src/module/loader/stream.ts
Normal file
@ -0,0 +1,93 @@
|
||||
import { logger } from '@/core/common/logger';
|
||||
import EventEmitter from 'eventemitter3';
|
||||
|
||||
export interface IStreamController<T = void> {
|
||||
/**
|
||||
* 开始流传输
|
||||
*/
|
||||
start(): Promise<T>;
|
||||
|
||||
/**
|
||||
* 主动终止流传输
|
||||
* @param reason 终止原因
|
||||
*/
|
||||
cancel(reason?: string): void;
|
||||
}
|
||||
|
||||
export interface IStreamReader<T = any> {
|
||||
/**
|
||||
* 接受字节流流传输的数据
|
||||
* @param data 传入的字节流数据,只包含本分块的内容
|
||||
* @param done 是否传输完成
|
||||
*/
|
||||
pump(data: Uint8Array | undefined, done: boolean): void;
|
||||
|
||||
/**
|
||||
* 开始流传输
|
||||
* @param stream 传输流对象
|
||||
* @param controller 传输流控制对象
|
||||
*/
|
||||
start(stream: ReadableStream, controller: IStreamController<T>): void;
|
||||
|
||||
/**
|
||||
* 结束流传输
|
||||
* @param done 是否传输完成,如果为 false 的话,说明可能是由于出现错误导致的终止
|
||||
* @param reason 如果没有传输完成,那么表示失败的原因
|
||||
*/
|
||||
end(done: boolean, reason?: string): void;
|
||||
}
|
||||
|
||||
interface StreamLoaderEvent {
|
||||
data: [data: Uint8Array | undefined, done: boolean];
|
||||
}
|
||||
|
||||
export class StreamLoader
|
||||
extends EventEmitter<StreamLoaderEvent>
|
||||
implements IStreamController<void>
|
||||
{
|
||||
/** 传输目标 */
|
||||
private target: Set<IStreamReader> = new Set();
|
||||
/** 读取流对象 */
|
||||
private stream?: ReadableStream;
|
||||
|
||||
constructor(public readonly url: string) {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将加载流传递给字节流读取对象
|
||||
* @param reader 字节流读取对象
|
||||
*/
|
||||
pipe(reader: IStreamReader) {
|
||||
this.target.add(reader);
|
||||
return this;
|
||||
}
|
||||
|
||||
async start() {
|
||||
const response = await window.fetch(this.url);
|
||||
const stream = response.body;
|
||||
if (!stream) {
|
||||
logger.error(23);
|
||||
return;
|
||||
}
|
||||
// 获取读取器
|
||||
this.stream = stream;
|
||||
const reader = response.body?.getReader();
|
||||
this.target.forEach(v => v.start(stream, this));
|
||||
|
||||
// 开始流传输
|
||||
while (true) {
|
||||
const { value, done } = await reader.read();
|
||||
this.target.forEach(v => v.pump(value, done));
|
||||
if (done) break;
|
||||
}
|
||||
|
||||
this.target.forEach(v => v.end(true));
|
||||
}
|
||||
|
||||
cancel(reason?: string) {
|
||||
if (!this.stream) return;
|
||||
this.stream.cancel(reason);
|
||||
this.target.forEach(v => v.end(false, reason));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user