From d34ad4b8cdf67ec36008ce3f19eb2cef00547e59 Mon Sep 17 00:00:00 2001 From: wyb10a10 Date: Mon, 25 Jul 2022 08:39:42 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E9=80=9ACocos=E7=AE=80=E5=8D=95?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/Script/example/SyncExmaple.ts | 11 ++++++++--- assets/Script/sync/DiffScaner.ts | 17 ++++++----------- assets/Script/sync/ReplicateMark.ts | 4 +++- assets/Script/sync/ReplicatorFactory.ts | 4 ++++ 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/assets/Script/example/SyncExmaple.ts b/assets/Script/example/SyncExmaple.ts index 5fa8a5d..8f06eb4 100644 --- a/assets/Script/example/SyncExmaple.ts +++ b/assets/Script/example/SyncExmaple.ts @@ -35,6 +35,9 @@ export default class SyncExample extends Component { vec.x = 123; let diff = getReplicateObject(vec).genDiff(this.lastVersion, this.lastVersion + 1); console.log(`vec diff ${diff}`);*/ + } + + makeObjectReplicated() { // 跟踪的属性并不能直接apply,而是需要调用接收者的如setPosition等方法使其生效 // 这里可以考虑将Node的同步作为一个组件进行挂载,专门负责与Cocos节点相关的同步工作 // 也可以考虑通过装饰器参数的描述来处理这种情况,比如 { name : _lpos, setter : setPosition, } @@ -44,9 +47,9 @@ export default class SyncExample extends Component { {Name : '_euler', Setter: 'eulerAngles'}]; //makeObjectReplicated(this.leftNode, { SyncProperty : syncProperty}); - let mark = getReplicateMark(this.leftNode); - mark.setObjMark({SyncProperty : syncProperty}); + let mark = getReplicateMark(this.leftNode, true, { SyncProperty : syncProperty}); getReplicator(this.leftNode, true, mark); + getReplicator(this.rightNode, true, mark); } onSyncClick() { @@ -61,12 +64,14 @@ export default class SyncExample extends Component { }*/ let diff = getReplicator(this.leftNode).genDiff(this.lastVersion, this.lastVersion + 1); if (diff) { - applyDiff(diff, this.rightNode); + // applyDiff(diff, this.rightNode); + getReplicator(this.rightNode).applyDiff(diff); this.lastVersion += 1; } } onRotateClick() { + this.makeObjectReplicated() tween(this.leftNode) .by(3.0, {eulerAngles : new Vec3(0, randomRange(0, 180), 0)}) .start(); diff --git a/assets/Script/sync/DiffScaner.ts b/assets/Script/sync/DiffScaner.ts index 888fe3f..1ebd056 100644 --- a/assets/Script/sync/DiffScaner.ts +++ b/assets/Script/sync/DiffScaner.ts @@ -38,16 +38,11 @@ export class ReplicateScanner implements IReplicator { for (let [name, info] of marks) { let data = info.def || target[name]; // 如果def是函数,则执行函数返回一个新的对象(比如嵌套的对象) - if (typeof info.def === "function") { + /*if (typeof info.def === "function") { data = info.def.call(target[name], target, info); - } else if (data instanceof Object) { - if (info.option?.ObjectOption) { - let subMark = getReplicateMark(data, true); - subMark.setObjMark(info.option.ObjectOption); - data = createReplicator(target[name], subMark); - } else { - data = createReplicator(target[name]); - } + } else*/ if (data instanceof Object) { + let subMark = getReplicateMark(data, true, info.option?.ObjectOption); + data = createReplicator(target[name], subMark); } let rp: ReplicateProperty = { data, version: 0 }; if (info.option) { @@ -82,7 +77,7 @@ export class ReplicateScanner implements IReplicator { // let setter = property.setter || name; let setter = name; // 判断是否实现了genDiff接口 - if ("genDiff" in property.data) { + if (property.data instanceof Object && "genDiff" in property.data) { let diff = property.data.genDiff(fromVersion, toVersion); if (diff) { ret[setter] = diff; @@ -116,7 +111,7 @@ export class ReplicateScanner implements IReplicator { if (property.setter && typeof this.target[property.setter] === "function") { // diff[key]可能是数组,当它是数组的时候,可以得到下面这样的效果 // 如setPosition,this.target.setPosition(diff[key][0], diff[key][1], diff[key][2]) - this.target[property.setter].call(this.target[key], diff[key]); + this.target[property.setter].apply(this.target, diff[key]); } else if (property.data instanceof Object && "applyDiff" in property.data) { // 判断是否实现了applyDiff接口 property.data.applyDiff(diff[key]); diff --git a/assets/Script/sync/ReplicateMark.ts b/assets/Script/sync/ReplicateMark.ts index 9bd0044..bfcadbf 100644 --- a/assets/Script/sync/ReplicateMark.ts +++ b/assets/Script/sync/ReplicateMark.ts @@ -114,6 +114,7 @@ export default class ReplicateMark { public setObjMark(objMark?: ObjectReplicatedOption) { this.objMark = objMark; + this.initMark(); } public getObjMark(): ObjectReplicatedOption | undefined { @@ -135,7 +136,8 @@ export default class ReplicateMark { } } else { // 如果没有指定SyncProperty,则添加所有属性到标记中 - for (let key in this.cls) { + // 使用Keys遍历,避免遍历到其原型属性导致无限递归 + for (let key of Object.keys(this.cls)) { this.addMark(key, this.cls[key]); } } diff --git a/assets/Script/sync/ReplicatorFactory.ts b/assets/Script/sync/ReplicatorFactory.ts index e1e0f2d..edec18d 100644 --- a/assets/Script/sync/ReplicatorFactory.ts +++ b/assets/Script/sync/ReplicatorFactory.ts @@ -1,3 +1,5 @@ +import { Vec3 } from "cc"; +import { CCVec3Replicator } from "./CocosReplicator"; import { ReplicateScanner } from "./DiffScaner"; import { ReplicateTrigger } from "./DiffTrigger"; import ReplicateMark, { ReplicateType } from "./ReplicateMark"; @@ -8,6 +10,8 @@ export function createReplicator(target: any, mark?: ReplicateMark) : IReplicato if (target instanceof Array) { // TODO: 数组类型 return null; + } else if (target instanceof Vec3) { + return new CCVec3Replicator(target); } else if (target instanceof Object) { if (mark) { let objMark = mark.getObjMark();