feat: 流式加载器 & fix: gl2 注释

This commit is contained in:
unanmed 2025-01-13 16:38:28 +08:00
parent 6dde0334e1
commit 231a72e78c
3 changed files with 94 additions and 2 deletions

View File

@ -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>(

View File

@ -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>
);
});

View 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));
}
}