mirror of
https://gitee.com/dgflash/oops-plugin-framework.git
synced 2026-05-13 09:14:50 +08:00
2. 存储模块性能提升,添加LRU缓存、批量操作支持,优化内存使用 3. 多语言模块性能与内存管理优化,组件查询性能提升 4. 时间模块类型安全与性能优化,使用泛型替代any,对象池机制减少内存分配 5. 事件系统修复双重注册、重复注册等严重问题,实现EventData对象池减少GC压力 6. RandomManager修复4个逻辑BUG,包括边界问题和越界问题 7. 音频模块内存与性能优化,避免重复加载,优化数据结构,添加完整清理机制 8. CCView与CCViewVM合并,支持按需启用MVVM 9. Collection模块优化,AsyncQueue添加队列容量限制,Collection查询性能提升 10. ECS系统全面优化,对象池复用减少内存分配,循环性能提升 11. 优化MVVM组件性能
320 lines
9.5 KiB
TypeScript
320 lines
9.5 KiB
TypeScript
import type { Color } from 'cc';
|
||
import { Button, CCInteger, Enum, Node, Sprite, UIOpacity, UIRenderer, _decorator, color } from 'cc';
|
||
import { VMBase } from './VMBase';
|
||
import { VM } from './ViewModel';
|
||
|
||
const { ccclass, property, menu, help } = _decorator;
|
||
|
||
/** 比较条件 */
|
||
enum CONDITION {
|
||
'==', // 正常计算,比较 等于
|
||
'!=', // 正常计算,比较 不等于
|
||
'>', // 正常计算,比较>
|
||
'>=', // 正常计算,比较>=
|
||
'<', // 正常计算,比较<
|
||
'<=', // 正常计算,比较>=
|
||
'range' // 计算在范围内
|
||
}
|
||
|
||
enum ACTION {
|
||
NODE_ACTIVE, // 满足条件的节点激活,不满足的不激活(只对子节点的激活有效果,当前节点active = false时,组件就失去效果了,如果设置当前节点可用NODE_VISIBLE代替)
|
||
NODE_VISIBLE, // 满足条件的节点显示,不满足的不显示
|
||
NODE_OPACITY, // 满足条件的节点改变不透明度,不满足的还原255
|
||
NODE_COLOR, // 满足条件的节点改变颜色,不满足的恢复白色
|
||
COMPONENT_CUSTOM, // 自定义控制组件模式
|
||
SPRITE_GRAYSCALE, // 满足条件的节点cc.Sprite组件,纹理变黑白
|
||
BUTTON_INTERACTABLE, // 满足条件的节点cc.BUTTON组件,
|
||
}
|
||
|
||
enum CHILD_MODE_TYPE {
|
||
NODE_INDEX,
|
||
NODE_NAME
|
||
}
|
||
|
||
/**
|
||
* [VM-State]
|
||
* 监听数值状态,根据数值条件设置节点是否激活
|
||
*/
|
||
@ccclass
|
||
@menu('OopsFramework/Mvvm/VM-State (状态控制)')
|
||
@help('https://gitee.com/dgflash/oops-framework/wikis/pages?sort_id=12037846&doc_id=2873565')
|
||
export default class VMState extends VMBase {
|
||
@property
|
||
watchPath = '';
|
||
|
||
@property({
|
||
tooltip: '遍历子节点,根据子节点的名字或名字转换为值,判断值满足条件 来激活'
|
||
})
|
||
foreachChildMode = false;
|
||
|
||
@property({
|
||
type: Enum(CONDITION),
|
||
})
|
||
condition: CONDITION = CONDITION['=='];
|
||
|
||
@property({
|
||
type: Enum(CHILD_MODE_TYPE),
|
||
tooltip: '遍历子节点,根据子节点的名字转换为值,判断值满足条件 来激活',
|
||
visible: function () {
|
||
// @ts-ignore
|
||
return this.foreachChildMode === true;
|
||
}
|
||
})
|
||
foreachChildType: CHILD_MODE_TYPE = CHILD_MODE_TYPE.NODE_INDEX;
|
||
|
||
@property({
|
||
displayName: 'Value: a',
|
||
visible: function () {
|
||
// @ts-ignore
|
||
return this.foreachChildMode === false;
|
||
}
|
||
})
|
||
valueA = 0;
|
||
|
||
@property({
|
||
displayName: 'Value: b',
|
||
visible: function () {
|
||
// @ts-ignore
|
||
return this.foreachChildMode === false && this.condition === CONDITION.range;
|
||
}
|
||
})
|
||
valueB = 0;
|
||
|
||
@property({
|
||
type: Enum(ACTION),
|
||
tooltip: '一旦满足条件就对节点执行操作'
|
||
})
|
||
valueAction: ACTION = ACTION.NODE_ACTIVE;
|
||
|
||
@property({
|
||
visible: function () {
|
||
// @ts-ignore
|
||
return this.valueAction === ACTION.NODE_OPACITY;
|
||
},
|
||
range: [0, 255],
|
||
type: CCInteger,
|
||
displayName: 'Action Opacity'
|
||
})
|
||
valueActionOpacity = 0;
|
||
|
||
@property({
|
||
visible: function () {
|
||
// @ts-ignore
|
||
return this.valueAction === ACTION.NODE_COLOR;
|
||
},
|
||
displayName: 'Action Color'
|
||
})
|
||
valueActionColor: Color = color(155, 155, 155);
|
||
|
||
@property({
|
||
visible: function () {
|
||
// @ts-ignore
|
||
return this.valueAction === ACTION.COMPONENT_CUSTOM;
|
||
},
|
||
displayName: 'Component Name'
|
||
})
|
||
valueComponentName = '';
|
||
|
||
@property({
|
||
visible: function () {
|
||
// @ts-ignore
|
||
return this.valueAction === ACTION.COMPONENT_CUSTOM;
|
||
},
|
||
displayName: 'Component Property'
|
||
})
|
||
valueComponentProperty = '';
|
||
|
||
@property({
|
||
visible: function () {
|
||
// @ts-ignore
|
||
return this.valueAction === ACTION.COMPONENT_CUSTOM;
|
||
},
|
||
displayName: 'Default Value'
|
||
})
|
||
valueComponentDefaultValue = '';
|
||
|
||
@property({
|
||
visible: function () {
|
||
// @ts-ignore
|
||
return this.valueAction === ACTION.COMPONENT_CUSTOM;
|
||
},
|
||
displayName: 'Action Value'
|
||
})
|
||
valueComponentActionValue = '';
|
||
|
||
@property({
|
||
type: [Node],
|
||
tooltip: '需要执行条件的节点,如果不填写则默认会执行本节点以及本节点的所有子节点 的状态'
|
||
})
|
||
watchNodes: Node[] = [];
|
||
|
||
// 缓存动态添加的组件,用于销毁时清理
|
||
private _addedComponents: Map<Node, UIOpacity> = new Map();
|
||
|
||
onLoad() {
|
||
super.onLoad();
|
||
// 如果数组里没有监听值,那么默认把所有子节点给监听了
|
||
if (this.watchNodes.length == 0) {
|
||
if (this.valueAction !== ACTION.NODE_ACTIVE && this.foreachChildMode === false) {
|
||
this.watchNodes.push(this.node);
|
||
}
|
||
this.watchNodes = this.watchNodes.concat(this.node.children);
|
||
}
|
||
}
|
||
|
||
start() {
|
||
if (this.enabled) {
|
||
this.onValueInit();
|
||
}
|
||
}
|
||
|
||
// 当值初始化时
|
||
protected onValueInit() {
|
||
const value = VM.getValue(this.watchPath);
|
||
this.checkNodeFromValue(value);
|
||
}
|
||
|
||
// 当值被改变时
|
||
protected onValueChanged(newVar: any, oldVar: any, pathArr: any[]) {
|
||
this.checkNodeFromValue(newVar);
|
||
}
|
||
|
||
// 检查节点值更新
|
||
private checkNodeFromValue(value: any) {
|
||
if (this.foreachChildMode) {
|
||
this.watchNodes.forEach((node, index) => {
|
||
const v = (this.foreachChildType === CHILD_MODE_TYPE.NODE_INDEX) ? index : node.name;
|
||
const check = this.conditionCheck(value, v);
|
||
// log('遍历模式', value, node.name, check);
|
||
this.setNodeState(node, check);
|
||
});
|
||
}
|
||
else {
|
||
const check = this.conditionCheck(value, this.valueA, this.valueB);
|
||
this.setNodesStates(check);
|
||
}
|
||
}
|
||
|
||
// 更新 多个节点 的 状态
|
||
private setNodesStates(checkState?: boolean) {
|
||
const nodes = this.watchNodes;
|
||
const check = checkState;
|
||
nodes.forEach((node) => {
|
||
this.setNodeState(node, check);
|
||
});
|
||
}
|
||
|
||
/** 更新单个节点的状态 */
|
||
private setNodeState(node: Node, checkState?: boolean) {
|
||
const n = this.valueAction;
|
||
const check = checkState;
|
||
switch (n) {
|
||
case ACTION.NODE_ACTIVE:
|
||
node.active = check ? true : false;
|
||
break;
|
||
case ACTION.NODE_VISIBLE: {
|
||
let opacity = node.getComponent(UIOpacity);
|
||
if (opacity == null) {
|
||
opacity = node.addComponent(UIOpacity);
|
||
// 缓存动态添加的组件
|
||
this._addedComponents.set(node, opacity);
|
||
}
|
||
|
||
if (opacity) {
|
||
opacity.opacity = check ? 255 : 0;
|
||
}
|
||
break;
|
||
}
|
||
case ACTION.NODE_OPACITY: {
|
||
let opacity = node.getComponent(UIOpacity);
|
||
if (opacity == null) {
|
||
opacity = node.addComponent(UIOpacity);
|
||
// 缓存动态添加的组件
|
||
this._addedComponents.set(node, opacity);
|
||
}
|
||
|
||
if (opacity) {
|
||
opacity.opacity = check ? this.valueActionOpacity : 255;
|
||
}
|
||
break;
|
||
}
|
||
case ACTION.NODE_COLOR: {
|
||
const uir = node.getComponent(UIRenderer);
|
||
if (uir) {
|
||
uir.color = check ? this.valueActionColor : color(255, 255, 255);
|
||
}
|
||
break;
|
||
}
|
||
case ACTION.COMPONENT_CUSTOM:
|
||
const comp: any = node.getComponent(this.valueComponentName);
|
||
if (comp == null) return;
|
||
if (this.valueComponentProperty in comp) {
|
||
comp[this.valueComponentProperty] = check ? this.valueComponentActionValue : this.valueComponentDefaultValue;
|
||
}
|
||
break;
|
||
case ACTION.SPRITE_GRAYSCALE: {
|
||
const sprite = node.getComponent(Sprite);
|
||
if (sprite) {
|
||
sprite.grayscale = check!;
|
||
}
|
||
break;
|
||
}
|
||
case ACTION.BUTTON_INTERACTABLE: {
|
||
const sprite = node.getComponent(Button);
|
||
if (sprite) {
|
||
sprite.interactable = check!;
|
||
}
|
||
break;
|
||
}
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
/** 条件检查 */
|
||
private conditionCheck(v: any, a: any, b?: any): boolean {
|
||
const cod = CONDITION;
|
||
switch (this.condition) {
|
||
case cod['==']:
|
||
if (v == a) return true;
|
||
break;
|
||
case cod['!=']:
|
||
if (v != a) return true;
|
||
break;
|
||
case cod['<']:
|
||
if (v < a) return true;
|
||
break;
|
||
case cod['>']:
|
||
if (v > a) return true;
|
||
break;
|
||
case cod['>=']:
|
||
if (v >= a) return true;
|
||
break;
|
||
case cod['<']:
|
||
if (v < a) return true;
|
||
break;
|
||
case cod['<=']:
|
||
if (v <= a) return true;
|
||
break;
|
||
case cod['range']:
|
||
if (v >= a && v <= b) return true;
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* 组件销毁时清理内存引用
|
||
*/
|
||
onDestroy() {
|
||
// 清理节点引用数组
|
||
this.watchNodes.length = 0;
|
||
|
||
// 清理动态添加的组件缓存
|
||
this._addedComponents.clear();
|
||
}
|
||
}
|