| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- import { _decorator, Component, find, game } from "cc";
- import { Constructor } from "../core";
- import { Data } from "./Data";
- const { ccclass, property } = _decorator;
- /**
- * 数据系统组件,常驻节点,可创建数据、获取数据、观察数据变化
- * 创建数据:g.userData = DataSystem.createData<UserData>(UserData);update方法里:DataSystem.watch(g.userData,"money") && this.moneyLabel.string = g.userData.money;
- * @author 袁浩
- */
- @ccclass('DataSystem')
- export class DataSystem extends Component {
- private dataMap: Map<Constructor, Data> = new Map<Constructor, Data>();
- private watchData: Map<Data, Map<PropertyKey, boolean>> = new Map<Data, Map<PropertyKey, boolean>>();
- private watchedList: Array<{ data: Data, key: PropertyKey }> = [];
- start() {
- game.addPersistRootNode(this.node);//常驻节点
- this.node.name = "DataSystem";
- }
- /**
- * 数据系统对象
- */
- private static get thisObject(): DataSystem {
- let node = find("DataSystem");
- return node && node.getComponent(DataSystem);
- }
- /**
- * 创建数据
- * @param classConstructor 数据对象类型
- * @returns
- */
- static createData<T extends Data>(classConstructor: Constructor<T>): void {
- let data = new classConstructor(DataSystem.thisObject.onPropertyChange, DataSystem.thisObject);
- DataSystem.thisObject.dataMap.set(classConstructor, data);
- DataSystem.thisObject.watchData.set(data, new Map<string, boolean>());
- }
- /**
- * 获取数据
- * @param classConstructor 数据对象类型
- * @returns
- */
- static getData<T extends Data>(classConstructor: Constructor<T>): T {
- return DataSystem.thisObject.dataMap.get(classConstructor) as T;
- }
- /**
- * 删除数据
- * @param classConstructor 数据对象类型
- */
- static deleteData<T extends Data>(classConstructor: Constructor<T>): void {
- DataSystem.thisObject.watchData.delete(DataSystem.thisObject.dataMap.get(classConstructor));
- DataSystem.thisObject.dataMap.delete(classConstructor);
- }
- /**
- * 观察数据,当数据产生变化时会被观察到,被观察后会在帧尾清空标记
- * 注意:在watch帧的时候,改变正在watch的属性值是不会被观察到变化的
- * @param data 数据对象
- * @param key 数据的属性名
- * @returns
- */
- static watch(data: Data, key: PropertyKey) {
- let propertyKeyMap = DataSystem.thisObject.watchData.get(data);
- DataSystem.thisObject.watchedList.push({ data, key });
- return propertyKeyMap.get(key);
- }
- lateUpdate() {
- for (let i = 0; i < this.watchedList.length; i++) {
- const watchedData = this.watchedList[i];
- this.watchData.get(watchedData.data).set(watchedData.key, false);
- }
- }
- private onPropertyChange(data: Data, key: PropertyKey, value: any) {
- let propertyKeyMap = this.watchData.get(data);
- propertyKeyMap.set(key, true);
- }
- }
|