import Check from "@lijuhong1981/jscheck/src/Check.js";
import { defined } from "@lijuhong1981/jscheck/src/isDefined.js";
import EventSubscriber from "@lijuhong1981/jsevents/src/EventSubscriber.js";
import { Node } from "three/webgpu";
import PostProcessingLibrary from "./PostProcessingLibrary.js";
/**
* PassNodeProxy是一个针对Node节点对象的代理类,用于管理threejs最新tsl体系下的Node节点对象,对外提供更加友好的接口。
* @template T extends Node
* @class
* @abstract
*/
class PassNodeProxy {
/**
* 构造函数
* @param {PostProcessingLibrary} library - 后处理库实例
* @constructor
*/
constructor(library) {
Check.defined('library', library);
/**
* 后处理库实例
* @type {PostProcessingLibrary}
* @readonly
*/
this.library = library;
/**
* Pass节点,由子类在构建完成后赋值给该属性。
* @type {T}
* @readonly
*/
this.node = undefined;
/**
* 属性值变化事件,当Pass节点的属性值发生变化时触发。
* @type {EventSubscriber}
* @readonly
*/
this.changed = new EventSubscriber();
this._enabled = false;
}
/**
* 批量设置Pass节点的属性值。
* @param {Object} values - 包含属性键值对的对象
* @returns {PassNodeProxy} - 返回当前实例
*/
setValues(values) {
Check.defined('values', values);
for (const key in values) {
if (key in this) {
if (typeof this[key].setValues === 'function')
this[key].setValues(values[key]);
else
this[key] = values[key];
}
}
return this;
}
/**
* 是否启用该Pass。
* @type {boolean}
* @default false
*/
set enabled(value) {
Check.typeOf.boolean('enabled', value);
if (this._enabled === value) return;
this._enabled = value;
this.changed.raiseEvent('enabled', value);
}
get enabled() {
return this._enabled;
}
/**
* Pass节点是否已经构建完成。
* @type {boolean}
* @readonly
*/
get isBuilt() {
return defined(this.node);
}
/**
* 检查Pass节点是否已经构建完成,如果未构建则抛出错误。
* @throws {Error}
*/
checkBuilt() {
if (!this.isBuilt) {
throw new Error('Pass节点尚未构建');
}
}
/**
* 构建输出节点,由子类实现该方法。
* @param {...any} args - 构建参数
* @returns {Node} - 处理后的节点对象
*/
build(...args) {
throw new Error('build方法需要由子类实现');
}
/**
* 重新构建Pass节点,先销毁原有节点再调用build方法进行构建。
* @param {...any} args - 构建参数
* @returns {Node} - 处理后的节点对象
*/
rebuild(...args) {
this.dispose();
return this.build(...args);
}
/**
* 销毁Pass节点,释放相关资源。
* @return {PassNodeProxy} - 返回当前实例
*/
dispose() {
this.node && this.node.dispose();
return this;
}
};
export default PassNodeProxy;
export { PassNodeProxy };