feat(sdk): 迁移脚本执行系统与编辑器热更新对齐 Astral
- Viewer.ts: enableScript setter 修复写回 options,脚本状态变量改为实例级 - Viewer.ts: 新增 InstallScriptsOptions、reinstallObjectScripts、invokeInstalledScriptEvent - Viewer.ts: installScripts 支持 loadedScriptNames 精准触发 loaded,补充 bindDataChange 分发 - Viewer.ts: unInstallScripts 移除错误的 enableScript 提前返回守卫 - Signals.ts: 脚本信号统一改用 reinstallObjectScripts 热更新 - Signals.ts: sceneCleared 先卸载脚本再清场 - Signals.ts: registerSignal/dispose 模式防止信号泄漏 - CodeEditor.vue: Monaco 忽略 TS80002(构造函数转 class 建议)
This commit is contained in:
@@ -2,15 +2,21 @@ import * as THREE from "three";
|
||||
import {RoomEnvironment} from "three/examples/jsm/environments/RoomEnvironment.js";
|
||||
import {ShaderPass} from "three/examples/jsm/postprocessing/ShaderPass.js";
|
||||
import {Effect} from "./Effect";
|
||||
import {useAddSignal} from "@/hooks";
|
||||
import {useAddSignal, useRemoveSignal} from "@/hooks";
|
||||
import Viewer from "../Viewer";
|
||||
import App from "@/core/app/App";
|
||||
import {focusObject} from "@/utils/scene/controls.ts";
|
||||
|
||||
type SignalListenerRecord = {
|
||||
name: string;
|
||||
listener: (...params: any[]) => void;
|
||||
};
|
||||
|
||||
export class Signals {
|
||||
private readonly viewer: Viewer;
|
||||
|
||||
private useBackgroundAsEnvironment = false;
|
||||
private readonly signalListeners: SignalListenerRecord[] = [];
|
||||
|
||||
constructor(viewer:Viewer) {
|
||||
this.viewer = viewer;
|
||||
@@ -18,41 +24,46 @@ export class Signals {
|
||||
this.init();
|
||||
}
|
||||
|
||||
private registerSignal(name: string, listener: (...params: any[]) => void) {
|
||||
this.signalListeners.push({ name, listener });
|
||||
useAddSignal(name, listener);
|
||||
}
|
||||
|
||||
init() {
|
||||
useAddSignal("sceneCleared", this.sceneCleared.bind(this));
|
||||
useAddSignal("transformModeChanged", this.transformModeChanged.bind(this));
|
||||
useAddSignal("snapChanged", this.snapChanged.bind(this));
|
||||
useAddSignal("spaceChanged", this.spaceChanged.bind(this));
|
||||
useAddSignal("effectEnabledChange", this.effectEnabledChange.bind(this));
|
||||
this.registerSignal("sceneCleared", this.sceneCleared.bind(this));
|
||||
this.registerSignal("transformModeChanged", this.transformModeChanged.bind(this));
|
||||
this.registerSignal("snapChanged", this.snapChanged.bind(this));
|
||||
this.registerSignal("spaceChanged", this.spaceChanged.bind(this));
|
||||
this.registerSignal("effectEnabledChange", this.effectEnabledChange.bind(this));
|
||||
|
||||
useAddSignal("rendererUpdated", this.rendererUpdated.bind(this));
|
||||
useAddSignal("rendererCreated", this.rendererCreated.bind(this));
|
||||
useAddSignal("rendererConfigUpdate", this.rendererConfigUpdate.bind(this));
|
||||
useAddSignal("rendererDetectKTX2Support", this.rendererDetectKTX2Support.bind(this));
|
||||
this.registerSignal("rendererUpdated", this.rendererUpdated.bind(this));
|
||||
this.registerSignal("rendererCreated", this.rendererCreated.bind(this));
|
||||
this.registerSignal("rendererConfigUpdate", this.rendererConfigUpdate.bind(this));
|
||||
this.registerSignal("rendererDetectKTX2Support", this.rendererDetectKTX2Support.bind(this));
|
||||
|
||||
useAddSignal("sceneBackgroundChanged", this.sceneBackgroundChanged.bind(this));
|
||||
useAddSignal("sceneEnvironmentChanged", this.sceneEnvironmentChanged.bind(this));
|
||||
useAddSignal("sceneGraphChanged", this.sceneGraphChanged.bind(this));
|
||||
useAddSignal("cameraChanged", this.cameraChanged.bind(this));
|
||||
useAddSignal("cameraReset", this.viewer.updateAspectRatio.bind(this.viewer));
|
||||
useAddSignal("viewportCameraChanged", this.viewportCameraChanged.bind(this));
|
||||
useAddSignal("viewportShadingChanged", this.viewportShadingChanged.bind(this));
|
||||
this.registerSignal("sceneBackgroundChanged", this.sceneBackgroundChanged.bind(this));
|
||||
this.registerSignal("sceneEnvironmentChanged", this.sceneEnvironmentChanged.bind(this));
|
||||
this.registerSignal("sceneGraphChanged", this.sceneGraphChanged.bind(this));
|
||||
this.registerSignal("cameraChanged", this.cameraChanged.bind(this));
|
||||
this.registerSignal("cameraReset", this.viewer.updateAspectRatio.bind(this.viewer));
|
||||
this.registerSignal("viewportCameraChanged", this.viewportCameraChanged.bind(this));
|
||||
this.registerSignal("viewportShadingChanged", this.viewportShadingChanged.bind(this));
|
||||
|
||||
useAddSignal("objectSelected", this.objectSelected.bind(this));
|
||||
useAddSignal("objectFocused", this.objectFocused.bind(this));
|
||||
useAddSignal("objectAdded", this.objectAdded.bind(this));
|
||||
useAddSignal("objectChanged", this.objectChanged.bind(this));
|
||||
useAddSignal("objectRemoved", this.objectRemoved.bind(this));
|
||||
this.registerSignal("objectSelected", this.objectSelected.bind(this));
|
||||
this.registerSignal("objectFocused", this.objectFocused.bind(this));
|
||||
this.registerSignal("objectAdded", this.objectAdded.bind(this));
|
||||
this.registerSignal("objectChanged", this.objectChanged.bind(this));
|
||||
this.registerSignal("objectRemoved", this.objectRemoved.bind(this));
|
||||
|
||||
useAddSignal("geometryChanged", this.geometryChanged.bind(this));
|
||||
useAddSignal("materialChanged", this.materialChanged.bind(this));
|
||||
this.registerSignal("geometryChanged", this.geometryChanged.bind(this));
|
||||
this.registerSignal("materialChanged", this.materialChanged.bind(this));
|
||||
|
||||
useAddSignal("sceneResize", this.sceneResize.bind(this));
|
||||
useAddSignal("showGridChanged", this.showGridChanged.bind(this));
|
||||
this.registerSignal("sceneResize", this.sceneResize.bind(this));
|
||||
this.registerSignal("showGridChanged", this.showGridChanged.bind(this));
|
||||
|
||||
useAddSignal("scriptAdded",this.scriptAdded.bind(this));
|
||||
useAddSignal("scriptRemoved",this.scriptRemoved.bind(this));
|
||||
useAddSignal("scriptChanged",this.scriptChanged.bind(this));
|
||||
this.registerSignal("scriptAdded",this.scriptAdded.bind(this));
|
||||
this.registerSignal("scriptRemoved",this.scriptRemoved.bind(this));
|
||||
this.registerSignal("scriptChanged",this.scriptChanged.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,6 +77,8 @@ export class Signals {
|
||||
* 清空
|
||||
*/
|
||||
sceneCleared() {
|
||||
this.viewer.unInstallScripts();
|
||||
|
||||
this.viewer.modules.controls.setTarget(0, 0, 0,true);
|
||||
this.viewer.pathtracer?.reset();
|
||||
|
||||
@@ -453,15 +466,29 @@ export class Signals {
|
||||
/**
|
||||
* 添加脚本
|
||||
*/
|
||||
scriptAdded(object:THREE.Object3D, _:ISceneScript){
|
||||
this.viewer.installScripts([object.uuid]);
|
||||
scriptAdded(object:THREE.Object3D, sc:ISceneScript){
|
||||
if (!object?.uuid || !sc?.name) return;
|
||||
|
||||
try {
|
||||
this.viewer.reinstallObjectScripts(object.uuid, [sc.name]);
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
App.log.error(`[Script] 热安装脚本 ${sc.name} 失败: ${message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除脚本
|
||||
*/
|
||||
scriptRemoved(object:THREE.Object3D, sc:ISceneScript){
|
||||
this.viewer.uninstallScriptsByUuid(object.uuid,sc.name);
|
||||
if (!object?.uuid) return;
|
||||
|
||||
try {
|
||||
this.viewer.reinstallObjectScripts(object.uuid);
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
App.log.error(`[Script] 卸载脚本 ${sc?.name || "unknown"} 失败: ${message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -469,8 +496,14 @@ export class Signals {
|
||||
*/
|
||||
scriptChanged(attributeName:string,object:THREE.Object3D, sc:ISceneScript){
|
||||
if(attributeName !== "source") return;
|
||||
if (!object?.uuid || !sc?.name) return;
|
||||
|
||||
this.viewer.installScripts([object.uuid],sc.name);
|
||||
try {
|
||||
this.viewer.reinstallObjectScripts(object.uuid, [sc.name]);
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
App.log.error(`[Script] 热更新脚本 ${sc.name} 失败: ${message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -479,4 +512,11 @@ export class Signals {
|
||||
render(){
|
||||
this.viewer.render();
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this.signalListeners.forEach(({ name, listener }) => {
|
||||
useRemoveSignal(name, listener);
|
||||
});
|
||||
this.signalListeners.length = 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user