处理循环引用的obj

This commit is contained in:
xu_yanfeng 2025-01-07 18:28:15 +08:00
parent 16e1fdf89f
commit f51162db06
4 changed files with 59 additions and 10 deletions

View File

@ -1,7 +1,7 @@
// eval 注入脚本的代码,变量尽量使用var,后来发现在import之后,let会自动变为var
import { uniq } from "lodash";
import { debugLog, Msg, PluginEvent, RequestLogData, RequestNodeInfoData, RequestSetPropertyData, ResponseNodeInfoData, ResponseSetPropertyData, ResponseSupportData, ResponseTreeInfoData } from "../../core/types";
import { ArrayData, BoolData, ColorData, DataType, EngineData, Group, ImageData, Info, InvalidData, NodeInfoData, NumberData, ObjectData, Property, StringData, TreeData, Vec2Data, Vec3Data, Vec4Data } from "../../views/devtools/data";
import { ArrayData, BoolData, ColorData, DataType, EngineData, Group, ImageData, Info, InvalidData, NodeInfoData, NumberData, ObjectCircleData, ObjectData, Property, StringData, TreeData, Vec2Data, Vec3Data, Vec4Data } from "../../views/devtools/data";
import { InjectEvent } from "./event";
import { getValue, trySetValueWithConfig } from "./setValue";
import { BuildArrayOptions, BuildImageOptions, BuildObjectOptions, BuildVecOptions } from "./types";
@ -421,11 +421,18 @@ export class Inspector extends InjectEvent {
}
if (typeof propertyValue === "object") {
// 空{} MaterialVariant 2.4.0
info = this._buildObjectData({
data: new ObjectData(),
path: path,
value: propertyValue,
});
try {
JSON.stringify(propertyValue);
info = this._buildObjectData({
data: new ObjectData(),
path: path,
value: propertyValue,
});
} catch {
// Object存在循环引用的情况
info = new ObjectCircleData();
}
if (info) {
return make(info);
}

View File

@ -14,7 +14,7 @@ export enum DataType {
Invalid = "Invalid",
Array = "Array", // 暂时在控制台打印下
Object = "Object",
ObjectItem = "ObjectItem",
ObjectCircle = "ObjectCircle",
Image = "Image", // 图片
Engine = "Engine", // 引擎的类型cc.Node, cc.Sprite, cc.Label等。。。
}
@ -72,6 +72,9 @@ export class Info {
public isObject(): boolean {
return false;
}
public isObjectCircle(): boolean {
return false;
}
public isImage(): boolean {
return false;
}
@ -203,6 +206,19 @@ export class ArrayData extends Info {
return true;
}
}
export class ObjectCircleData extends Info {
constructor() {
super();
this.type = DataType.ObjectCircle;
}
parse(data: ObjectCircleData) {
super.parse(data);
return this;
}
public isObjectCircle(): boolean {
return true;
}
}
export class ObjectData extends Info {
/**
* object无限递归的情况
@ -553,7 +569,9 @@ export class Property {
case DataType.Invalid:
this.value = new InvalidData(data.value).parse(data.value as InvalidData);
break;
case DataType.ObjectItem:
case DataType.ObjectCircle:
this.value = new ObjectCircleData().parse(data.value as ObjectCircleData);
break;
default:
throw new Error(`not support type: ${typeof data === "string" ? data : JSON.stringify(data)}`);
}

View File

@ -1,7 +1,7 @@
import { v4 } from "uuid";
import { Msg, Page, PluginEvent, RequestNodeInfoData, ResponseNodeInfoData, ResponseSupportData, ResponseTreeInfoData } from "../../../core/types";
import { VisibleProp } from "../comp";
import { ArrayData, BoolData, ColorData, EngineData, EnumData, Group, ImageData, Info, InvalidData, NodeInfoData, NumberData, ObjectData, Property, StringData, TextData, TreeData, Vec2Data, Vec3Data, Vec4Data } from "../data";
import { ArrayData, BoolData, ColorData, EngineData, EnumData, Group, ImageData, Info, InvalidData, NodeInfoData, NumberData, ObjectCircleData, ObjectData, Property, StringData, TextData, TreeData, Vec2Data, Vec3Data, Vec4Data } from "../data";
export class TestClient {
recv(event: PluginEvent) {}
}
@ -107,6 +107,10 @@ export class TestServer {
.buildChild("obj") //
.buildComponent("group-obj")
.buildProperty("object", new ObjectData().testNormal()); //
this.testData
.buildChild("obj-circle")
.buildComponent("group-obj-circle") //
.buildProperty("circle", new ObjectCircleData());
this.testData
.buildChild("arr[arr]")

View File

@ -18,6 +18,7 @@
<Engine v-if="value.isEngine()" v-model:data="(value as EngineData)"> </Engine>
<div v-if="value.isObject() && !expand" class="objectDesc"></div>
<div v-if="value.isArray()" class="array">Array[{{ value.data.length }}]</div>
<div v-if="value.isObjectCircle()" class="circle-obj" @click="onLogToConsole">circle object can't display, click to log in console</div>
</div>
</CCProp>
<div v-if="value && value.isArrayOrObject()">
@ -32,7 +33,7 @@
import ccui from "@xuyanfeng/cc-ui";
import { Option } from "@xuyanfeng/cc-ui/types/cc-select/const";
import { defineComponent, onMounted, PropType, ref, toRaw, watch } from "vue";
import { Msg, RequestSetPropertyData } from "../../../core/types";
import { Msg, RequestLogData, RequestSetPropertyData } from "../../../core/types";
import { bridge } from "../bridge";
import { ArrayData, EngineData, EnumData, ImageData, Info, NumberData, ObjectData, Property, StringData, TextData, Vec2Data, Vec3Data } from "../data";
import Engine from "./property-engine.vue";
@ -139,6 +140,10 @@ export default defineComponent({
bridge.send(Msg.RequestSetProperty, raw as RequestSetPropertyData);
}
},
onLogToConsole() {
const data = toRaw(props.value.path);
bridge.send(Msg.RequestLogData, data as RequestLogData);
},
};
},
});
@ -178,6 +183,21 @@ export default defineComponent({
color: #d2d2d2;
font-size: 12px;
}
.circle-obj {
user-select: none;
cursor: pointer;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 12px;
color: gray;
&:hover {
color: white;
}
&:active {
color: chocolate;
}
}
.vec {
width: 100%;