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

Modify the calculation of renderOrder in EventManager. #4522

Merged
merged 11 commits into from Jun 12, 2019

Conversation

@caryliu1999
Copy link
Contributor

commented May 29, 2019

@@ -277,6 +287,25 @@ var eventManager = {
}
},

_visitTarget (node) {
// sortAllChildren is performed the next frame, but the event is executed immediately.

This comment has been minimized.

Copy link
@2youyou2

2youyou2 May 30, 2019

Collaborator

看了下 sortAllChildren 不是马上就执行了吗,_delaySort 才是会延迟执行?

if (dirty) {
this._nodePriorityIndex = 0;
let rootEntity = cc.director.getScene();
this._visitTarget(rootEntity);

This comment has been minimized.

Copy link
@pandamicro

pandamicro May 30, 2019

Member

还是要在事件触发前遍历整个节点树啊,其实可以让你之前的实现更通用化一些,就是给 render flow 加一个阶段,updateEventOrder 阶段,在 listener dirty 的时候只需要给节点设置 event dirty 的 _renderFlag 就可以了

@pandamicro

This comment has been minimized.

Copy link
Member

commented May 30, 2019

对于 2.x 和 native renderer 都是有 render flow 概念的,对于 3d 来说需要在 ui.ts 中做一些适配,暂时没有很统一

@caryliu1999

This comment has been minimized.

Copy link
Contributor Author

commented May 30, 2019

对于 2.x 和 native renderer 都是有 render flow 概念的,对于 3d 来说需要在 ui.ts 中做一些适配,暂时没有很统一

  1. native renderer的render flow在原生层进行场景树的递归,要么就需要产生跟js层的交互,要么就得在节点加字段以共享内存的形式存储渲染顺序,这也是不太想在渲染流程这一块做这个事情的原因,另外就是一定会增加渲染流程的消耗。

  2. 不过在触发事件时做场景树的完整遍历也不合适,虽然只做一次处理,不是很优雅,即便只有两个节点需要排序,也得遍历整个场景树。

这里想到了一个更合适的方案做了修改,取消了场景树的遍历,也不需要在渲染流程中保存节点渲染次序了,只是修改了排序时的对比方法,这里可以不需要遍历场景树来判断两个节点的先后次序。大概思路是:场景树的节点跟自己的父节点刚好组成了一个单链表,然后场景树中的两个节点所属的单链表一定是有一个相交节点的,向上的末节点都是Scene节点,这样只需要找到两个单链表的第一个相交父节点,然后再比较子节点的_localZOrder就可以决定两个节点的渲染次序了,这里采用了最优的查找算法,只需要遍历一次,最差的情况下遍历次数是长链表的节点个数,也就是节点的场景树深度值,场景树的深度值也不会很大,最优的情况就是同一父节点不需要遍历,时间复杂度上没有问题,测试的TestList场景200个节点排序耗时也只有0.4ms, 1000个节点链式的场景树结构,每两个比较都是最差情况,耗时13ms。

@pandamicro

This comment has been minimized.

Copy link
Member

commented May 31, 2019

喔唷,厉害了!果然多想想还是有好处的

caryliu1999 added some commits May 31, 2019

@jareguo

This comment has been minimized.

Copy link
Contributor

commented Jun 4, 2019

先不合并,用户反馈会有BUG,但是我没测试出来,已经跟他要了会出现BUG的使用场景,还没回复,确认完再合并。

@jareguo jareguo closed this Jun 4, 2019

@jareguo jareguo reopened this Jun 6, 2019

@caryliu1999

This comment has been minimized.

Copy link
Contributor Author

commented Jun 6, 2019

@从小爱吃大葱 反馈的prefab加载时,由于预创建的节点localZOrder都为0,导致事件层级错误的BUG已经修复了,感谢 @从小爱吃大葱 的反馈!

@2youyou2

This comment has been minimized.

Copy link
Collaborator

commented Jun 11, 2019

为什么不在 node 中记录他的层级结构 level(level 在 set parent 时对 parent.level + 1),然后排序时根据 level 和 zorder 直接排序?

@caryliu1999

This comment has been minimized.

Copy link
Contributor Author

commented Jun 11, 2019

为什么不在 node 中记录他的层级结构 level(level 在 set parent 时对 parent.level + 1),然后排序时根据 level 和 zorder 直接排序?

  1. 遵循node中的数据增加尽量克制的原则,不添加无必要的信息。

  2. 单纯的依赖节点的层级level是没办法判断两个节点次序

1560246101090

如果想用这种提前记录层级的方式,那这个层级level就不能是简单的场景树节点的深度值了。

@2youyou2

This comment has been minimized.

Copy link
Collaborator

commented Jun 12, 2019

明白了

@2youyou2 2youyou2 merged commit 3c8c4e1 into cocos-creator:v2.1.2 Jun 12, 2019

1 check passed

ci/circleci: test Your tests passed on CircleCI!
Details

knoxHuang added a commit to knoxHuang/engine-2 that referenced this pull request Jun 19, 2019

Modify the calculation of renderOrder in EventManager. (cocos-creator…
…#4522)

* Modify the calculation of renderOrder in EventManager.

* Remove the calculation of renderOrder in EventManager.

* modify format

* fix bug

* delete renderQueueIndex in render-flow.

* Fix the sorting of the same localZorder.

* fix the sorting of same localZOrder.

* Fix the event bug caused by node activation.

* Fix the event bug caused by node activation.

* Modify the reset of localZOrder.

* add reset childArrivalOrder

jareguo added a commit that referenced this pull request Jul 8, 2019

Modify the calculation of renderOrder in EventManager. (#4522)
* Modify the calculation of renderOrder in EventManager.

* Remove the calculation of renderOrder in EventManager.

* modify format

* fix bug

* delete renderQueueIndex in render-flow.

* Fix the sorting of the same localZorder.

* fix the sorting of same localZOrder.

* Fix the event bug caused by node activation.

* Fix the event bug caused by node activation.

* Modify the reset of localZOrder.

* add reset childArrivalOrder
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.