Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Syncframework #36

Merged
merged 123 commits into from
Jul 30, 2023
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
123 commits
Select commit Hold shift + click to select a range
f427548
【creator3.0】清理老版本资源
wyb10a10 Mar 20, 2021
9c0aa6b
【creator3.0】新项目设置文件同步
wyb10a10 Mar 20, 2021
e7da3b4
【creator3.0】资源文件转换
wyb10a10 Mar 20, 2021
29504ff
【creator3.0】场景资源转换
wyb10a10 Mar 20, 2021
be91e4c
【creator3.0】通用脚本调整
wyb10a10 Mar 20, 2021
ce2436d
【creator3.0】网络框架调整
wyb10a10 Mar 20, 2021
9e240a1
【creator3.0】资源框架调整
wyb10a10 Mar 20, 2021
5edd368
【creator3.0】UI框架调整
wyb10a10 Mar 20, 2021
75c2a7e
【creator3.0】示例代码调整
wyb10a10 Mar 20, 2021
a6aea64
【creator3.0】UI遮罩层问题
wyb10a10 Mar 20, 2021
c818498
修复遮罩层bug
wyb10a10 Mar 25, 2021
13e2496
添加spine资源测试
wyb10a10 Apr 4, 2021
f4c8c46
测试Spine内存泄露
wyb10a10 Apr 4, 2021
2c75ac1
demo内存泄露fix
wyb10a10 Apr 9, 2021
95f494f
3.1.1
wyb10a10 Jun 14, 2021
7ec3b77
3.1.1
wyb10a10 Jun 14, 2021
5237cdc
网络同步
wyb10a10 Jun 27, 2021
13e77ce
完善属性复制逻辑
wyb10a10 Jun 29, 2021
38783c2
添加属性同步装饰器
wyb10a10 Jul 5, 2021
cede668
复制属性
wyb10a10 Jul 13, 2021
9cbcc15
清理资源
wyb10a10 Jul 15, 2021
ec55377
网络同步测试场景
wyb10a10 Aug 21, 2021
4aa09b0
优化代码结构
wyb10a10 Sep 5, 2021
e9a037f
调整测试场景
wyb10a10 Sep 6, 2021
1993477
添加动画
wyb10a10 Sep 7, 2021
d59ad2c
递归apply
wyb10a10 Sep 8, 2021
984ddab
Merge branch 'syncframework' of github.com:wyb10a10/cocos_creator_fra…
wyb10a10 Sep 8, 2021
9cac972
debug
wyb10a10 Sep 8, 2021
7b5ac3e
基础位置和缩放同步
wyb10a10 Sep 8, 2021
6f9bf47
指定属性同步与跳过属性同步
wyb10a10 Sep 8, 2021
6cbdf54
使用欧拉角和tween进行线性旋转
wyb10a10 Sep 13, 2021
8480a06
同步指定属性
wyb10a10 Sep 13, 2021
a2f3540
Merge branch 'syncframework' of github.com:wyb10a10/cocos_creator_fra…
wyb10a10 Sep 14, 2021
ef8d75b
改用keys来applyDiff
wyb10a10 Sep 14, 2021
e925137
调整跟踪的属性
wyb10a10 Sep 14, 2021
e5ccf21
新增setter选项,应对特殊的属性同步
wyb10a10 Sep 20, 2021
d57884a
类装饰器
wyb10a10 Sep 27, 2021
21c7f5a
初值不纳入变化,修正版本号计算
wyb10a10 Oct 1, 2021
c669acc
fix bug
wyb10a10 Dec 7, 2021
c9bbd04
fix example bug
wyb10a10 Dec 8, 2021
a111d3a
replicate mark
wyb10a10 Dec 13, 2021
3d7b0bd
new gen diff
wyb10a10 Dec 13, 2021
af96317
Merge branch 'syncframework' of github.com:wyb10a10/cocos_creator_fra…
wyb10a10 Dec 17, 2021
8684c77
重构装饰器
wyb10a10 Dec 17, 2021
0733cc9
完善类装饰器
wyb10a10 Dec 28, 2021
8b24592
测试代码
wyb10a10 Dec 28, 2021
cac6725
完善装饰器
wyb10a10 Dec 29, 2021
e6da1fb
内置对象不可枚举
wyb10a10 Dec 29, 2021
30e3e26
隐藏内置属性,并将Mark绑定到prototype
wyb10a10 Jan 10, 2022
2879f8a
Merge branch 'syncframework' of github.com:wyb10a10/cocos_creator_fra…
wyb10a10 Jan 10, 2022
7b8689f
debug
wyb10a10 Jan 10, 2022
dac6b55
跟踪原始值
wyb10a10 Jan 10, 2022
1ece9ce
优化代码
wyb10a10 Jan 14, 2022
4a197e7
代码调整
wyb10a10 Jan 16, 2022
2992991
重构装饰器
wyb10a10 Jan 19, 2022
360bdc8
移除返回值
wyb10a10 Jan 19, 2022
6a5a8ff
调通trigger
wyb10a10 Jan 19, 2022
ccc75a7
temp commit
wyb10a10 May 10, 2022
240c6c3
I come back
wyb10a10 Jul 16, 2022
ed421e3
diffscan
wyb10a10 Jul 18, 2022
3dae012
update
wyb10a10 Jul 18, 2022
71590d0
makeup datamap
wyb10a10 Jul 19, 2022
2be60d7
scanner diff apply
wyb10a10 Jul 22, 2022
39282c3
scanner and trigger
wyb10a10 Jul 23, 2022
1353052
makePropertyReplicatedMark
wyb10a10 Jul 23, 2022
de39692
makeObjectReplicatedMark
wyb10a10 Jul 23, 2022
94a7343
add factory and cocos replicator
wyb10a10 Jul 24, 2022
e28251c
auto gen mark
wyb10a10 Jul 24, 2022
d34ad4b
调通Cocos简单对象同步
wyb10a10 Jul 25, 2022
fe06c95
fix eulerAngles error
wyb10a10 Jul 26, 2022
59ee647
clear code
wyb10a10 Jul 26, 2022
f071783
debug
wyb10a10 Jul 29, 2022
e639405
auto get mark
wyb10a10 Jul 29, 2022
adf3a1a
delay init for class replicator
wyb10a10 Jul 29, 2022
60a1262
fix bug
wyb10a10 Jul 29, 2022
ac8eb04
fix init bug
wyb10a10 Jul 29, 2022
1d57741
change seq
wyb10a10 Jul 30, 2022
2ea0eb9
init server framework
YJH143 Aug 8, 2022
4bd7daf
array replicator
wyb10a10 Aug 9, 2022
ba4dc35
Merge branch 'syncframework' of github.com:wyb10a10/cocos_creator_fra…
wyb10a10 Aug 9, 2022
a668aca
array replicator
wyb10a10 Aug 10, 2022
2873b8f
SimpleArrayReplicator
wyb10a10 Aug 10, 2022
c451715
ArrayReplicator
wyb10a10 Aug 11, 2022
f3987e3
ArrayReplicator
wyb10a10 Aug 14, 2022
1a0eac0
temp commit
wyb10a10 Aug 16, 2022
4ff8fd6
gendiff
wyb10a10 Aug 17, 2022
5814812
apply diff
wyb10a10 Aug 25, 2022
0e3f95a
server framework
YJH143 Aug 28, 2022
6a2ecbe
temp commit
wyb10a10 Sep 3, 2022
5c79123
Merge branch 'syncframework' of github.com:wyb10a10/cocos_creator_fra…
wyb10a10 Sep 3, 2022
d278315
apply diff
wyb10a10 Sep 4, 2022
0fd1573
test simple array
wyb10a10 Sep 5, 2022
32f9895
test simple array version
wyb10a10 Sep 5, 2022
20f8e0d
createReplicator
wyb10a10 Sep 6, 2022
854f67c
debug
Sep 6, 2022
67b560f
delete meta files
Sep 6, 2022
ad456a0
调整目录,以及文件名
Sep 7, 2022
55e6e4e
array test
wyb10a10 Sep 9, 2022
20bbb03
Merge branch 'syncframework' of github.com:wyb10a10/cocos_creator_fra…
wyb10a10 Sep 9, 2022
b99b99f
fix init error
wyb10a10 Sep 12, 2022
51ebf9e
fix bug
wyb10a10 Sep 13, 2022
96dbaa2
debug
wyb10a10 Sep 15, 2022
8fa6aa9
fix bug
wyb10a10 Mar 13, 2023
6fb87e6
update array replicator
wyb10a10 Jul 13, 2023
7ecbfcb
fix scan bug
wyb10a10 Jul 21, 2023
98bb586
new array replicator
wyb10a10 Jul 21, 2023
9e3496a
fix lot of bug and add more test
wyb10a10 Jul 22, 2023
b94c64f
debug
wyb10a10 Jul 23, 2023
9e022d7
fix bug
wyb10a10 Jul 23, 2023
c040606
clean code
wyb10a10 Jul 23, 2023
c3605ce
update protocol
wyb10a10 Jul 23, 2023
d811835
finish array link
wyb10a10 Jul 23, 2023
baa3a11
add simple hash replicator
wyb10a10 Jul 24, 2023
29855d3
add simple set replicator
wyb10a10 Jul 25, 2023
5e86977
debug simple set
wyb10a10 Jul 26, 2023
11eec0f
add log
wyb10a10 Jul 26, 2023
1fee93f
update simple hash replicator
wyb10a10 Jul 28, 2023
60cf62d
add hash replicator
wyb10a10 Jul 28, 2023
df635d2
test hash replicator
wyb10a10 Jul 29, 2023
ab5dce6
update factory
wyb10a10 Jul 30, 2023
a7947af
fix bug
wyb10a10 Jul 30, 2023
b33b2f8
clean code
wyb10a10 Jul 30, 2023
ecf3d50
Merge branch 'master' into syncframework
wyb10a10 Jul 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions assets/Script/example/SyncExmaple.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Component, Label, _decorator, view, director, Node, RichText, tween, Tween, math, randomRange, Vec3, Quat } from "cc";
import { applyDiff, getReplicateObject, makeObjectReplicated } from "../sync/SyncUtil";
import { Component, Label, _decorator, view, director, Node, RichText, tween, Tween, math, randomRange, Vec3, Quat, ModelComponent, Color } from "cc";
import { applyDiff, getReplicateObject, makeObjectReplicated, ReplicatedOption } from "../sync/SyncUtil";

const { ccclass, property } = _decorator;

Expand All @@ -17,18 +17,26 @@ export default class SyncExample extends Component {
vec.x = 123;
let diff = getReplicateObject(vec).genDiff(this.lastVersion, this.lastVersion + 1);
console.log(`vec diff ${diff}`);*/
let syncProperty = ['_scale', '_position', '_eulerAngles'];
// 跟踪的属性并不能直接apply,而是需要调用接收者的如setPosition等方法使其生效
// 这里可以考虑将Node的同步作为一个组件进行挂载,专门负责与Cocos节点相关的同步工作
// 也可以考虑通过装饰器参数的描述来处理这种情况,比如 { name : _lpos, setter : setPosition, }
let syncProperty : ReplicatedOption[] = [
{Name : '_lscale', Setter: 'setScale'},
{Name : '_lpos', Setter: 'setPosition'},
{Name : '_euler', Setter: 'eulerAngles'}];
makeObjectReplicated(this.leftNode, { SyncProperty : syncProperty});
}

onSyncClick() {
/*let diffScale = getReplicateObject(this.leftNode.scale).genDiff(this.lastVersion, this.lastVersion + 1);
let diffPos = getReplicateObject(this.leftNode.position).genDiff(this.lastVersion, this.lastVersion + 1);
let diffRot = getReplicateObject(this.leftNode.eulerAngles).genDiff(this.lastVersion, this.lastVersion + 1);

let diff = {scale : diffScale, position: diffPos, eulerAngles: diffRot};*/
let diff = getReplicateObject(this.leftNode).genDiff(this.lastVersion, this.lastVersion + 1);
applyDiff(diff, this.rightNode);
if (diff) {
applyDiff(diff, this.rightNode);
this.lastVersion += 1;
}
}

onRotateClick() {
Expand Down Expand Up @@ -61,5 +69,9 @@ export default class SyncExample extends Component {
.start();
}

onColorClick() {
this.leftNode.getComponent(ModelComponent)?.material?.setProperty("mainColor", Color.BLUE);
}

// update (dt) {}
}
192 changes: 147 additions & 45 deletions assets/Script/sync/SyncUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,34 @@

/** 属性变化回调 */
export type ReplicateNotify = (target: any, key: string, value: any) => boolean;
const IsSupportGetSet = false;

/**
* 属性同步选项
*/
export interface ReplicatedOption {
/** 指定同步哪些属性 */
SyncProperty?: string[];
/** 指定跳过哪些属性的同步 */
SkipProperty?: string[];
/** 要同步的属性名 */
Name: string;
/** 应用同步的方法,默认为Name */
Setter?: string;
/** 属性同步条件 */
Condiction?: number;
/** 同步回调 */
Notify?: ReplicateNotify;
}

/**
* 对象属性同步配置
*/
export interface ObjectReplicatedOption {
/** 指定同步哪些属性 */
SyncProperty?: ReplicatedOption[];
/** 指定跳过哪些属性的同步 */
SkipProperty?: string[];
}

export const REPLICATE_OBJECT_INDEX = "__repObj__";
export const REPLICATE_MARK_INDEX = "__repMrk__";

/**
* 查询对象的ReplicateObject,检查对象的target.__repObj__字段
Expand All @@ -34,50 +46,74 @@ export const REPLICATE_OBJECT_INDEX = "__repObj__";
export function getReplicateObject(target: any, autoCreator: boolean = false): ReplicateObject {
let ret: ReplicateObject = target[REPLICATE_OBJECT_INDEX];
if (!ret && autoCreator) {
ret = new ReplicateObject();
ret = new ReplicateObject();
target[REPLICATE_OBJECT_INDEX] = ret;
}
return ret;
}

export function getReplicateMark(target: any): ReplicateMark {
let ret: ReplicateMark = target[REPLICATE_MARK_INDEX];
if (!ret) {
ret = new ReplicateMark();
target[REPLICATE_MARK_INDEX] = ret;
}
return ret;
}

export function makePropertyDescriptor(target: any, propertyKey: string, descriptor: PropertyDescriptor, option?: ReplicatedOption): PropertyDescriptor {
// 在不影响原来set方法的基础上自动跟踪属性变化
let realProperty: string;
if (option && option.Setter) {
realProperty = option.Setter;
} else {
realProperty = propertyKey;
}
delete descriptor.value;
delete descriptor.writable;
let oldSet = descriptor.set;
descriptor.set = (v: any) => {
let repObj = getReplicateObject(target, true);
// 标记属性发生变化
repObj.propertyChanged(realProperty, v);
if (oldSet) {
oldSet(v);
}
}
// 在不影响原来get方法的基础上,实现set方法的对应操作
let oldGet = descriptor.get;
if (!oldGet) {
descriptor.get = () => {
let repObj = getReplicateObject(target, true);
return repObj.getProperty(realProperty);
}
}
return descriptor;
}

/**
* 将一个对象的指定属性设置为可复制,为对象自动添加__repObj__属性,同时跟踪该属性的变化
* @param target 要指定的对象
* @param propertyKey 对象的属性名
* @param descriptor 属性的描述符
* @param option 自定义同步选项
*/
export function makePropertyReplicated(target: any, propertyKey: string, descriptor?: PropertyDescriptor, option?:ReplicatedOption) {
export function makePropertyReplicated(target: any, propertyKey: string, descriptor?: PropertyDescriptor, option?: ReplicatedOption) {
if (!descriptor) {
descriptor = Object.getOwnPropertyDescriptor(target, propertyKey);
}
if (descriptor) {
// 在不影响原来set方法的基础上自动跟踪属性变化
let oldValue = descriptor.value;
delete descriptor.value;
delete descriptor.writable;
let oldSet = descriptor.set;
descriptor.set = (v: any) => {
let repObj = getReplicateObject(target, true);
// 标记属性发生变化
repObj.propertyChanged(propertyKey, v);
if (oldSet) {
oldSet(v);
if (IsSupportGetSet) {
descriptor = makePropertyDescriptor(target, propertyKey, descriptor, option);
Object.defineProperty(target, propertyKey, descriptor);
// 设置默认值
if (oldValue !== undefined) {
target[propertyKey] = oldValue;
}
}
// 在不影响原来get方法的基础上,实现set方法的对应操作
let oldGet = descriptor.get;
if (!oldGet) {
descriptor.get = () => {
let repObj = getReplicateObject(target, true);
return repObj.getProperty(propertyKey);
}
}
console.warn(`${descriptor}`);
Object.defineProperty(target, propertyKey, descriptor);
// 设置默认值
if (oldValue !== undefined) {
target[propertyKey] = oldValue;
} else {
getReplicateMark(target).addMark(propertyKey, oldValue, option);
}
}
}
Expand All @@ -87,21 +123,21 @@ export function makePropertyReplicated(target: any, propertyKey: string, descrip
* @param target
* @param option
*/
export function makeObjectReplicated(target: any, option?:ReplicatedOption) {
export function makeObjectReplicated(target: any, option?: ObjectReplicatedOption) {
if (option && option.SyncProperty) {
option.SyncProperty.forEach((key) => {
let descriptor = Object.getOwnPropertyDescriptor(target, key);
option.SyncProperty.forEach((pOpt) => {
let descriptor = Object.getOwnPropertyDescriptor(target, pOpt.Name);
if (descriptor) {
makePropertyReplicated(target, key, descriptor, option);
makePropertyReplicated(target, pOpt.Name, descriptor, pOpt);
}
});
} else {
let keys = Object.keys(target);
keys.forEach((key) => {
if (!(option?.SkipProperty && option.SkipProperty.indexOf(key) >= 0)) {
makePropertyReplicated(target, key, Object.getOwnPropertyDescriptor(target, key), option);
makePropertyReplicated(target, key, Object.getOwnPropertyDescriptor(target, key));
}
})
})
}
}

Expand All @@ -110,9 +146,12 @@ export function makeObjectReplicated(target: any, option?:ReplicatedOption) {
* @param diff
* @param target
*/
export function applyDiff(diff : any, target : any) {
for (let propertyName in diff) {
if(diff[propertyName] instanceof Object) {
export function applyDiff(diff: any, target: any) {
let keys = Object.keys(diff);
keys.forEach((propertyName) => {
if (typeof target[propertyName] == "function") {
target[propertyName](diff[propertyName]);
} else if (diff[propertyName] instanceof Object) {
if (target[propertyName] instanceof Object) {
let prop = target[propertyName];
applyDiff(diff[propertyName], prop);
Expand All @@ -124,7 +163,29 @@ export function applyDiff(diff : any, target : any) {
} else {
target[propertyName] = diff[propertyName];
}
});
}

export function genDiff(target: any, from: number, to: number): any {
let repObj = getReplicateObject(target);
if (!IsSupportGetSet && repObj.getLastVersion() == 0) {
let markObj = getReplicateMark(target);
let objOption = markObj.getObjMark();
if (objOption) {
makeObjectReplicated(target, objOption);
}
let keys = Object.keys(target);
keys.forEach((propertyName) => {
let option = markObj.getMark(propertyName);
if (option) {
makePropertyReplicated(target, propertyName,
Object.getOwnPropertyDescriptor(target, propertyName), option.option);
// TODO: 比对初值
}
});
}

return repObj.genDiff(from, to);
}

/**
Expand All @@ -138,8 +199,41 @@ export function replicated(option?: ReplicatedOption) {
};
}

export function replicatedClass(option?: ReplicatedOption) {
type ClassDecorator = <TFunction extends Function>
(target: TFunction) => TFunction | void;

type Consturctor = { new(...args: any[]): any };

export function replicatedClass<T extends Consturctor>(option?: ObjectReplicatedOption) {
return (target: T) => {
makeObjectReplicated(target, option);
}
}

interface ReplicateMarkInfo {
def?: any,
option?: ReplicatedOption,
}

class ReplicateMark {
private markMap: Map<string, ReplicateMarkInfo> = new Map<string, ReplicateMarkInfo>();
private objMark?: ObjectReplicatedOption;

public addMark(key: string, def?: any, option?: ReplicatedOption) {
this.markMap.set(key, { def, option });
}

public getMark(key: string): ReplicateMarkInfo | undefined {
return this.markMap.get(key);
}

public setObjMark(objMark: ObjectReplicatedOption) {
this.objMark = objMark;
}

public getObjMark(): ObjectReplicatedOption | undefined {
return this.objMark;
}
}

/**
Expand Down Expand Up @@ -182,6 +276,10 @@ class ReplicateObject {
outObject[key] = data;
}

public getLastVersion(): number {
return this.lastVersion;
}

/**
* 当一个属性被重新赋值时回调,即 target.key = v时
* 1. 对比数值是否有发生变化,有则更新dataMap
Expand All @@ -204,7 +302,7 @@ class ReplicateObject {
repPro.data = v;
}
} else {
repPro = { version: 0, data: v, changed: true };
repPro = { version: 0, data: v, changed: false };
this.dataMap.set(key, repPro);
}

Expand All @@ -214,11 +312,13 @@ class ReplicateObject {
}

// 如果有outter,需要通知,但只通知一次就够了
if (!this.hasNewChange && this.outter) {
this.outter.propertyChanged(this.outterKey);
// 首次赋值时(初始值,无需通知outter)
if (!this.hasNewChange && repPro.changed) {
if (this.outter) {
this.outter.propertyChanged(this.outterKey);
}
this.hasNewChange = true;
}

this.hasNewChange = true;
}

public getProperty(key: string): any {
Expand All @@ -237,7 +337,7 @@ class ReplicateObject {
* @param toVersion 必须是最新的版本号
*/
public genDiff(fromVersion: number, toVersion: number): any {
if (toVersion <= fromVersion) {
if (toVersion < fromVersion) {
return false;
}

Expand All @@ -264,6 +364,8 @@ class ReplicateObject {
}
}

this.lastVersion = toVersion;

return outObject;
}

Expand Down
12 changes: 6 additions & 6 deletions profiles/v2/packages/scene.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,9 @@
},
"d8be8bee-362a-494a-9643-8e52af4c0c15": {
"position": {
"x": 480,
"y": 320,
"z": 2880
"x": -2,
"y": 0,
"z": 6.237669892207257
},
"rotation": {
"x": 0,
Expand All @@ -120,14 +120,14 @@
"w": 1
},
"viewCenter": {
"x": 480,
"y": 320,
"x": -2,
"y": 0,
"z": 0
}
}
},
"camera-uuids": [
"f46876e4-e81b-4931-b493-6d367be385e7"
"a18214d2-f37c-41d3-908b-0a859a46c913"
],
"float-window": {
"position": {
Expand Down