DataSystem.ts 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import { _decorator, Component, find, game } from "cc";
  2. import { Constructor } from "../core";
  3. import { Data } from "./Data";
  4. const { ccclass, property } = _decorator;
  5. /**
  6. * 数据系统组件,常驻节点,可创建数据、获取数据、观察数据变化
  7. * 创建数据:g.userData = DataSystem.createData<UserData>(UserData);update方法里:DataSystem.watch(g.userData,"money") && this.moneyLabel.string = g.userData.money;
  8. * @author 袁浩
  9. */
  10. @ccclass('DataSystem')
  11. export class DataSystem extends Component {
  12. private dataMap: Map<Constructor, Data> = new Map<Constructor, Data>();
  13. private watchData: Map<Data, Map<PropertyKey, boolean>> = new Map<Data, Map<PropertyKey, boolean>>();
  14. private watchedList: Array<{ data: Data, key: PropertyKey }> = [];
  15. start() {
  16. game.addPersistRootNode(this.node);//常驻节点
  17. this.node.name = "DataSystem";
  18. }
  19. /**
  20. * 数据系统对象
  21. */
  22. private static get thisObject(): DataSystem {
  23. let node = find("DataSystem");
  24. return node && node.getComponent(DataSystem);
  25. }
  26. /**
  27. * 创建数据
  28. * @param classConstructor 数据对象类型
  29. * @returns
  30. */
  31. static createData<T extends Data>(classConstructor: Constructor<T>): void {
  32. let data = new classConstructor(DataSystem.thisObject.onPropertyChange, DataSystem.thisObject);
  33. DataSystem.thisObject.dataMap.set(classConstructor, data);
  34. DataSystem.thisObject.watchData.set(data, new Map<string, boolean>());
  35. }
  36. /**
  37. * 获取数据
  38. * @param classConstructor 数据对象类型
  39. * @returns
  40. */
  41. static getData<T extends Data>(classConstructor: Constructor<T>): T {
  42. return DataSystem.thisObject.dataMap.get(classConstructor) as T;
  43. }
  44. /**
  45. * 删除数据
  46. * @param classConstructor 数据对象类型
  47. */
  48. static deleteData<T extends Data>(classConstructor: Constructor<T>): void {
  49. DataSystem.thisObject.watchData.delete(DataSystem.thisObject.dataMap.get(classConstructor));
  50. DataSystem.thisObject.dataMap.delete(classConstructor);
  51. }
  52. /**
  53. * 观察数据,当数据产生变化时会被观察到,被观察后会在帧尾清空标记
  54. * 注意:在watch帧的时候,改变正在watch的属性值是不会被观察到变化的
  55. * @param data 数据对象
  56. * @param key 数据的属性名
  57. * @returns
  58. */
  59. static watch(data: Data, key: PropertyKey) {
  60. let propertyKeyMap = DataSystem.thisObject.watchData.get(data);
  61. DataSystem.thisObject.watchedList.push({ data, key });
  62. return propertyKeyMap.get(key);
  63. }
  64. lateUpdate() {
  65. for (let i = 0; i < this.watchedList.length; i++) {
  66. const watchedData = this.watchedList[i];
  67. this.watchData.get(watchedData.data).set(watchedData.key, false);
  68. }
  69. }
  70. private onPropertyChange(data: Data, key: PropertyKey, value: any) {
  71. let propertyKeyMap = this.watchData.get(data);
  72. propertyKeyMap.set(key, true);
  73. }
  74. }