Files
cocos_creator_framework/assets/Script/sync/DiffScaner.ts
wyb10a10 3dae01294a update
2022-07-19 00:00:54 +08:00

89 lines
3.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 用扫描方式生成Diff
* 2022-01-16 by 宝爷
*/
import { getReplicateMark } from "./ReplicateMark";
import { IDiffGenerator, ReplicateProperty } from "./SyncUtil";
export class ObjectDiffScanner implements IDiffGenerator {
/** 最后一个有数据变化的版本号 */
private lastVersion: number = 0;
/** 最后一次检测的版本号 */
private lastCheckVersion: number = 0;
/** 要扫描的目标Object */
private target: any = null;
/** 所有发生过变化的数据,属性名 : 变化参数 */
private dataMap: Map<string, ReplicateProperty> = new Map<string, ReplicateProperty>();
/** 构造函数 */
constructor(target: any) {
this.target = target;
// 获取类的同步标记
let mark = getReplicateMark(target.prototype);
if(mark) {
let marks = mark.getMarks();
for (let [name, info] of marks) {
// todo: 如果def是IDiffGenerator则需要克隆一个新的对象
// todo: 这里应该使用target的还是mark的数据呢
let rp : ReplicateProperty = { data: info.def || this.target[name], version: 0};
if(info.option) {
// 这里还可能做点其他事情
if(info.option.Setter) {
rp.setter = info.option.Setter;
}
}
this.dataMap.set(name, rp);
}
}
}
/**
* 生成DifftoVersion必须为对象的最新版本号
* @param fromVersion 从哪个版本开始扫描
* @param toVersion 扫描到哪个版本结束
* @returns
*/
genDiff(fromVersion: number, toVersion: number): any {
if (toVersion < fromVersion || this.target === null) {
return false;
}
let ret: any = {};
let needScan = this.lastCheckVersion < toVersion;
// 如果不需要扫描且最终版本小于fromVersion则直接返回
if (!needScan && fromVersion > this.lastVersion) {
return false;
}
// 遍历生成Diff
for (let [name, property] of this.dataMap) {
let setter = property.setter || name;
// 判断是否实现了genDiff接口
if ("genDiff" in property.data) {
let diff = property.data.genDiff(fromVersion, toVersion);
if (diff) {
ret[setter] = diff;
}
} else {
if (needScan) {
if(property.data != this.target[name]) {
property.data = this.target[name];
ret[setter] = property.data;
property.version = toVersion;
}
} else if (property.version > fromVersion) {
ret[setter] = property.data;
}
}
}
this.lastCheckVersion = toVersion;
return ret;
}
/**
* 获取当前版本号
* @returns 最后一个有数据变化的版本号
*/
getVersion(): number {
return this.lastVersion;
}
}