From a668acafaac46dfc4a4f409df902864f730534d4 Mon Sep 17 00:00:00 2001 From: wyb10a10 Date: Wed, 10 Aug 2022 08:44:49 +0800 Subject: [PATCH] array replicator --- assets/Script/server.meta | 12 ++ assets/Script/server/connection.ts.meta | 9 ++ assets/Script/server/webSock.ts.meta | 9 ++ assets/Script/sync/ArrayReplicator.ts | 139 +++++++++++++++++++++ assets/Script/sync/ArrayReplicator.ts.meta | 9 ++ assets/Script/sync/CocosReplicator.ts | 94 -------------- 6 files changed, 178 insertions(+), 94 deletions(-) create mode 100644 assets/Script/server.meta create mode 100644 assets/Script/server/connection.ts.meta create mode 100644 assets/Script/server/webSock.ts.meta create mode 100644 assets/Script/sync/ArrayReplicator.ts create mode 100644 assets/Script/sync/ArrayReplicator.ts.meta diff --git a/assets/Script/server.meta b/assets/Script/server.meta new file mode 100644 index 0000000..1e8bd28 --- /dev/null +++ b/assets/Script/server.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.0", + "importer": "directory", + "imported": true, + "uuid": "7445f412-3c2a-4c71-8f62-a2e5e5b82134", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/assets/Script/server/connection.ts.meta b/assets/Script/server/connection.ts.meta new file mode 100644 index 0000000..0d93e9f --- /dev/null +++ b/assets/Script/server/connection.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "7b0db602-63b9-47a5-867e-91247733fc9a", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Script/server/webSock.ts.meta b/assets/Script/server/webSock.ts.meta new file mode 100644 index 0000000..b9f502e --- /dev/null +++ b/assets/Script/server/webSock.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "38d6bfe6-1fe3-4b0d-b241-7f2131924135", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Script/sync/ArrayReplicator.ts b/assets/Script/sync/ArrayReplicator.ts new file mode 100644 index 0000000..39eab67 --- /dev/null +++ b/assets/Script/sync/ArrayReplicator.ts @@ -0,0 +1,139 @@ +import ReplicateMark from "./ReplicateMark"; +import { createReplicator } from "./ReplicatorFactory"; +import { IReplicator } from "./SyncUtil"; + +/** + * 数组对象某个版本的数据 + */ +interface ArrayVersion { + version: number; + data: any[]; +} + +/** + * ArrayDiffHistory管理一个数组的变化历史 + * 由于复杂Diff可以直接由genDiff生成,所以这里只需要保存简单Diff,如number、string、boolean等 + * 每个Diff的结构为[length, idx1, data1, idx2, data2, ...] + */ +class ArrayDiffHistory { + private hisotry: ArrayVersion[] = []; + + /** + * append一个新的version + * @param version 新的版本号 + * @param data 新的数据 + */ + append(version: number, data: any[]) { + this.hisotry.push({ version, data }); + } + + /** + * 根据最新的diff,清理老版本的数据 + * 如果length变小,删除历史中所有idx>length的数据 + * 如果idx的data变化,删除历史中所有该idx的数据 + */ +} + +export class SimpleArrayReplicator implements IReplicator { + genDiff(fromVersion: number, toVersion: number) { + throw new Error("Method not implemented."); + } + applyDiff(diff: any): void { + throw new Error("Method not implemented."); + } + getVersion(): number { + throw new Error("Method not implemented."); + } +} + +export class ArrayReplicator implements IReplicator { + private data: Array; + private target: Array; + + constructor(target: Array, mark?: ReplicateMark) { + this.target = target; + this.data = []; + this.makeUpDataArray(target, mark); + } + + pushData(data: T, mark?: ReplicateMark) { + if (data instanceof Object) { + this.data.push(createReplicator(data, mark)); + } else { + this.data.push(data); + } + } + + makeUpDataArray(target: Array, mark?: ReplicateMark) { + for (let i = 0; i < target.length; ++i) { + this.pushData(target[i], mark); + } + } + + genDiff(fromVersion: number, toVersion: number): any { + if (toVersion < fromVersion) { + return false; + } + + // 长度都为0时,不发生变化 + if (this.target.length == 0 && this.data.length == 0) { + return false; + } + + // 先记录长度,再比较数据 + let ret: Array = [this.target.length]; + for (let i = 0; i < this.target.length; i++) { + // 如果i大于data的长度,表示插入了一个新的对象 + if (i >= this.data.length) { + this.pushData(this.target[i]); + // 如果是一个新插入的对象,是否需要添加特殊的标识?方便对端实例化这个新对象 + // continue; + } + let data : any = this.data[i]; + if (data instanceof Object && "genDiff" in data) { + let diff = data.genDiff(fromVersion, toVersion); + if (diff) { + ret.push(i, diff); + } + } else if (data != this.target[i]) { + ret.push(i, this.target[i]); + this.data[i] = this.target[i]; + } + } + + // 如果没有差异(ret的长度为1),且长度相同,则返回false + if (ret.length == 1 && ret[0] == this.data.length) { + return false; + } + + // 如果data的长度大于target的长度,则删除data的多余部分 + if (this.data.length > this.target.length) { + this.data.splice(this.target.length, this.data.length - this.target.length); + } + + return ret; + } + + applyDiff(diff: any): void { + if (diff instanceof Array) { + // 如果长度减少,删除多余的对象 + let length = diff[0]; + if(length < this.target.length) { + this.target.splice(length, this.target.length - length); + } + // 遍历修改或push + for (let i = 1; i < diff.length; ++i) { + // 如果需要创建新的对象 + if(i > this.target.length) { + //todo 为提高效率,可以把简单类型和复杂类型区分开 + //this.target.push(new T()); + } + this.target.push(...diff); + } + } + } + + getVersion(): number { + return 0; + } +} \ No newline at end of file diff --git a/assets/Script/sync/ArrayReplicator.ts.meta b/assets/Script/sync/ArrayReplicator.ts.meta new file mode 100644 index 0000000..8f1bb9f --- /dev/null +++ b/assets/Script/sync/ArrayReplicator.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "27c03987-8891-4e31-926e-cb6f60918583", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Script/sync/CocosReplicator.ts b/assets/Script/sync/CocosReplicator.ts index df18c9f..f16760a 100644 --- a/assets/Script/sync/CocosReplicator.ts +++ b/assets/Script/sync/CocosReplicator.ts @@ -3,8 +3,6 @@ */ import { Vec3 } from "cc"; -import ReplicateMark from "./ReplicateMark"; -import { createReplicator } from "./ReplicatorFactory"; import { IReplicator } from "./SyncUtil"; export class CCVec3Replicator implements IReplicator { @@ -40,95 +38,3 @@ export class CCVec3Replicator implements IReplicator { return this.version; } } - -export class ArrayReplicator implements IReplicator { - private data: Array; - private target: Array; - - constructor(target: Array, mark?: ReplicateMark) { - this.target = target; - this.data = []; - this.makeUpDataArray(target, mark); - } - - pushData(data: T, mark?: ReplicateMark) { - if (data instanceof Object) { - this.data.push(createReplicator(data, mark)); - } else { - this.data.push(data); - } - } - - makeUpDataArray(target: Array, mark?: ReplicateMark) { - for (let i = 0; i < target.length; ++i) { - this.pushData(target[i], mark); - } - } - - genDiff(fromVersion: number, toVersion: number): any { - if (toVersion < fromVersion) { - return false; - } - - // 长度都为0时,不发生变化 - if (this.target.length == 0 && this.data.length == 0) { - return false; - } - - // 先记录长度,再比较数据 - let ret: Array = [this.target.length]; - for (let i = 0; i < this.target.length; i++) { - // 如果i大于data的长度,表示插入了一个新的对象 - if (i >= this.data.length) { - this.pushData(this.target[i]); - // 如果是一个新插入的对象,是否需要添加特殊的标识?方便对端实例化这个新对象 - // continue; - } - let data : any = this.data[i]; - if (data instanceof Object && "genDiff" in data) { - let diff = data.genDiff(fromVersion, toVersion); - if (diff) { - ret.push(i, diff); - } - } else if (data != this.target[i]) { - ret.push(i, this.target[i]); - this.data[i] = this.target[i]; - } - } - - // 如果没有差异(ret的长度为1),且长度相同,则返回false - if (ret.length == 1 && ret[0] == this.data.length) { - return false; - } - - // 如果data的长度大于target的长度,则删除data的多余部分 - if (this.data.length > this.target.length) { - this.data.splice(this.target.length, this.data.length - this.target.length); - } - - return ret; - } - - applyDiff(diff: any): void { - if (diff instanceof Array) { - // 如果长度减少,删除多余的对象 - let length = diff[0]; - if(length < this.target.length) { - this.target.splice(length, this.target.length - length); - } - // 遍历修改或push - for (let i = 1; i < diff.length; ++i) { - // 如果需要创建新的对象 - if(i > this.target.length) { - //todo 为提高效率,可以把简单类型和复杂类型区分开 - //this.target.push(new T()); - } - this.target.push(...diff); - } - } - } - - getVersion(): number { - return 0; - } -} \ No newline at end of file